我想說,這是迄今爲止您的一個很好的解決方案。
雖然我看到了一些優化。這裏是我的變化:
% INITIALIZE
NN = 9;
L = rand(1,NN-1);
while numel(L) ~= NN;
L = unique(randi(100,1,NN)); end
% Some bogus constraints
constraints = [...
L(1) L(2)
L(3) L(6)
L(3) L(5)
L(8) L(4)];
% METHOD 0 (your original method)
tic
orderings = perms(L);
p = size(orderings,1);
c = size(constraints,1);
toKeep = true(p,1);
for perm = 1:p
for constr = 1:c
idxA = find(orderings(perm,:) == constraints(constr,1));
idxB = find(orderings(perm,:) == constraints(constr,2));
if idxA > idxB
toKeep(perm) = false;
end
end
end
orderings0 = orderings(toKeep,:);
toc
% METHOD 1 (your original, plus a few optimizations)
tic
orderings = perms(L);
p = size(orderings,1);
c = size(constraints,1);
toKeep = true(p,1);
for perm = 1:p
for constr = 1:c
% break on first condition breached
if toKeep(perm)
% find only *first* entry
toKeep(perm) = ...
find(orderings(perm,:) == constraints(constr,1), 1) < ...
find(orderings(perm,:) == constraints(constr,2), 1);
else
break
end
end
end
orderings1 = orderings(toKeep,:);
toc
% METHOD 2
tic
orderings = perms(L);
p = size(orderings,1);
c = size(constraints,1);
toKeep = true(p,1);
for constr = 1:c
% break on first condition breached1
if any(toKeep)
% Vectorized search for constraint values
[i1, j1] = find(orderings == constraints(constr,1));
[i2, j2] = find(orderings == constraints(constr,2));
% sort by rows
[i1, j1i] = sort(i1);
[i2, j2i] = sort(i2);
% Check if columns meet condition
toKeep = toKeep & j1(j1i) < j2(j2i);
else
break
end
end
orderings2 = orderings(toKeep,:);
toc
% Check for equality
all(orderings2(:) == orderings1(:))
結果:
Elapsed time is 17.911469 seconds. % your method
Elapsed time is 10.477549 seconds. % your method + optimizations
Elapsed time is 2.184242 seconds. % vectorized outer loop
ans =
1
ans =
1
然而,整個方法有一個根本的缺陷恕我直言;直接使用perms
。這由於內存限制而固有地構成限制(NN < 10
,如在help perms
中所述)。
我有一個強烈的懷疑,你可以得到更好的性能,無論是在時間上和記憶方面,當你把自定義perms
。幸運的是,perms
不是內置的,因此您可以通過將該代碼複製粘貼到自定義函數中開始。
每當你在向量或矩陣中尋找東西時,都應該使用find或ismember。 – 2013-06-03 08:54:10
當然。建議的解決方案是一個僞代碼(perms指令除外)。但是,我認爲這不是可能的最佳解決方案,因爲我必須遍歷所有排序和所有約束。但是,我更新了代碼(現在不是僞代碼)。 – Eleanore
最好[不要在Matlab中使用'i'和'j'作爲變量名](http://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab) 。 – Shai