如何找到最佳总和

时间:2014-03-18 17:48:20

标签: mathematical-optimization

想象一下这组价值观:

      A B C
LINE1 2 1 1
LINE2 1 4 1
LINE3 3 1 3
LINE4 6 5 4

我可以从1到3为每行选择一个值。如果我从特定列中选择一个值,我需要将第4行的值相加。

示例:

2 (LINE1, COLUMN A)
1 (LINE2, COLUMN A)
3 (LINE3, COLUMN C)

因此,当我从COLUMN A中选择值时,我需要将它们与LINE 4的值相加。最终结果:

      A B C
LINE1 2 - -
LINE2 1 - -
LINE3 - - 3
LINE4 6 - 4 

2 + 1 + 6 = 9
3 + 4 = 7
TOTAL: 16

事实是:我需要从组合中检索较小的总数。我随机选择了示例中的数字,但我的算法需要选择能够得到总数较小的数字。

我认为最佳解决方案是从COLUMN C(TOTAL:9)中选择所有数字,但是我需要从不同列中选择数字。

我认为这是一个优化问题,我认为使用单纯形,但我不知道如何开始开发。

谢谢!

3 个答案:

答案 0 :(得分:2)

这似乎是所谓的0-1分配问题的一个例子;对该术语的网络搜索应该会产生大量的点击。这是线性编程问题的一个特例。有几个软件包可能很有用。我已经使用GLPK解决了各种问题,并发现它非常有用。不要试图为这个问题编写软件;这是非常困难的,你不用担心。

要将此描述为0-1赋值问题,让Ajk为您显示的表中的值,并引入二进制变量x11,x12,x13; x21,x22,x23; x31,x32,x33;等等(即第j行的第k个元素的xjk)并且最小化xjk乘以Ajk的总和,受限于每行j的行和xj1 + xj2 + xj3 = 1。也就是说,xjk选择(如果xjk = 1)或省略(如果xjk = 0)对应的值Ajk,并且从每一行中选择恰好一个值。

例如,GLPK允许您用非常类似的术语来描述这些问题。

如果我误解了这个问题,你就必须调整我所说的约束等等。祝你好运玩得开心。受限制的优化问题总是很有意思。

答案 1 :(得分:2)

这是我在GNU MathProg建模语言中使用GLPK提出的解决方案。注意:这是我在MathProg中写的第一件事,所以非常欢迎反馈。

具体而言,我不确定我链接x []和s []的方式是否有效(我更常用于SAT CNF编码而不是ILP)。

将代码保存为test.mod并使用glpsol --math test.mod执行。

set A, dimen 3;
set B, dimen 2;

set I := setof{(i,j,v) in A} i;
set J := setof{(i,j,v) in A} j;

var x{I, J}, binary;
var s{J}, binary;

s.t. lines {i in I}:
  sum{j in J} x[i, j] = 1;

s.t. rows {j in J, i in I}:
  x[i, j] <= s[j];

minimize obj:
  (sum{(i,j,v) in A} x[i, j]*v) + (sum{(j,v) in B} s[j]*v);

solve;

printf "Result:\n";
printf {(i,j,v) in A : x[i, j] == 1} " %3d %3d %5d\n", i, j, v;
printf {(j,v) in B : s[j] == 1} " --- %3d %5d\n", j, v;
printf " --- --- %5d\n", (sum{(i,j,v) in A} x[i, j]*v) + (sum{(j,v) in B} s[j]*v);
printf "\n";

data;

set A :=
# Line 1
  1 1 2
  1 2 1
  1 3 1
# Line 2
  2 1 1
  2 2 4
  2 3 1
# Line 3
  3 1 3
  3 2 1
  3 3 3;

set B :=
# Line 4
  1 6
  2 5
  3 4;

end;

感谢罗伯特建议GLPK并在答案中提供解决方案的大纲。

答案 2 :(得分:1)

在这个例子中,您可以选择七组列:A,B,C,A和B,A和C,B和C,A,B和C.如果这组列是固定的您选择属于​​其中一列的每一行中的最小值。最小的总数是赢家。

A: 2 + 1 + 3 + 6 = 12.
B: 1 + 4 + 1 + 5 = 11
C: 1 + 1 + 3 + 4 = 9

AB: 1 + 1 + 1 + 6 + 5 = 14
AC: 1 + 1 + 3 + 6 + 4 = 15
BC: 1 + 1 + 1 + 5 + 4 = 12

ABC: 1 + 1 + 1 + 6 + 5 + 4 = 18.

当然对于k列,几乎有2 ^ k种可能性来选择列;对于每个列的选择,其余的计算都是微不足道的。