Вопрос

Я ищу алгоритм для вычисления pow() Это рекурсивный хвост и использует мемузаризацию для ускорения повторных расчетов.

Производительность не проблема; Это в основном интеллектуальное упражнение - я провел поездку поезда со всеми разными pow() Реализации, которые я мог, но не смог придумать то, что я был доволен тем, что имел эти два свойства.

Мой лучший удар был следующим:

def calc_tailrec_mem(base, exp, cache_line={}, acc=1, ctr=0):
    if exp == 0:
        return 1
    elif exp == 1:
        return acc * base
    elif exp in cache_line:
        val = acc * cache_line[exp]
        cache_line[exp + ctr] = val
        return val
    else:
        cache_line[ctr] = acc        
    return calc_tailrec_mem(base, exp-1, cache_line, acc * base, ctr + 1)

Работает, но это не воменяет результаты всех расчетов - только те, которые с показателями 1..exp/2 а также exp.

Это было полезно?

Решение

Я не думаю, что вы записываете правильную вещь в вашем кэше, отображение изменено, когда вы называете его различными аргументами.

Я думаю, что вам нужно иметь кэш (Base, Exp) -> Pow (Base, Exp).

Я понимаю, что ctr для, и почему только половина того, что вы ожидаете, записан.

Рассмотреть возможность calc_tailrec_mem(2,4): Первый уровень, POW (2,1) записывается как 2, следующий уровень = calc_tailrec_mem(2,3,...), и POW (2,2) записан. Следующий уровень calc_tailrec_mem(2,2,...), но это уже сохраняется в кэше, поэтому рекурсия останавливается.

Функция очень сбивает с толку, потому что она кэширует что-то совершенно отличное от того, что он должен быть рассчитанным, из-за аккумулятора и ctr.

Другие советы

Вы получите лучшую производительность, если вы используете последовательную технику квадрата, описанную в SICP Раздел 1.2.4 Экспертизация. Отказ Он не использует мемузаризацию, но общий подход o (log n) вместо O (n), поэтому вы все равно должны увидеть улучшение.

Я говорю о решении итеративного процесса от упражнения 1.16 здесь.

Это слишком поздно, но кто-нибудь там ищет ответ, вот оно:

int powMem(int base,int exp){
    //initializes once and for all
    static map<int,int> memo;

    //base case to stop the recursion
    if(exp <= 1) return base;

    //check if the value is already calculated before. If yes just return it.
    if(memo.find(exp) != memo.end())
        return memo[exp];

    //else just find it and then store it in memo for further use.
    int x = powMem(base,exp/2);
    memo[exp] = x*x;

    //return the answer
    return memo[exp];
}

Это использует массив памятки - карта, чтобы быть точной - хранить уже рассчитанные значения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top