我遇到了一个动态编程解决方案的问题,我正试图在matlab中实现,并试图看看是否有比我能想出的更好(运行时)的实现。
问题(所有值都在真实中): 输入:令X为T-by-d矩阵,W为k-by-d矩阵,A为k-by-k矩阵。 输出:X中的行T的Y T-by-1数组s.t Y(i)是W中最大化目标的行数。
如果我们选择的上一行是i,则A(i,j)给出了选择行j的成本。
要计算输出的权重,对于X中的每一行,我们将W的Y(i)行的点积相加,并从A中添加相关成本。
我们的目标是最大化上述重量。
动态解决方案:
实例化k-by-T矩阵
填充矩阵的第一列,其中包含第一行X点的产生结果,每行为W
对于每个相同的列(表示为i),用每行W填充i行X的点积,并加上A(j,i)的成本,其中j是行上一列中具有最大值的单元格的索引
从最后一列回溯,每次选择具有最高值的单元格的行索引
Matlab实现(实例化变量):
T = 8;
d = 10;
k = 20;
X = rand(T,d);
W = rand(k,d);
A = rand(k);
Y = zeros(T,1);
weight_table = zeros(k,T);
weight_table(:,1) = W*X(1,:)';
for t = 2 : T
[~, prev_ind] = max(weight_table(:,t-1));
weight_table(:,t) = W*X(t,:)' + A(:,prev_ind);
end
[~, Y] = max(weight_table);
答案 0 :(得分:2)
由于跨迭代存在数据依赖性,我建议保持循环,但预先计算一些事情,如W
的乘积和X
的每一行的转置。这是在这里完成的(仅显示weight_table
计算部分,因为其余代码保持与原始帖子相同) -
weight_table = zeros(k,T);
weight_table(:,1) = W*X(1,:)';
WXt = W*X.'; %//' Pre-calculate
for t = 2 : T
[~, prev_ind] = max(weight_table(:,t-1));
weight_table(:,t) = WXt(:,t) + A(:,prev_ind); %// Use pre-calculated values and thus avoid that multiplication across each iteration
end
对于更大的输入,例如 - T = 800; d = 1000; k = 2000;
,我的系统上的性能提升8-10x
。