这是一个普通的 Octave(或 Matlab)解决方案。矩阵Distances
与问题相同。该算法构建一个 0-1 矩阵a
,其中每一列编码一个距离总和小于limit
(例如 10)的集合。
矩阵a
用恒等元初始化,因为所有单元素子集都是可接受的(距离之和为 0)。然后选择每一列c = a(:,m);
并研究添加另一个元素的可能性(cand = c; cand(k) = 1;
意味着添加第 k 个元素)。不失一般性,只考虑在集合的最后一个当前元素之后添加元素就足够了。
乘积cand'*Distances*cand
是候选集距离之和的两倍cand
。因此,如果它小于限制的两倍,则添加该列:a = [a cand];
. 最后,a
为了便于阅读,矩阵以转置形式显示。
limit = 10;
n = length(Distances);
a = eye(n, n);
col1 = 1;
col2 = n;
while (col1 <= col2)
for m = col1:col2
c = a(:,m);
for k = max(find(c>0))+1:n
cand = c;
cand(k) = 1;
if cand'*Distances*cand < 2*limit
a = [a cand];
end
end
end
col1 = col2 + 1;
col2 = length(a);
end
disp(a')
输出:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
1 1 0 0 0
1 0 1 0 0
1 0 0 1 0
0 1 1 0 0
0 1 0 1 0
0 0 0 1 1
对于 250 x 250 矩阵,性能在很大程度上取决于大小limit
。如果它太大以至于所有或大部分 2^250 集都符合条件,那么这将耗尽内存。(2 ^ 250 比 10 ^ 75 多,所以我认为你不会想在这么多套附近看到任何地方)。
这是为了以更易读的形式输出:
for m = 1:length(a)
disp(find(a(:,m))')
end
输出:
1
2
3
4
5
1 2
1 3
1 4
2 3
2 4
4 5