В этой заметке привожу результаты тестов 3-х языковых моделей AI (ИИ). AI предложено проанализировать не оптимизированный алгоритм поиска простых чисел.
В тестах участвовали следующие модели:
ollama show llama3
Model
architecture llama
parameters 8.0B
context length 8192
embedding length 4096
quantization Q4_0
Parameters
num_keep 24
stop "<|start_header_id|>"
stop "<|end_header_id|>"
stop "<|eot_id|>"
License
META LLAMA 3 COMMUNITY LICENSE AGREEMENT
Meta Llama 3 Version Release Date: April 18, 2024
Llama 3
ollama show llama3.1
Model
architecture llama
parameters 8.0B
context length 131072
embedding length 4096
quantization Q4_0
Parameters
stop "<|start_header_id|>"
stop "<|end_header_id|>"
stop "<|eot_id|>"
License
LLAMA 3.1 COMMUNITY LICENSE AGREEMENT
Llama 3.1 Version Release Date: July 23, 2024
Llama 3.1
ollama show llama3.2
Model
architecture llama
parameters 3.2B
context length 131072
embedding length 3072
quantization Q4_K_M
Parameters
stop "<|start_header_id|>"
stop "<|end_header_id|>"
stop "<|eot_id|>"
License
LLAMA 3.2 COMMUNITY LICENSE AGREEMENT
Llama 3.2 Version Release Date: September 25, 2024
Llama 3.2
ollama run llama3
>>>как в следующей программе работает функция prime_numbers, отвечай на русском языке: # Импортируем функцию timeit из модуля timeit для измерения времени выполнения код
... а
... from timeit import timeit
...
... # Напишем функцию поиска простых чисел из числовой последовательности от 2 до n
... n = 1000
...
...
... def prime_numbers(n):
... """
... Реализация алгоритма "Решето Эратосфена" (Sieve of Eratosthenes)
... для нахождения простых чисел в диапазоне от 2 до n.
...
... Args:
... n Максимальное натуральное число, до которого продолжается поиск.
... Returns:
... sieve Список из n элементов, где значением True отмечен элемент с простым индексом.
... """
... # Создадим список sieve длинной n+1 с инициализацией флагами True и False.
... # Это необходимо для работы алгоритма "Решето Эратосфена".
...
... sieve = [False] * 2 + [True] * (n - 1) # Флаг True, предположительно простое число.
... for i in range(2, n): # Переберем числа от 2 до n включительно.
... for j in range(i + 1, n + 1): # Переберем числа от i+1 до n+1.
... if j % i == 0: # Если j делится без остатка на i:
... sieve[j] = False # установим флаг в False для элемента sieve[j].
... return sieve
...
...
... se = prime_numbers(n) # Вызовем функцию prime_numbers с параметром n для получения
... # решета Эратосфена с отмеченными простми числами.
... # Выводим простые числа:
... for i, val in enumerate(se): # Переберем элементы списка se
... if val: # Если флаг элемента se[i] из списка se равен True:
... print(i, end=' ') # Выведем число i и разделитель (пробел)
...
... print('\nRun 1000 tests...') # Выводим сообщение о начале тестов.
...
... # Вызываем функцию timeit 1000 раз для точного измерения времени выполнения функции sieve
... print(timeit(globals=globals(), stmt='prime_numbers(n)', number=1000),
... 'мс на одно выполнение функции при n = {}'.format(n))
...
В этой программе функция `prime_numbers` реализует алгоритм "Решето Эратосфена" для поиска простых чисел в диапазоне от 2 до `n`.
Алгоритм работает следующим образом:
1. Создается список `sieve` длиной `n+1`, инициализованный флагами `True` и `False`. Это необходимо для работы алгоритма "Решето Эратосфена".
2. Затем iterate over the range `[2, n)`, где `n` - это максимальное натуральное число, до которого продолжается поиск.
3. Для каждого числа `i` в этом диапазоне:
* Iterate over the range `[i+1, n+1)` (exclusive), что соответствует множителям `i`.
* Если находим множитель `j`, который делится без остатка на `i`, то устанавливаем флаг в `False` для элемента `sieve[j]`. Это означает, что `j` не является
простым числом.
4. В конце функция возвращает список `sieve`, где значением `True` отмечен элемент с простым индексом.
В программе также измеряется время выполнения функции `prime_numbers` 1000 раз для оценки ее эффективности.
Лист. 1. Llama3.
ollama run llama3.1
>>> как в следующей программе работает функция prime_numbers, отвечай на русском языке: # Импортируем функцию timeit из модуля timeit для измерения времени выполнения
... кода
... from timeit import timeit
...
... # Напишем функцию поиска простых чисел из числовой последовательности от 2 до n
... n = 1000
...
...
... def prime_numbers(n):
... """
... Реализация алгоритма "Решето Эратосфена" (Sieve of Eratosthenes)
... для нахождения простых чисел в диапазоне от 2 до n.
...
... Args:
... n Максимальное натуральное число, до которого продолжается поиск.
... Returns:
... sieve Список из n элементов, где значением True отмечен элемент с простым индексом.
... """
... # Создадим список sieve длинной n+1 с инициализацией флагами True и False.
... # Это необходимо для работы алгоритма "Решето Эратосфена".
...
... sieve = [False] * 2 + [True] * (n - 1) # Флаг True, предположительно простое число.
... for i in range(2, n): # Переберем числа от 2 до n включительно.
... for j in range(i + 1, n + 1): # Переберем числа от i+1 до n+1.
... if j % i == 0: # Если j делится без остатка на i:
... sieve[j] = False # установим флаг в False для элемента sieve[j].
... return sieve
...
...
... se = prime_numbers(n) # Вызовем функцию prime_numbers с параметром n для получения
... # решета Эратосфена с отмеченными простми числами.
... # Выводим простые числа:
... for i, val in enumerate(se): # Переберем элементы списка se
... if val: # Если флаг элемента se[i] из списка se равен True:
... print(i, end=' ') # Выведем число i и разделитель (пробел)
...
... print('\nRun 1000 tests...') # Выводим сообщение о начале тестов.
...
... # Вызываем функцию timeit 1000 раз для точного измерения времени выполнения функции sieve
... print(timeit(globals=globals(), stmt='prime_numbers(n)', number=1000),
... 'мс на одно выполнение функции при n = {}'.format(n))
...
Отличная реализация алгоритма "Решето Эратосфена"!
Давайте разберем работу функции `prime_numbers`:
**Функция принимает аргумент**: `n`, максимальное натуральное число, до которого продолжается поиск простых чисел.
**Внутри функции создается список**: `sieve`, длиной `n+1`. Это список из флагов (`True` или `False`) для каждого числа от 2 до `n`.
**Алгоритм работы:**
1. Инициализация списка `sieve`: первый элемент (`sieve[0]`) всегда равен `False`, а все остальные элементы (`sieve[i]`, где `i` от 1 до `n`) инициализируются
как `True`.
2. Два внешних цикла (`for i in range(2, n): ...` и `for j in range(i + 1, n + 1): ...`) обрабатывают числа от 2 до `n`.
3. Внутренний цикл (`for j in range(i + 1, n + 1): ...`) проверяет, делится ли число `j` на `i`. Если да, то:
* Установка флага в `False` для элемента `sieve[j]`, что означает, что `j` не является простым числом.
4. После внутреннего цикла завершения вышедшее значение `sieve[i]` уже известно и равно `True`.
**Результат**: функция `prime_numbers` возвращает список `sieve` с отмеченными простыми числами (в значении `True`) от 2 до `n`.
Например, если `n = 10`, то результатом будет список: `[False, False, True, True, True, False, True, True, True, False]`. В этом списке `3`, `5` и `7` являются
простыми числами.
Понятно?
Лист. 2. Llama3.1
ollama run llama3.2
>>> как в следующей программе работает функция prime_numbers, отвечай на русском языке: # Импортируем функцию timeit из модуля timeit для измерения времени выпол
... нения кода
... from timeit import timeit
...
... # Напишем функцию поиска простых чисел из числовой последовательности от 2 до n
... n = 1000
...
...
... def prime_numbers(n):
... """
... Реализация алгоритма "Решето Эратосфена" (Sieve of Eratosthenes)
... для нахождения простых чисел в диапазоне от 2 до n.
...
... Args:
... n Максимальное натуральное число, до которого продолжается поиск.
... Returns:
... sieve Список из n элементов, где значением True отмечен элемент с простым индексом.
... """
... # Создадим список sieve длинной n+1 с инициализацией флагами True и False.
... # Это необходимо для работы алгоритма "Решето Эратосфена".
...
... sieve = [False] * 2 + [True] * (n - 1) # Флаг True, предположительно простое число.
... for i in range(2, n): # Переберем числа от 2 до n включительно.
... for j in range(i + 1, n + 1): # Переберем числа от i+1 до n+1.
... if j % i == 0: # Если j делится без остатка на i:
... sieve[j] = False # установим флаг в False для элемента sieve[j].
... return sieve
...
...
... se = prime_numbers(n) # Вызовем функцию prime_numbers с параметром n для получения
... # решета Эратосфена с отмеченными простми числами.
... # Выводим простые числа:
... for i, val in enumerate(se): # Переберем элементы списка se
... if val: # Если флаг элемента se[i] из списка se равен True:
... print(i, end=' ') # Выведем число i и разделитель (пробел)
...
... print('\nRun 1000 tests...') # Выводим сообщение о начале тестов.
...
... # Вызываем функцию timeit 1000 раз для точного измерения времени выполнения функции sieve
... print(timeit(globals=globals(), stmt='prime_numbers(n)', number=1000),
... 'мс на одно выполнение функции при n = {}'.format(n))
...
Функция `prime_numbers` в этой программе использует алгоритм "Решето Эратосфена" (Sieve of Eratosthenes) для поиска простых чисел в диапазоне от 2 до `n`.
Эта функция создает список `sieve` длиной `n+1`, где каждый элемент представляет собой флаг: `True` для простого числа, а `False` для composite числа.
Этапы работы функции:
1. Функция создает список `sieve` длиной `n+1` с инициализацией флагов `True` и `False`.
2. Для каждого простого числа `i` от 2 до `n`, она итерирует через число `j` от `i+1` до `n+1`, проверяя, делится ли `j` на `i`. Если это так, то она
устанавливает флаг элемента `sieve[j]` в `False`.
3. В качестве результата функция возвращает список `sieve`.
Примечание: в данной программе используется алгоритм "Решето Эратосфена" с некоторыми ограничениями, поскольку он не works для всех значений `n`. Например,
при `n` больше 2, в функции будет ошибка, так как функция будет использовать `i+1` в качестве начального значения цикла.
В этом случае, для `n > 2`, функция создает список `sieve` длиной `n+1` с инициализацией флагов `True` и `False`. Поскольку при `i = 2` значение `j` равно
`3`, то в функции будет ошибка.
Чтобы исправить эту проблему, можно использовать алгоритм "Решето Эратосфена" с начальным значением `i=2`, а затем продолжать поиск простых чисел до
значения `n`.
Лист. 3. Llama3.2