简短我应该如何减少(优化)代码中所需操作的数量?
LONGER 为了研究,我在C ++中编写了一组方程,如果它适合模型,则输出一个序列。在代码的内部是这个函数,在运行时被称为多次:
int Weight(int i, int q, int d){
int j, sum = 0;
if (i <= 0)
return 0;
else if (i == 1)
return 1;
for (j = 1; j <= d; j++){
sum += Weight((i - j), q, d);
}
sum = 1 + ((q - 1) * sum);
return sum;
}
因此,基于变量d
的大小,索引i
的大小,以及在其余代码中调用此函数的次数,可以完成许多冗余计算。我该如何减少计算次数?
理想情况下,例如,在计算Weight(5, 3, 1)
之后,当我调用Weight(6, 3, 1)
时,我如何告诉计算机替换其值而不是重新计算其值,因为该函数是递归定义的?
在这种情况下,多维向量是否可以存储值?我应该只将值打印到要读取的文件中吗?我还没有遇到输入大小I溢出的溢出,但是尾递归有助于优化吗?
注意:我还在学习如何编程,我很惊讶我甚至可以在第一时间获得该模型。
答案 0 :(得分:3)
您可以使用memoization
int WeightImpl(int i, int q, int d); // forward declaration
// Use memoization and use `WeightImpl` for the real computation
int Weight(int i, int q, int d){
static std::map<std::tuple<int, int, int>, int> memo;
auto it = memo.find(std::make_tuple(i, q, d));
if (it != memo.end()) {
return it->second;
}
const int res = WeightImpl(i, q, d);
memo[std::make_tuple(i, q, d)] = res;
return res;
}
// Do the real computation
int WeightImpl(int i, int q, int d){
int j, sum = 0;
if (i <= 0)
return 0;
else if (i == 1)
return 1;
for (j = 1; j <= d; j++){
sum += Weight((i - j), q, d); // Call the memoize version to save intermediate result
}
sum = 1 + ((q - 1) * sum);
return sum;
}
注意:当您使用递归调用时,您必须谨慎调用哪个版本来实际记忆每个中间计算。我的意思是应该修改递归函数以不调用自身,而是调用函数的memoize版本。对于非递归函数,可以在不修改实际函数的情况下完成memoization。
答案 1 :(得分:0)
您可以使用数组来存储中间值。例如,某些d和q的数组包含索引i处的权重(i,q,d)。
如果将数组项初始化为-1,则可以在函数中执行,例如
if(sum_array[i] != -1){ // if the value is pre-calculated
sum += sum_array[i];
}
else{
sum += Weight((i - j), q, d);
}