Я пытаюсь узнать об мемоизации с помощью C++ вместе с boost и спецификацией C++11. . Однако я столкнулся с проблемой, с которой у меня проблемы. Я следую руководству здесь: Запоминание в C и учебник говорит, что вы можете обобщить запоминание рекурсивных функций, используя шаблоны и лямбда-функции. В руководстве также перечислены рекурсивные функции факториала и Фибоначчи для использования с шаблоном. Однако руководство использует только функцию Фибоначчи.
Я написал тестовую программу, чтобы увидеть, как все это работает, и сделать как мемоизированную функцию Фибоначчи, так и факториал в одном запуске. Дело в том, что шаблон мемоизации использует статическую карту для хранения кэшированных значений, и похоже, что карта не уникальна для каждого экземпляра мемоизированных функций. Ожидается ли это? Что нужно сделать, чтобы сделать карту уникальной для каждого экземпляра шаблона? Прежде чем я начал использовать функции C++11, я пытался создать класс шаблона, который принимал бы функцию повышения для инкапсуляции этого процесса. Будет ли статическая карта уникальной в классе шаблона?
Основная логика создания мемоизированных функций
// Template function to create memoized versions of recursive lambda functions
template<typename inType, typename outType>
std::function<outType(inType) > memoize(std::function<outType(inType) > foo) {
return [foo](inType n) {
static std::map<inType, outType> memo;
outType ret;
if (memo.count(n) > 0) {
cout << "Cache Hit" << endl;
ret = memo[n];
return ret;
}
ret = foo(n);
memo[n] = ret;
return ret;
};
}
// Recursive lambda fibonacci function
std::function<int(int) > fibonacci_r = [](int n) {
if (n <= 1) {
return n;
} else {
return fibonacci_r(n - 1) + fibonacci_r(n - 2);
}
};
// Recursive lambda factorial function
std::function<int(int) > factorial_r = [](int n) {
if (n == 0) {
return 1;
} else {
return n * factorial_r(n - 1);
}
};
Логика для тестирования мемоизированных функций
int position = 7;
cout << "Fibonacci:" << endl;
cout << "Non Memo Fibonacci" << endl;
cout << position << "-> " << fibonacci_r(position) << endl;
cout << "Memo Fibonacci" << endl;
fibonacci_r = memoize(fibonacci_r);
cout << position << " -> " << fibonacci_r(position) << endl;
cout << endl;
cout << "Non Memo Factorial" << endl;
cout << position << " -> " << factorial_r(position) << endl;
cout << "Memo Factorial" << endl;
factorial_r = memoize(factorial_r);
cout << position << " -> " << factorial_r(position) << endl;
Вывод
Fibonacci:
Non Memo Fibonacci
7-> 13
Memo Fibonacci
Cache Hit
Cache Hit
Cache Hit
Cache Hit
Cache Hit
7 -> 13
Non Memo Factorial
7 -> 5040
Memo Factorial
Cache Hit
7 -> 13
В конце вывода вы можете увидеть, что факториал Memo попал в кеш. Однако я не думаю, что он должен иметь только 1 попадание в кеш. В любом случае, 7!
не равно 13, а 13 является значением кэша для 7 в лямбда-памятке Фибоначчи.