Java 互依变量组合优化
这是我在这些论坛上的第一篇帖子,提前感谢所有回复 我正在开发一个java应用程序,在这个应用程序中我遇到了我认为被称为“组合优化问题”的问题。我只有基本的数学技能,所以试图研究这样一个问题的设置到目前为止还没有取得成果 基本上,我想做的是编程最有效的方法,用变量v1、v2、v3等找到更大集合n的最优子集n。除了依赖于子集中可能包含或可能不包含的某些其他变量的值/分数外,这些变量都有一个确定的值/分数 我感兴趣的是选择给出最大总值/分数的子集 例如,全集N由以下变量组成,具有以下定值以及与其他变量的关系:Java 互依变量组合优化,java,algorithm,mathematical-optimization,combinatorics,Java,Algorithm,Mathematical Optimization,Combinatorics,这是我在这些论坛上的第一篇帖子,提前感谢所有回复 我正在开发一个java应用程序,在这个应用程序中我遇到了我认为被称为“组合优化问题”的问题。我只有基本的数学技能,所以试图研究这样一个问题的设置到目前为止还没有取得成果 基本上,我想做的是编程最有效的方法,用变量v1、v2、v3等找到更大集合n的最优子集n。除了依赖于子集中可能包含或可能不包含的某些其他变量的值/分数外,这些变量都有一个确定的值/分数 我感兴趣的是选择给出最大总值/分数的子集 例如,全集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天内计算出了解决方案
我不一定需要一个代码来解决这个问题,而是需要一个最佳的数学方法来解决这个问题(如果有的话!)。但请记住,我很难理解基本水平以上的数学符号
再次感谢所有回复 您可以将集合视为图形。每个vX是一个具有各自值的节点/顶点。示例v1是值为8的节点/vertice,v2是值为6的节点/vertice,等等。它们之间有边。示例v1有两条边:一条用于v2,另一条用于v8。每个边也可以有一个值(在您的示例中为-1) 因此,如果您使用图形,并选择v1到v5:您有8+6+9+7+6(垂直值)-1-1-1-1-1-1(边缘值) 试着看看这个,看看它是否对你有帮助
另请参见一些图表理论:。观察最长/最短路径算法(示例:)不幸的是,该问题是NP难问题,无法找到最优解 如果您可以有效地解决这个问题,那么您可以通过将每个顶点的值设置为1来解决NP难题,并对每个边进行非常大的惩罚
所以你应该寻找近似解。您可能会发现,使用模拟退火或遗传算法可以得到合理的答案。对于线性规划解算器,输入如下内容
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
最大化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
从属于
v1+v2-v1v2花费了我相当长的时间,但我现在已经尝试掌握这里提到的几个解决方案。我最终用模拟退火法结束了。不确定它是否是正确的/最佳的解决方案,但至少它很容易理解和实现——而且它似乎在我尝试做的事情中表现得相当好。谢谢你的建议!