Wolfram mathematica 数学中的二次规划
我在研究最大独立集问题的二次松弛(第22页),发现Wolfram mathematica 数学中的二次规划,wolfram-mathematica,graph-theory,mathematical-optimization,Wolfram Mathematica,Graph Theory,Mathematical Optimization,我在研究最大独立集问题的二次松弛(第22页),发现FindMaximum对于我尝试的每一个图都失败了,除非我给出它的最优解作为起点。这些二次规划有10-20个变量,所以我希望它们是可解的 有没有办法让Mathematica解这样的二次规划 在Mathematica内部是否有易于调用的二次规划包 下面是一个失败的示例FindMaximum,然后在解决方案中初始化工作FindMaximum setupQuadratic[g_Graph] := ( Ag = AdjacencyMatrix[g]
FindMaximum
对于我尝试的每一个图都失败了,除非我给出它的最优解作为起点。这些二次规划有10-20个变量,所以我希望它们是可解的
FindMaximum
,然后在解决方案中初始化工作FindMaximum
setupQuadratic[g_Graph] := (
Ag = AdjacencyMatrix[g];
A = IdentityMatrix[Length@VertexList@g] - Ag;
cons = And @@ Table[0 <= x[v] <= 1, {v, VertexList@g}];
vars = x /@ VertexList[g];
indSet = FindIndependentVertexSet@g;
xOpt = Array[Boole[MemberQ[indSet, #]] &, {Length@VertexList@g}];
);
g = GraphData[{"Cubic", {10, 11}}];
setupQuadratic[g];
FindMaximum[{vars.A.vars, cons}, vars]
FindMaximum[{vars.A.vars, cons}, Thread[{vars, xOpt}]]
看来,
最大化
将为您提供更好的服务。这是您的函数的一个修改版本,它返回一个包含两个结果的列表—“手动”结果和通过最大化
获得的结果:
Clear[findIVSet];
findIVSet[g_Graph] :=
Module[{Ag, A, cons, vars, indSet, indSetFromMaximize, xOpt},
Ag = AdjacencyMatrix[g];
A = IdentityMatrix[Length@VertexList@g] - Ag;
cons = And @@ Table[0 <= x[v] <= 1, {v, VertexList@g}];
vars = x /@ VertexList[g];
indSet = FindIndependentVertexSet@g;
xOpt = Array[Boole[MemberQ[indSet, #]] &, {Length@VertexList@g}];
{indSet, DeleteCases[vars /. (Last@
Maximize[{vars.A.vars, cons}, vars,Integers] /. (x[i_] -> 1) :> (x[i] -> i)), 0]}];
对于“手动”的和来自最大化的那些,它们并不总是相同的,但是还有不止一个
独立集的一个解。Maximize
的结果都是独立的集合,很容易验证:
In[34]:= MapThread[IndependentVertexSetQ, {graphs, sets[[All, 2]]}]
Out[34]= {True, True, True, True, True, True, True, True, True, True, True, True, True,
True, True,True}
在我看来,FindMaximum在这里不起作用的原因是函数的狂野性。我在可变空间中尝试了一个包含1048576个样本的网格,没有一个样本的值高于零。您的最佳起始值为-20
In[10]:= (x[1]^2 + x[2]^2 + x[3]^2 - 2 x[3] x[4] + x[4]^2 -
2 x[2] (x[3] + x[4]) + x[5]^2 - 2 x[3] x[6] - 2 x[5] x[6] +
x[6]^2 - 2 x[5] x[7] + x[7]^2 - 2 x[6] x[8] - 2 x[7] x[8] +
x[8]^2 - 2 x[7] x[9] + x[9]^2 - 2 x[1] (x[2] + x[5] + x[9]) -
2 x[4] x[10] - 2 x[8] x[10] - 2 x[9] x[10] + x[10]^2 /.
Thread[vars -> #]) & @@@ Tuples[{0.0, 0.333, 0.667, 1.0}, 10] // Max
Out[10]=0
In[11]:= (x[1]^2 + x[2]^2 + x[3]^2 - 2 x[3] x[4] + x[4]^2 -
2 x[2] (x[3] + x[4]) + x[5]^2 - 2 x[3] x[6] - 2 x[5] x[6] +
x[6]^2 - 2 x[5] x[7] + x[7]^2 - 2 x[6] x[8] - 2 x[7] x[8] +
x[8]^2 - 2 x[7] x[9] + x[9]^2 - 2 x[1] (x[2] + x[5] + x[9]) -
2 x[4] x[10] - 2 x[8] x[10] - 2 x[9] x[10] + x[10]^2 /.
Thread[vars -> #]) & @@@ {xOpt}
Out[11]= {-20}
可能尝试位于的包中显示的方法。见问题8
丹尼尔·利奇布劳
Wolfram Research您链接的论文非常好。谢谢我已经有了FindIndependentVertexSet中的独立集,它可能会在内部使用类似于你所建议的东西,我实际上感兴趣的是找到原始二次,实数的最大值domain@Yaroslav你为什么对真正的领域感兴趣?据我所见,在你链接的文章中明确指出,所有变量只能有值0或1(即整型域)。那么,对于这个问题,是什么让你认为实域的结果与最大独立集问题有关呢?很明显,我们不是在寻找局部极值,所以约束很重要。用连续约束找到的极值可能与用离散约束找到的极值大不相同。还是我完全没有抓住要点?因为在整数域中求解它是NP完全的,而实值QP编程是容易处理的。丢弃整数约束被称为“松弛”,它对某些类型的图出人意料地有效--@Yaroslav它是可处理的,但最大化是非凸的(在这种情况下,最小化是凸的)。所以不能保证全局性。有趣的是,我想这个QP并不像我想的那么容易。显然,此类非凸QP问题被称为“盒子QP”。上述目标简化为次[-20,幂[Slot[1],2]]
后的ReplaceAll
。评估原始目标的一种方法是vars.A.vars/。线程[vars->xOpt]
顺便说一句,如果您将@@
替换为
或者将
替换为{code>}
(但不能同时替换两者!),则可以修复上述问题。我扩展了vars.A.vars,因为它在我的机器上节省了2.3倍的时间。我知道第二部分可能写得不一样。我这样做只是为了保持代码的结构不变。我的观点是有一个bug,目标应该是4
atxOpt
,而不是-20
有趣,谢谢。顺便说一句,通过使用二次规划的SDP松弛,我也得到了很好的结果--
In[10]:= (x[1]^2 + x[2]^2 + x[3]^2 - 2 x[3] x[4] + x[4]^2 -
2 x[2] (x[3] + x[4]) + x[5]^2 - 2 x[3] x[6] - 2 x[5] x[6] +
x[6]^2 - 2 x[5] x[7] + x[7]^2 - 2 x[6] x[8] - 2 x[7] x[8] +
x[8]^2 - 2 x[7] x[9] + x[9]^2 - 2 x[1] (x[2] + x[5] + x[9]) -
2 x[4] x[10] - 2 x[8] x[10] - 2 x[9] x[10] + x[10]^2 /.
Thread[vars -> #]) & @@@ Tuples[{0.0, 0.333, 0.667, 1.0}, 10] // Max
In[11]:= (x[1]^2 + x[2]^2 + x[3]^2 - 2 x[3] x[4] + x[4]^2 -
2 x[2] (x[3] + x[4]) + x[5]^2 - 2 x[3] x[6] - 2 x[5] x[6] +
x[6]^2 - 2 x[5] x[7] + x[7]^2 - 2 x[6] x[8] - 2 x[7] x[8] +
x[8]^2 - 2 x[7] x[9] + x[9]^2 - 2 x[1] (x[2] + x[5] + x[9]) -
2 x[4] x[10] - 2 x[8] x[10] - 2 x[9] x[10] + x[10]^2 /.
Thread[vars -> #]) & @@@ {xOpt}
Out[11]= {-20}