Замораживание при попытке обработать большие числа в рамках рекурсии

#python

#python

Вопрос:

Я пытался создать программу на Python, которая вычисляет уровень обслуживания телекоммуникационной сети, используя рекурсивную формулу Erlang B: изображение

Программа получает нагрузку на трафик и количество линейных служб в качестве входных данных, генерируя указанный GoS как вероятность. Моя проблема в том, что когда я пытаюсь указать большее число, например, 30 для линейных служб и 5 для нагрузки трафика, оно зависает и не показывает результата. С другой стороны, предоставление служебного номера нижней строки, такого как 10, позволяет вычислить указанный результат. Возможно, это связано с утечками памяти?

Это то, что я написал до сих пор:

 lines = int(input('Give number of service lines (s): '))
load = int(input('Give the number of the traffic load (a) : '))


def grade_of_service(s, a):
    if s == 0:
        return 1
    else:
        result = float((a * grade_of_service(s-1, a)/(s   a * grade_of_service(s-1, a))))
        print(result)
        return result


print(grade_of_service(lines, load))
  

Заранее спасибо.

Комментарии:

1. Это работает для меня. Попробуйте удалить print() внутреннюю часть функции?

2. Print() внутри функции был просто заполнителем, общий код работал, например, с lines = 10 и load = 5, но для больших чисел, например, lines = 30 и load = 5, проблема заключалась в том, что результаты постоянно пересчитывались, как упоминал Хосе.

3. Я упомянул об этом, потому что попытка напечатать тонны данных за короткий промежуток времени иногда также может создать впечатление, что программа застряла или заморожена.

4. Причина, по которой я поместил print внутри функции, заключалась в том, чтобы проверить, были ли вообще какие-либо результаты, поэтому технически у меня была такая же проблема даже до этого.

Ответ №1:

Ваша рекурсивная функция экспоненциально увеличивается s : каждый рекурсивный вызов умножает на два количество вызовов.

У s = 30 вас есть 2**30 вызовы в строке, которых много.

Обычно способ решения такого рода проблем заключается в повторении снизу вверх или сохранении промежуточных результатов в таблице, чтобы избежать их постоянного пересчета, но в этом случае вы можете решить это с помощью переменной:

 lines = int(input('Give number of service lines (s): '))
load = int(input('Give the number of the traffic load (a) : '))


def grade_of_service(s, a):
    if s == 0:
        return 1
    else:
        previous_grade_of_service = grade_of_service(s-1, a)
        return float((a * previous_grade_of_service /(s   a * previous_grade_of_service)))


print(grade_of_service(lines, load))
  

РЕДАКТИРОВАТЬ Вот пример для «кэшированной» версии:

 lines = int(input('Give number of service lines (s): '))
load = int(input('Give the number of the traffic load (a) : '))

cache = [None] * (lines   1)
cache[0] = 1
def cached_grade_of_service(s, a):
    cached = cache[s]
    if cached == None:
        cached = float((a * cached_grade_of_service(s-1, a)/(s   a * cached_grade_of_service(s-1, a))))
        cache[s] = cached
    return cached

print(cached_grade_of_service(lines, load))
  

Комментарии:

1. @dimitris1821gr Если вы приняли ответ, почему вы не можете его поддержать?

2. Я сделал, но он не отобразил его из-за того, что моя репутация была ниже 15. Кроме того, еще один вопрос: является ли кэшированный ответ общим подходом для решения подобных вопросов в будущем, или могут быть применены оба метода?

3. @dimitris1821gr это во многом зависит от проблемы и разборчивости. Это называется динамическим программированием . Я склоняюсь к подходу «снизу вверх», но это не всегда возможно, и иногда это сильно ухудшает разборчивость. Например: Фибоначчи оказывается unsigned prev = 1, curr = 1, tmp = 0; for (unsigned i = 2; i < limit; i ) tmp = prev, prev = curr, curr = prev tmp; return curr;