специализированный код под задачу будет эффективнееНо:
for(int a = 0; ; a++) {
for(int b = 0; ; b++) {
// вычисления для a и b
// вычисления для -a и b
// вычисления для a и -b
//
}
}
import sqlite3
from datetime import datetime
from tqdm import tqdm
# Устанавливаем диапазон для переменных
minValue = -3
maxValue = 3
# Создаем соединение с базой данных SQLite
conn = sqlite3.connect('equationResults.db')
cursor = conn.cursor()
# Проверяем, существует ли таблица cubeResults
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='cubeResults'")
if cursor.fetchone() is None:
print("Таблица cubeResults не найдена в базе данных. Пожалуйста, запустите populateDatabase.py, чтобы заполнить базу данных.")
conn.close()
exit()
# Создаем таблицу, если она еще не существует
cursor.execute('''
CREATE TABLE IF NOT EXISTS results (
a INTEGER,
b INTEGER,
c INTEGER,
equationResult TEXT
)
''')
# Создаем таблицу для хранения диапазонов и результатов
cursor.execute('''
CREATE TABLE IF NOT EXISTS rangeResults (
minValue INTEGER,
maxValue INTEGER,
firstA INTEGER,
firstB INTEGER,
firstC INTEGER,
lastA INTEGER,
lastB INTEGER,
lastC INTEGER,
startDate TEXT,
startTime TEXT,
endDate TEXT,
endTime TEXT
)
''')
# Создаем индексы для столбцов a, b и c, если они еще не существуют
cursor.execute('CREATE INDEX IF NOT EXISTS idxA ON results(a)')
cursor.execute('CREATE INDEX IF NOT EXISTS idxB ON results(b)')
cursor.execute('CREATE INDEX IF NOT EXISTS idxC ON results(c)')
# Функция для получения куба числа из базы данных
def getCubeFromDatabase(number):
cursor.execute('SELECT cube FROM cubeResults WHERE number=?', (number,))
return cursor.fetchone()[0]
# Функция для проверки уравнения
def checkEquation(a, b, c):
return getCubeFromDatabase(a) + getCubeFromDatabase(b) == getCubeFromDatabase(c)
# Функция для проверки, есть ли результат уже в базе данных
def isInDatabase(a, b, c):
cursor.execute('SELECT * FROM results WHERE a=? AND b=? AND c=?', (a, b, c))
return cursor.fetchone() is not None
try:
# Начинаем транзакцию
conn.execute('BEGIN TRANSACTION')
firstRecorded = False
lastA = lastB = lastC = None
# Записываем дату и время начала
startDate = datetime.now().strftime('%Y-%m-%d')
startTime = datetime.now().strftime('%H:%M:%S')
# Проверяем уравнение для всех значений в заданном диапазоне
for a in tqdm(range(minValue, maxValue + 1), desc='Processing a'):
for b in tqdm(range(minValue, maxValue + 1), desc='Processing b', leave=False):
for c in tqdm(range(minValue, maxValue + 1), desc='Processing c', leave=False):
# Исключаем варианты, где a, b или c равны нулю
if a == 0 or b == 0 or c == 0:
continue
# Если результат уже есть в базе данных, пропускаем его
if isInDatabase(a, b, c):
continue
# Если уравнение верно, сохраняем результат в базе данных
if checkEquation(a, b, c):
equationResult = 'Равно'
else:
equationResult = '!='
cursor.execute('INSERT INTO results VALUES (?, ?, ?, ?)', (a, b, c, equationResult))
# Записываем первые значения a, b, c
if not firstRecorded:
firstA, firstB, firstC = a, b, c
firstRecorded = True
# Обновляем последние значения a, b, c
lastA, lastB, lastC = a, b, c
# Записываем дату и время окончания
endDate = datetime.now().strftime('%Y-%m-%d')
endTime = datetime.now().strftime('%H:%M:%S')
# Записываем диапазон, результаты и время в таблицу rangeResults
cursor.execute('INSERT INTO rangeResults VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', (minValue, maxValue, firstA, firstB, firstC, lastA, lastB, lastC, startDate, startTime, endDate, endTime))
# Завершаем транзакцию
conn.execute('COMMIT')
except KeyboardInterrupt:
print("\nПрервано пользователем. Останавливаюсь...")
finally:
# Закрываем соединение с базой данных
conn.close()
import sqlite3
from tqdm import tqdm
# Устанавливаем диапазон для переменных
minValue = -1000
maxValue = 1000
# Создаем соединение с базой данных SQLite
conn = sqlite3.connect('equationResults.db')
cursor = conn.cursor()
# Создаем таблицу, если она еще не существует
cursor.execute('''
CREATE TABLE IF NOT EXISTS cubeResults (
number INTEGER,
cube INTEGER
)
''')
# Создаем индексы для столбцов number и cube, если они еще не существуют
cursor.execute('CREATE INDEX IF NOT EXISTS idxNumber ON cubeResults(number)')
cursor.execute('CREATE INDEX IF NOT EXISTS idxCube ON cubeResults(cube)')
# Начинаем транзакцию
conn.execute('BEGIN TRANSACTION')
# Заполняем таблицу кубами чисел
for number in tqdm(range(minValue, maxValue + 1), desc='Processing numbers'):
cube = number**3
cursor.execute('INSERT INTO cubeResults VALUES (?, ?)', (number, cube))
# Завершаем транзакцию
conn.execute('COMMIT')
# Закрываем соединение с базой данных
conn.close()
if isInDatabase(a, b, c):
continue
Это - медленная проверка.Медленная??? Я и от возведения в степень отказался, беру готовый ответ из базы, и проиндексировал... Очень много новых слов, значит я не на долго пропаду - пойду учиться.
Опытные люди используют кеширование. То есть часто используемые записи кладут поближеЕсли смогу понять, что вы сказали - отпишусь.
к приложению (в память Python) а данные которые редко нужны - вытесняются (evict) из
памяти.
2. Этот код не для Windows;
3. Если я в формуле a³+b³+c³=3 поменяю 3, на 0 будет ли программа правильно считать?
Поможете сделать код лучше?
int((3-a**3-b**3)**(1/3.0))
. Не забудьте только проверить, что это значение c подходит, ибо тут корень округляется до целого. И не факт, что уравнение выполняется. import random
# Функция оценки для уравнения a^3 + b^3 + c^3 = 0
def fitness(a, b, c):
return abs(a**3 + b**3 + c**3)
# Генерация начальной популяции
def generate_population(size, x_range):
return [[random.randint(*x_range), random.randint(*x_range), random.randint(*x_range)] for _ in range(size)]
# Скрещивание
def crossover(x, y):
z = []
for i in range(len(x)):
if random.random() < 0.5:
z.append(x[i])
else:
z.append(y[i])
return z
# Мутация
def mutate(x, x_range):
i = random.randint(0, len(x) - 1)
x[i] = random.randint(*x_range)
return x
# Генетический алгоритм
def genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations):
population = generate_population(population_size, x_range)
for _ in range(generations):
population = sorted(population, key=lambda x: fitness(*x))
if fitness(*population[0]) == 0:
break
next_generation = population[:2] # Элитизм
while len(next_generation) < population_size:
parents = random.sample(population[:10], 2) # Турнирный отбор
child = crossover(*parents)
child = mutate(child, x_range)
next_generation.append(child)
population = next_generation
return population[0]
# Параметры алгоритма
population_size = 1000
x_range = (-100, 100)
generations = 100
# Запуск алгоритма
solution = genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations)
print(f"Найденное решение: a={solution[0]}, b={solution[1]}, c={solution[2]}")
print(f"Значение функции оценки: {fitness(*solution)}")
Что за противоположные знаки? Это генетический алгоритм, спрашивайте у mayton2019.
def fitness(a, b, c):
return abs(a**3 + b**3 + c**3)
def fitness(a, b, c):
return abs(a**3 + b**3 + c**3)
# Функция оценки для уравнения a^3 + b^3 + c^3 = 0
def fitness(a, b, c):
if a < 0 or b < 0 or c < 0:
return float('inf')
return abs(a**3 + b**3 + c**3)
population_size = 100000000
D:\mayton2019>py main.py
Traceback (most recent call last):
File "D:\mayton2019\main.py", line 52, in <module>
solution = genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations)
File "D:\mayton2019\main.py", line 32, in genetic_algorithm
population = generate_population(population_size, x_range)
File "D:\mayton2019\main.py", line 12, in generate_population
return [[random.randint(*x_range), random.randint(*x_range), random.randint(*x_range)] for _ in range(size)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
MemoryError
import random
# Функция оценки для уравнения a^3 + b^3 + c^3 = 0
def fitness(a, b, c):
if a < 0 or b < 0 or c < 0:
return float('inf')
return abs(a**3 + b**3 + c**3)
# Генерация начальной популяции
def generate_population(size, x_range):
return [[random.randint(*x_range), random.randint(*x_range), random.randint(*x_range)] for _ in range(size)]
# Скрещивание
def crossover(x, y):
z = []
for i in range(len(x)):
if random.random() < 0.5:
z.append(x[i])
else:
z.append(y[i])
return z
# Мутация
def mutate(x, x_range):
i = random.randint(0, len(x) - 1)
x[i] = random.randint(*x_range)
return x
# Генетический алгоритм
def genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations):
population = generate_population(population_size, x_range)
for _ in range(generations):
population = sorted(population, key=lambda x: fitness(*x))
if fitness(*population[0]) == 0:
break
next_generation = population[:2] # Элитизм
while len(next_generation) < population_size:
parents = random.sample(population[:10], 2) # Турнирный отбор
child = crossover(*parents)
child = mutate(child, x_range)
next_generation.append(child)
population = next_generation
return population[0]
# Параметры алгоритма
population_size = 100000000
x_range = (-100, 100)
generations = 100
# Запуск алгоритма
solution = genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations)
print(f"Найденное решение: a={solution[0]}, b={solution[1]}, c={solution[2]}")
print(f"Значение функции оценки: {fitness(*solution)}")
Я не запрещаю тебе пользоваться AI.
import numpy as np
# Функция оценки для уравнения a^3 + b^3 + c^3 = 0
def fitness(population):
# population — массив формы (N, 3)
mask_negative = (population < 0).any(axis=1)
# Приводим к int64, чтобы избежать переполнения при возведении в куб
cubes = population.astype(np.int64) ** 3
fitness_values = np.abs(np.sum(cubes, axis=1)).astype(float)
fitness_values[mask_negative] = np.inf
return fitness_values
# Генерация начальной популяции с использованием NumPy
def generate_population(size, x_range):
return np.random.randint(x_range[0], x_range[1] + 1, size=(size, 3))
# Скрещивание (одиночное точечное)
def crossover(parent1, parent2):
point = np.random.randint(1, 3) # точка разреза: 1 или 2
child = np.empty(3, dtype=int)
child[:point] = parent1[:point]
child[point:] = parent2[point:]
return child
# Мутация — меняем случайный ген на новое случайное значение с вероятностью mutation_rate
def mutate(individual, x_range, mutation_rate=0.1):
if np.random.rand() < mutation_rate:
idx = np.random.randint(0, 3)
individual[idx] = np.random.randint(x_range[0], x_range[1] + 1)
return individual
# Генетический алгоритм
def genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations):
population = generate_population(population_size, x_range)
for gen in range(generations):
fitness_values = fitness(population)
best_idx = np.argmin(fitness_values)
best_fitness = fitness_values[best_idx]
print(f"Поколение {gen+1}, лучшая оценка: {best_fitness}")
if best_fitness == 0:
return population[best_idx]
# Сортируем популяцию по значению функции оценки
sorted_indices = np.argsort(fitness_values)
population = population[sorted_indices]
# Элитизм — сохраняем 2 лучших индивида
next_generation = population[:2].copy()
# Турнирный отбор и создание потомков
while len(next_generation) < population_size:
parents_idx = np.random.choice(10, size=2, replace=False)
parent1 = population[parents_idx[0]]
parent2 = population[parents_idx[1]]
child = crossover(parent1, parent2)
child = mutate(child, x_range)
next_generation = np.vstack([next_generation, child])
population = next_generation
# Возвращаем лучшего индивида после всех поколений
fitness_values = fitness(population)
best_idx = np.argmin(fitness_values)
return population[best_idx]
# Параметры алгоритма
population_size = 100000
x_range = (-100, 100)
generations = 100
# Запуск алгоритма
solution = genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations)
print(f"Найденное решение: a={solution[0]}, b={solution[1]}, c={solution[2]}")
print(f"Значение функции оценки: {np.abs(solution[0]**3 + solution[1]**3 + solution[2]**3)}")
import numpy as np
import os
import sys
def fitness(population):
mask_negative = (population < 0).any(axis=1)
cubes = population.astype(np.int64) ** 3
fitness_values = np.abs(np.sum(cubes, axis=1)).astype(float)
fitness_values[mask_negative] = np.inf
return fitness_values
def generate_population(size, x_range):
return np.random.randint(x_range[0], x_range[1] + 1, size=(size, 3))
def crossover(parent1, parent2):
point = np.random.randint(1, 3)
child = np.empty(3, dtype=int)
child[:point] = parent1[:point]
child[point:] = parent2[point:]
return child
def mutate(individual, x_range, mutation_rate=0.1):
if np.random.rand() < mutation_rate:
idx = np.random.randint(0, 3)
individual[idx] = np.random.randint(x_range[0], x_range[1] + 1)
return individual
def save_population_to_csv(population, filename="population_backup.csv"):
np.savetxt(filename, population, delimiter=",", fmt='%d')
print(f"\nТекущее состояние популяции сохранено в файл '{filename}'.")
def load_population_from_csv(filename="population_backup.csv"):
if os.path.exists(filename):
population = np.loadtxt(filename, delimiter=",", dtype=int)
print(f"Загружена популяция из файла '{filename}'.")
return population
else:
return None
def genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations):
population = load_population_from_csv()
if population is None:
print("Файл с сохранённой популяцией не найден. Создаём новую популяцию.")
population = generate_population(population_size, x_range)
else:
print(f"Продолжаем работу с загруженной популяцией размером {population.shape[0]}.")
try:
for gen in range(generations):
fitness_values = fitness(population)
best_idx = np.argmin(fitness_values)
best_fitness = fitness_values[best_idx]
print(f"Поколение {gen+1}, лучшая оценка: {best_fitness}")
if best_fitness == 0:
print("Найдено точное решение!")
return population[best_idx]
sorted_indices = np.argsort(fitness_values)
population = population[sorted_indices]
next_generation = population[:2].copy()
while len(next_generation) < population_size:
parents_idx = np.random.choice(10, size=2, replace=False)
parent1 = population[parents_idx[0]]
parent2 = population[parents_idx[1]]
child = crossover(parent1, parent2)
child = mutate(child, x_range)
next_generation = np.vstack([next_generation, child])
population = next_generation
except KeyboardInterrupt:
print("\nПолучен сигнал прерывания (Ctrl+C). Сохраняем состояние и завершаем работу...")
save_population_to_csv(population)
sys.exit(0)
fitness_values = fitness(population)
best_idx = np.argmin(fitness_values)
return population[best_idx]
# Параметры алгоритма
population_size = 1000000 # Можно уменьшить для ускорения
x_range = (-100, 100)
generations = 100000 # Можно увеличить для более долгой работы
# Запуск алгоритма
solution = genetic_algorithm(fitness, generate_population, crossover, mutate, population_size, x_range, generations)
print(f"Найденное решение: a={solution[0]}, b={solution[1]}, c={solution[2]}")
print(f"Значение функции оценки: {np.abs(solution[0]**3 + solution[1]**3 + solution[2]**3)}")
population_size = 5000 # Можно уменьшить для ускорения
x_range = (-1000000000, 1000000000)
generations = 2000 # Можно увеличить для более долгой работы
Поколение 2000, лучшая оценка: 29934254657720.0
Найденное решение: a=850515598, b=583371668, c=631088364
Значение функции оценки: 29934254657720
import numpy as np
import os
import sys
from typing import Optional, Tuple
def fitness(population: np.ndarray) -> np.ndarray:
mask_negative = (population < 0).any(axis=1)
cubes = population.astype(np.int64) ** 3
fitness_values = np.abs(np.sum(cubes, axis=1)).astype(float)
fitness_values[mask_negative] = np.inf
return fitness_values
def generate_population(size: int, x_range: Tuple[int, int]) -> np.ndarray:
return np.random.randint(x_range[0], x_range[1] + 1, size=(size, 3))
def crossover(parent1: np.ndarray, parent2: np.ndarray) -> np.ndarray:
point = np.random.randint(1, 3)
child = np.empty(3, dtype=int)
child[:point] = parent1[:point]
child[point:] = parent2[point:]
return child
def mutate(individual: np.ndarray, x_range: Tuple[int, int], mutation_rate: float = 0.1) -> np.ndarray:
if np.random.rand() < mutation_rate:
idx = np.random.randint(0, 3)
individual[idx] = np.random.randint(x_range[0], x_range[1] + 1)
return individual
def save_population_to_csv(population: np.ndarray, filename: str = "population_backup.csv") -> None:
np.savetxt(filename, population, delimiter=",", fmt='%d')
print(f"\nТекущее состояние популяции сохранено в файл '{filename}'.")
def load_population_from_csv(filename: str = "population_backup.csv") -> Optional[np.ndarray]:
if os.path.exists(filename):
population = np.loadtxt(filename, delimiter=",", dtype=int)
if population.ndim == 1:
population = population.reshape(1, -1)
print(f"Загружена популяция из файла '{filename}', размер: {population.shape}.")
return population
else:
return None
def genetic_algorithm(
fitness,
generate_population,
crossover,
mutate,
population_size: int,
x_range: Tuple[int, int],
generations: int
) -> np.ndarray:
population = load_population_from_csv()
if population is None:
print("Файл с сохранённой популяцией не найден. Создаём новую популяцию.")
population = generate_population(population_size, x_range)
else:
print(f"Продолжаем работу с загруженной популяцией размером {population.shape[0]}")
if population.shape[0] < population_size:
needed = population_size - population.shape[0]
new_individuals = generate_population(needed, x_range)
population = np.vstack([population, new_individuals])
try:
for gen in range(generations):
# print(f"Начинаем поколение {gen + 1}")
fitness_values = fitness(population)
best_idx = np.argmin(fitness_values)
best_fitness = fitness_values[best_idx]
print(f"Поколение {gen + 1}, лучшая оценка: {best_fitness}")
if best_fitness == 0:
print("Найдено точное решение!")
return population[best_idx]
sorted_indices = np.argsort(fitness_values)
population = population[sorted_indices]
next_generation = population[:2].copy()
while len(next_generation) < population_size:
parents_idx = np.random.choice(10, size=2, replace=False)
parent1 = population[parents_idx[0]]
parent2 = population[parents_idx[1]]
child = crossover(parent1, parent2)
child = mutate(child, x_range)
next_generation = np.vstack([next_generation, child])
population = next_generation
except KeyboardInterrupt:
print("\nПолучен сигнал прерывания (Ctrl+C). Сохраняем состояние и завершаем работу...")
save_population_to_csv(population)
sys.exit(0)
fitness_values = fitness(population)
best_idx = np.argmin(fitness_values)
return population[best_idx]
if __name__ == "__main__":
population_size: int = 5000
x_range: Tuple[int, int] = (-1000000000, 1000000000)
generations: int = 2000
solution = genetic_algorithm(
fitness,
generate_population,
crossover,
mutate,
population_size,
x_range,
generations
)
print(f"Найденное решение: a={solution[0]}, b={solution[1]}, c={solution[2]}")
print(f"Значение функции оценки: {np.abs(solution[0]**3 + solution[1]**3 + solution[2]**3)}")
Забегая вперед я бы предложил тебе сразу делать эту задачу на С++Я дошел да "-5000000, 5000000" насколько далеко мне нужно зайти, чтобы перейти на С++?
Также в коде введено ограничение, что все координаты должны быть неотрицательными (иначе fitness = бесконечность), что ограничивает пространство поискаЭто правда? Я не считаю отрицательные?
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
Загружена популяция из файла '/content/drive/MyDrive/GA_backup/population_backup.csv', размер: (50000000, 3).
Загружен номер поколения: 6 из файла '/content/drive/MyDrive/GA_backup/generation_backup.csv'.
Продолжаем работу с загруженной популяцией размером 50000000 и поколением 6
[2025-07-30 11:19:28] Поколение 7, лучшая оценка: 801.0
[2025-07-30 11:40:00] Поколение 8, лучшая оценка: 72.0
[2025-07-30 12:00:41] Поколение 9, лучшая оценка: 8.0
Текущее состояние популяции сохранено в файл '/content/drive/MyDrive/GA_backup/population_backup.csv'.
Номер поколения 9 сохранён в файл '/content/drive/MyDrive/GA_backup/generation_backup.csv'.
[2025-07-30 12:22:33] Поколение 10, лучшая оценка: 1.0
[2025-07-30 12:43:05] Поколение 11, лучшая оценка: 0.0
Найдено точное решение!
Найденное решение: a=0, b=0, c=0
Значение функции оценки: 0
Mounted at /content/drive
Файл с сохранённой популяцией не найден. Создаём новую популяцию.
[2025-07-31 10:09:18] Поколение 1, лучшая оценка: 64284052936256.0
[2025-07-31 10:38:05] Поколение 2, лучшая оценка: 1452962413.0
[2025-07-31 11:07:07] Поколение 3, лучшая оценка: 55547389.0
Текущее состояние популяции сохранено в файл '/content/drive/MyDrive/geneticAlgorithmProfiler/population_backup.csv'.
Номер поколения 3 сохранён в файл '/content/drive/MyDrive/geneticAlgorithmProfiler/generation_backup.csv'.
[2025-07-31 11:38:01] Поколение 4, лучшая оценка: 3962457.0
ncalls,tottime,percall,cumtime,percall2,filename:lineno(function)
1,0.0,0.000,0.000,0.000,_ufunc_config.py:400(__init__)
1,0.0,0.000,0.000,0.000,_ufunc_config.py:429(__call__)
1,0.0,0.000,0.000,0.000,_ufunc_config.py:434(inner)
200000003,562.581,0.000,562.581,0.000,{method 'reduce' of 'numpy.ufunc' objects}
def fitness(population: np.ndarray) -> np.ndarray:
mask_negative = (population < 0).any(axis=1)
cubes = population.astype(np.float64) ** 3
fitness_values = np.abs(np.sum(cubes, axis=1))
fitness_values[mask_negative] = np.inf
return fitness_values
x_range = (-5000000, 5000000)
значит мне же не нужно его еще раз считать. x_range = (-5000000, 5000000)
. Если да, то это 0, 0 и 0.