我遇到了一个问题,当涉及大量数据(人口规模)时,我的计算目标函数的方法效率不高。 (如果您认为解释太长,请向下滚动)
矩阵'A'的大小为nx1,其中n是设施的数量。每行中的元素分别代表设施的长度。例如:
A = [0.05 % 1 % Original Position
0.03 % 2
0.06 % 3
0.04 % 4
0.02]; % 5
矩阵'W'是一个大小为n的上三角方阵,包含设施之间的流量。例如: (即,从设施1到3,流量为4,相同为3比1)
W = [0 5 2 4 1
0 0 3 0 2
0 0 0 0 0
0 0 0 0 5
0 0 0 0 0];
我需要连续找到最佳排列,以使目标函数值最小化。
.......................................... .....(1)
其中w_ij是设施之间的流量,B_ij是2个设施中心之间的距离。
例如,设施的安排是[2 4 1 5 3],因此矩阵A置换为
A = [0.03 % 2 % Permuted Position
0.04 % 4
0.05 % 1
0.02 % 5
0.06]; % 3
第4和第3设施中心之间的距离,B_13 = 0.05 / 2 + 0.02 + 0.06 / 2 = 0.0750,流量值2基于矩阵W.
现在,给定数据集p,m×n的置换矩阵。其中m是人口数,n是设施数。每行存储设施的安排。例如:
p = [3 2 1 5 4 % can be any number of row and column.
5 4 1 2 3 % in this case m = 3 (Since it has 3 rows)
1 2 3 4 5];
到目前为止,这是我能想到的目标函数(也是堆栈溢出成员的一些指导)。该目标函数的目的是基于等式(1)返回它们的值。您可以参考here,以了解它为for循环中的每次迭代所做的工作。
function fit_value = fit_func(p,A,W,m) % m is the number of rows
fit_value = zeros(1,m);
A2 = A(p);
for i=1:m
W2 = W(p(i,:),p(i,:));
end_pts = cumsum(A2(i,:));
start_pts = end_pts - A2(i,:);
start_dist = abs(bsxfun(@minus,start_pts,start_pts'));
end_dist = abs(bsxfun(@minus,end_pts,end_pts'));
distance = (start_dist + end_dist)./2;
fit_value(i) = sum(sum(distance .* W2));
end
但是,每次调用函数的数据都很大(函数可能多次调用)。它必须循环m次才能获得fit_value。是否有任何技巧而不是使用'for'循环?
总体而言(对于那些跳过解释的人)
% Take this 4 Parameter
A = [0.05
0.03
0.06
0.04
0.02];
W = [0 5 2 4 1
0 0 3 0 2
0 0 0 0 0
0 0 0 0 5
0 0 0 0 0];
p = [3 2 1 5 4
5 4 1 2 3
1 2 3 4 5];
m = 3; % since p have 3 rows.
% Substitute into this function
function fit_value = fit_func(p,A,W,m) % m is the number of rows
fit_value = zeros(1,m);
A2 = A(p);
for i=1:m % this for loop consume the time very much
W2 = W(p(i,:),p(i,:));
end_pts = cumsum(A2(i,:));
start_pts = end_pts - A2(i,:);
start_dist = abs(bsxfun(@minus,start_pts,start_pts'));
end_dist = abs(bsxfun(@minus,end_pts,end_pts'));
distance = (start_dist + end_dist)./2;
fit_value(i) = sum(sum(distance .* W2));
end
% Will Return This Output
fit_value = [1.100 1.1400 1.6100];
为了获得高效的代码,有什么诀窍而不是使用for循环?