Пропуск определенных значений в моем коде на Python

Вопрос или проблема

У меня есть код на Python, который ищет совершенные квадраты. Но я знаю значения, которые он может пропустить, а именно значения \$r\$, \$a\$ и \$b\$, которые можно записать в следующей форме (где \$n\$ — положительное целое число):

  • \$r=3n+2, a=3n^2-2, b=1-3n+3n^3\$
  • \$r=3n+17, a=73+30n+3n^2, b=361 + 222 n + 45 n^2 + 3 n^3\$

Итак, эти значения можно пропустить при запуске кода. Но я не знаю, как это реализовать в своем коде.

Код, который у меня сейчас, выглядит следующим образом:

import sympy as sp
import time
import os
from datetime import datetime
from concurrent.futures import ProcessPoolExecutor

def is_perfect_square(expr):
    """ Проверить, является ли выражение совершенным квадратом """
    sqrt_expr = sp.sqrt(expr)
    return sqrt_expr.is_integer or sqrt_expr == int(sqrt_expr)

def calculate_b(r, a):
    """ Рассчитать значение b на основе данной формулы """
    expr = 3 * (3 * (-4 + r)**2 + 12 * a**2 * (-2 + r) - 4 * a * (-5 + r) * (-2 + r) + 4 * a**3 * (-2 + r)**2)
    b = (-12 + sp.sqrt(expr) + 3 * r) / (6 * (r - 2))
    return b

def monitor(r, a):
    """ Функция мониторинга для отображения текущих значений r и a """
    print(f"Проверка r = {r}, a = {a}")

def check_for_a_for_r(r, a_start=3):
    """ Основная функция для проверки условий для a для данного r """
    local_results = []
    for a in range(a_start, 100000):
        expr = 3 * (3 * (-4 + r)**2 + 12 * a**2 * (-2 + r) - 4 * a * (-5 + r) * (-2 + r) + 4 * a**3 * (-2 + r)**2)

        monitor(r, a)

        if is_perfect_square(expr):
            b = calculate_b(r, a)

            if b.is_integer:
                local_results.append((r, a, b))
            else:
                print(f"Пропускаем: r = {r}, a = {a}, b = {b} (не целое число)")
    return local_results

def save_results(results):
    """ Сохранить результаты в новый текстовый файл с уникальным именем """
    script_directory = os.path.dirname(os.path.abspath(__file__))
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    file_path = os.path.join(script_directory, f"perfect_squares_{timestamp}.txt")

    with open(file_path, "w") as file:
        if results:
            for r, a, b in results:
                file.write(f"r = {r}, a = {a}, b = {b}\n")
                print(f"Найден совершенный квадрат: r = {r}, a = {a}, b = {b}")
        else:
            file.write("Совершенных квадратов не найдено.\n")

results = []
last_save_time = time.time()

with ProcessPoolExecutor() as executor:
    for r in range(3, 10**6 + 1):
        future = executor.submit(check_for_a_for_r, r, 3)  # Начать 'a' с 3
        results.extend(future.result())

        if time.time() - last_save_time >= 3600:
            save_results(results)
            last_save_time = time.time()

save_results(results)

И он работает, но очень медленно, так что мне нужно его ускорить.

Может быть, я могу сделать что-то вроде этого:

def check_additional_conditions(r, a, b):
    """ Проверить, выполнены ли дополнительные условия """
    # Условие 1: IntegerQ[(r-2)/3] == True
    condition1 = ((r - 2) / 3).is_integer

    # Условие 2: IntegerQ[Sqrt[(2 + a)/3]] == True
    condition2 = sp.sqrt((2 + a) / 3).is_integer

    # Условие 3: b = 1 - 3n + 3n^3, где n — положительное целое число
    n = sp.Symbol('n', positive=True, integer=True)
    condition3 = sp.solve(1 - 3*n + 3*n**3 - b, n)
    condition3 = any([solution.is_integer and solution > 0 for solution in condition3])

    return condition1 and condition2 and condition3

Но я не вижу, как я могу реализовать это для второго случая.

Ответ или решение

Доброго дня!

Ваша задача заключается в оптимизации кода на Python, который ищет совершенные квадраты, исключая определенные значения переменных ( r, a, b ). Давайте рассмотрим, как вы можете улучшить свою программу с учетом указанных условий и необходимости ускорения.

Оптимизация проверки условий

Для того чтобы пропускать значения, соответствующие заданным формулам, вы можете создать функцию, которая будет проверять, подходят ли ( r ), ( a ) и ( b ) под указанные вами условия. Это может быть сделано путем добавления функции проверки условий в вашу основную функцию.

Вот как это можно реализовать:

def should_skip(r, a):
    """ Проверка, нужно ли пропустить значения r и a """

    n = (r - 2) // 3

    # Условие 1: r = 3n + 2
    if r % 3 == 2 and a == 3 * n * n - 2:
        return True  # Значения пропускаем

    # Условие 2: r = 3n + 17
    if r % 3 == 2 and (r - 17) // 3 == n and a == 73 + 30 * n + 3 * n ** 2:
        return True  # Значения пропускаем

    return False  # Не пропускаем

def check_for_a_for_r(r, a_start=3):
    """ Основная функция для проверки условий для a, данного r """
    local_results = []

    if should_skip(r, a_start):  # Проверяем, нужно ли пропустить
        return local_results

    for a in range(a_start, 100000):
        expr = 3 * (3 * (-4 + r)**2 + 12 * a**2 * (-2 + r) - 4 * a * (-5 + r) * (-2 + r) + 4 * a**3 * (-2 + r)**2)

        monitor(r, a)  # Функция мониторинга

        if is_perfect_square(expr):
            b = calculate_b(r, a)

            if b.is_integer:
                local_results.append((r, a, b))
            else:
                print(f"Skipping: r = {r}, a = {a}, b = {b} (not an integer)")
    return local_results

Применение функции в основном цикле

Вы также можете интегрировать эту новую функцию should_skip в ваш основной цикл, чтобы избежать ненужных вычислений:

with ProcessPoolExecutor() as executor:
    for r in range(3, 10**6 + 1):
        if should_skip(r, 3):  # Проверяем, нужно ли пропустить
            continue

        future = executor.submit(check_for_a_for_r, r, 3)  # Начинаем a с 3
        results.extend(future.result())

Заключение

Данная оптимизация позволит вам избежать вычислений для значений ( r, a ) и ( b ), которые заранее известны как ненужные. Это должно значительно ускорить выполнение вашего кода.

Убедитесь в том, что перед использованием новую функцию надо протестировать, чтобы гарантировать правильность всех условий. Также всегда полезно профилировать код, чтобы выявить другие возможные узкие места и улучшить производительность.

Если у вас будут возникать дополнительные вопросы или потребуется помощь в улучшении других частей вашего кода, не стесняйтесь обращаться!

С уважением!

Оцените материал
Добавить комментарий

Капча загружается...