我有一个向量#secondary { /* left Sidebar */
width: 18rem;
margin-left: -67rem;
float: left;
position: relative;
}
#tertiary { /* right Sidebar */
width: 18rem;
margin-right: -23rem;
float: right;
position: relative;
}
,即
A
我试图找到一组由此向量A = [300; 165; 150; 150; 400; 300; 80; 250; 165; 80; 200]
的元素组成的向量,以便它们的元素总和尽可能接近400的值,以便向量{{的所有元素1}}包含在不相交的向量集中。
例如,400已经是400,所以这是第一组没有松弛的向量。
另一组是A
的向量,它们的总和是400.
另外两个可以是两组向量A
,它们的总和是380,所以20的松弛就会受到影响。
另一个是[250 150]
,他们总计330,松弛70.最后一个是200和150,松弛50。总松弛是20 + 20 + 70 + 50 = 160。
我正在尝试找到一种可以最大限度地减少松弛的启发式或算法(不是编程模型)。我在Matlab编码。
答案 0 :(得分:1)
您可以尝试这样的事情:
v = [300; 165; 150; 150; 400; 300; 80; 250; 165; 80; 200];
binarystr = dec2bin(1:(2^(length(v))-1));
bincell = mat2cell(binarystr,ones(size(binarystr ,1),1),ones(size(binarystr ,2),1));
bin = cellfun(@(x) str2double(x),bincell);
现在您可以乘以找到所有组合:
comb = b*v;
找到最低
target = 400;
[val,index] = min(abs(comb-target));
如果你想知道组合是什么,你可以寻找索引:
idxs = find(bin(index,:));
,值为:
disp(idxs)
disp(v(idxs))
希望这有帮助。
答案 1 :(得分:0)
所以我认为这是一个非常有趣的问题,并在工作中开始(我希望我的老板不会发现),但我错过了一部分。代码非常可怕,但我想展示我猜的概念。
A = [300; 165; 150; 150; 400; 300; 80; 250; 165; 80; 200] ;
P = (1 - (sum(A) /400 - floor(sum(A)/400))) * 400; %//minimum slack to be achieved
%//Round 1
G1 = zeros(floor(sum(A)/400)+1,3)
for t = 1:floor(sum(A)/400)+1
if size(A,1) > 1
%//single combination
[F indF] = min(abs(A-400));
%//double combination
if size(A >1)
D = combntns(A,2);
sumD = sum(D,2);
[F2 indF2] = min(abs(sumD-400));
end
%//triple combination
if size(A >2)
T = combntns(A,3);
sumT = sum(T,2);
[F3 indF3] = min(abs(sumT-400));
end
%remove 1
[R removeInd] = min([F,F2,F3]);
if removeInd == 1
G1(t,1) = A(indF);
A(indF) =[];
else if removeInd ==2
G1(t,1:2) = D(indF2,:) ;
[tmp,tmp2] = intersect(A,G1(t,:));
A(tmp2) = [];
else removeInd == 3
G1(t,:) = T(indF3,:) ;
[tmp,tmp2] = intersect(A,G1(t,:));
A(tmp2) = [] ;
end
end
else if size(A,1) == 1
G1(t,1) = A;
end
end
end
</pre></code>
the results:
>>400 0 0
150 250 0
165 150 80
300 80 0
165 200 0
300 0 0
The reason the results were wrong is because I searched for subsets with length of 1,2 and 3. 4 is not possible, since it produce huge results (but you can include it anyways). If I switch to subsets with length of 1 and 2 I get the right answer. So I think the step I am missing is how long my subsets can be.
results when max length of subset is set to 2:
>>400 0 0
150 250 0
300 80 0
300 80 0
165 200 0
165 150 0
你要做的只是三重组合%,并改变这一行:[R removeInd] = min([F,F2]);没有F3