具有相互依赖变量的组合优化

时间:2016-12-20 11:52:36

标签: java algorithm mathematical-optimization combinatorics

这是我在这些论坛上的第一篇文章,感谢所有回复。

我正在开发一个java应用程序,在其中我遇到了我认为被称为“组合优化问题”的问题。我只有基本的数学技能,所以到目前为止,试图调查这样一个问题的设置并不富有成效。

基本上,我想要做的是编写一个最有效的方法来找到一个更大的集合N的最佳子集n与变量v1,v2,v3等。变量都有一个确定的值/得分除了值/分数取决于可能包含或可能不包含在子集中的某些其他变量。

我有兴趣选择能够给出最大总值/得分的子集。

因此,例如,完整集N由以下变量组成,并具有以下确定值以及与其他变量的关系:

v1  8   { v2 ; v8 }
v2  6   { v1 ; v4 }
v3  9   { }
v4  7   { v2 ; v5 ; v8 }
v5  6   { v4 ; v10 }
v6  8   { v7 }
v7  5   { v6 }
v8  9   { v1 ; v4 }
v9  6   { } 
v10 7   { v5 }

与一个或多个其他选定变量有关系意味着总值将具有一定的“起飞” - 为了这个例子,我们为每个关系说一个。 因此,选择前五个变量作为子集将得到总值30:

v1  8   { v2 ; v8 }      = 8 - 1 = 7
v2  6   { v1 ; v4 }      = 6 - 2 = 4
v3  9   { }              = 9 - 0 = 9
v4  7   { v2 ; v5 ; v8 } = 7 - 2 = 5
v5  6   { v4 ; v10 }     = 6 - 1 = 5

这对于这样的小套装当然不是问题,但我目前面临100K的套装和10K的子集 - 使用当前算法,我的电脑在3天内计算出解决方案!

我不一定需要一个代码来解决这个问题,而是需要最佳的数学方法(如果有的话!)。请记住,虽然我很难理解基本水平以上的数学符号。

再次感谢所有回复!

3 个答案:

答案 0 :(得分:1)

对于线性程序求解器,请输入

之类的输入
v1  8   { v2 ; v8 }
v2  6   { v1 ; v4 }
v3  9   { }
v4  7   { v2 ; v5 ; v8 }
v5  6   { v4 ; v10 }
v6  8   { v7 }
v7  5   { v6 }
v8  9   { v1 ; v4 }
v9  6   { }
v10 7   { v5 }

并将其转换为整数程序,如

maximize   8*v1 - v1v2 - v1v8
         + 6*v2 - v2v1 - v2v4
         + 9*v3
         + 7*v4 - v4v2 - v4v5 - v4v8
         + 6*v5 - v5v4 - v5v10
         + 8*v6 - v6v7
         + 5*v7 - v7v6
         + 9*v8 - v8v1 - v8v4
         + 6*v9
         + 7*v10 - v10v5

subject to
v1 + v2 - v1v2 <= 1
v1 + v8 - v1v8 <= 1
v2 + v1 - v2v1 <= 1
v2 + v4 - v2v4 <= 1
v4 + v2 - v4v2 <= 1
v4 + v5 - v4v5 <= 1
v4 + v8 - v4v8 <= 1
v5 + v4 - v5v4 <= 1
v5 + v10 - v5v10 <= 1
v6 + v7 - v6v7 <= 1
v7 + v6 - v7v6 <= 1
v8 + v1 - v8v1 <= 1
v8 + v4 - v8v4 <= 1
v10 + v5 - v10v5 <= 1

binary v1, v1v2, v1v8,
       v2, v2v1, v2v4,
       v3,
       v4, v4v2, v4v5, v4v8,
       v5, v5v4, v5v10,
       v6, v6v7,
       v7, v7v6,
       v8, v8v1, v8v4,
       v9,
       v10, v10v5

您的实例大小对于最佳解决方案来说可能太多了,但是人们永远不会知道......

答案 1 :(得分:0)

您可以将自己的设置视为图表。每个vX是具有相应值的节点/顶点。示例v1是值为8的节点/顶点,v2是值为6的节点/顶点,等等。然后在它们之间存在边。示例v1有2条边:一条用于v2,另一条用于v8。每个边也可以有一个值(在你的情况下为-1)。

因此,如果你使用图形,并选择v1到v5:你有8 + 6 + 9 + 7 + 6(顶点值)-1 -1 -1 -1 -1 -1(边缘值)。

尝试查看此http://jgrapht.org/以了解它是否对您有所帮助。

另见Graph Teory:http://www.people.vcu.edu/~gasmerom/MAT131/graphs.html。观察最长/最短路径算法(例如:http://www.maxburstein.com/blog/introduction-to-graph-theory-finding-shortest-path/

答案 2 :(得分:0)

不幸的是,这个问题很难找到最佳解决方案。

如果你能有效地解决这个问题,那么你可以通过将每个顶点的值设置为1来解决NP-hard maximum independent set problem,并为每个边缘设置一个非常大的惩罚。

所以你应该寻找近似的解决方案。您可能会发现模拟退火或遗传算法可以得到合理的答案。