Mathematica 中的二次规划

发布于 2024-10-19 19:48:18 字数 1271 浏览 3 评论 0原文

我正在研究最大独立集问题的二次松弛(p.22 此处 ),并发现 FindMaximum 对于我尝试的每个图表都会失败,除非我将最佳解决方案作为起点。这些二次规划有 10-20 个变量,所以我希望它们是可解的。

  1. 有没有办法让 Mathematica 求解这样的二次规划?
  2. 是否有一些可以轻松从 Mathematica 中调用的二次编程包?

这是 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}]]

下面是我尝试过的其他图表

{"DodecahedralGraph", "FruchtGraph", "TruncatedPrismGraph", \
"TruncatedTetrahedralGraph", {"Cubic", {10, 2}}, {"Cubic", {10, 
   3}}, {"Cubic", {10, 4}}, {"Cubic", {10, 6}}, {"Cubic", {10, 
   7}}, {"Cubic", {10, 11}}, {"Cubic", {10, 12}}, {"Cubic", {12, 
   5}}, {"Cubic", {12, 6}}, {"Cubic", {12, 7}}, {"Cubic", {12, 
   9}}, {"Cubic", {12, 10}}}

I'm looking at quadratic relaxation of maximum independent set problem (p.22 here), and found that FindMaximum fails for every graph I try, unless I give it optimal solution as the starting point. These quadratic programmes have 10-20 variables, so I expect them to be solvable.

  1. Is there a way to make Mathematica solve such quadratic programmes?
  2. Is there some quadratic programming package that's easy to call from within Mathematica?

Here's an example of failing FindMaximum, followed by working FindMaximum initialized at the solution

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}]]

Here are other graphs I tried

{"DodecahedralGraph", "FruchtGraph", "TruncatedPrismGraph", \
"TruncatedTetrahedralGraph", {"Cubic", {10, 2}}, {"Cubic", {10, 
   3}}, {"Cubic", {10, 4}}, {"Cubic", {10, 6}}, {"Cubic", {10, 
   7}}, {"Cubic", {10, 11}}, {"Cubic", {10, 12}}, {"Cubic", {12, 
   5}}, {"Cubic", {12, 6}}, {"Cubic", {12, 7}}, {"Cubic", {12, 
   9}}, {"Cubic", {12, 10}}}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

美男兮 2024-10-26 19:48:18

可以尝试位于此处的包中显示的方法。参见问题 8

Daniel Lichtblau
沃尔夫勒姆研究公司

Might try method shown in package located here. See problem 8

Daniel Lichtblau
Wolfram Research

吃素的狼 2024-10-26 19:48:18

看来 Maximize 会更好地为您服务。这是您的函数的修改版本,它返回 2 个结果的列表 - “手动”结果和通过 Maximize 获得的结果:

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]}];

以下是结果:

In[32]:= graphs = GraphData /@ {"DodecahedralGraph", "FruchtGraph", 
"TruncatedPrismGraph", "TruncatedTetrahedralGraph", {"Cubic", {10, 2}}, {"Cubic", {10, 
  3}}, {"Cubic", {10, 4}}, {"Cubic", {10, 6}}, {"Cubic", {10, 
  7}}, {"Cubic", {10, 11}}, {"Cubic", {10, 12}}, {"Cubic", {12, 
  5}}, {"Cubic", {12, 6}}, {"Cubic", {12, 7}}, {"Cubic", {12, 
  9}}, {"Cubic", {12, 10}}};


In[33]:= sets = findIVSet /@ graphs

Out[33]= {{{1, 2, 3, 8, 10, 11, 17, 20}, {5, 6, 7, 8, 14, 15, 17, 18}},
{{2, 4, 6, 11, 12}, {2, 4, 6, 11, 12}}, {{2, 7, 10, 12, 16, 18}, {8, 11, 13, 16, 17, 18}}, 
{{1, 4, 7, 12}, {4, 7, 9, 12}}, {{2,3, 8, 9}, {2, 3, 8, 9}}, {{1, 4, 7, 10}, {2, 5, 8, 9}}, 
{{1, 4, 7, 10}, {2, 4, 7, 9}}, {{2, 4, 5, 8}, {3, 6, 7, 9}}, {{2, 5, 8, 9}, {2, 5, 8, 9}}, 
{{1, 3, 7, 10}, {4, 5, 8, 9}}, {{1, 6, 8, 9}, {2, 3, 6, 10}}, {{1, 6, 7, 12}, {4, 5, 9, 10}}, 
{{3, 4, 7, 8, 12}, {3, 4, 7, 8, 12}}, {{1, 5, 8, 9}, {4, 5, 10, 11}}, 
{{1, 5, 6, 9, 10}, {3, 4, 7, 8, 12}}, {{3, 4, 7, 9, 10}, {3, 4, 7, 9, 10}}}

“手动”结果并不总是相同” 和那些来自 Maximize 的,但是还有更多
独立组的一个解决方案。 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}

It seems that Maximize will serve you better. Here is a modified version of your function, which returns a list of 2 results - the "manual" one and the one obtained by Maximize:

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]}];

Here are the results:

In[32]:= graphs = GraphData /@ {"DodecahedralGraph", "FruchtGraph", 
"TruncatedPrismGraph", "TruncatedTetrahedralGraph", {"Cubic", {10, 2}}, {"Cubic", {10, 
  3}}, {"Cubic", {10, 4}}, {"Cubic", {10, 6}}, {"Cubic", {10, 
  7}}, {"Cubic", {10, 11}}, {"Cubic", {10, 12}}, {"Cubic", {12, 
  5}}, {"Cubic", {12, 6}}, {"Cubic", {12, 7}}, {"Cubic", {12, 
  9}}, {"Cubic", {12, 10}}};


In[33]:= sets = findIVSet /@ graphs

Out[33]= {{{1, 2, 3, 8, 10, 11, 17, 20}, {5, 6, 7, 8, 14, 15, 17, 18}},
{{2, 4, 6, 11, 12}, {2, 4, 6, 11, 12}}, {{2, 7, 10, 12, 16, 18}, {8, 11, 13, 16, 17, 18}}, 
{{1, 4, 7, 12}, {4, 7, 9, 12}}, {{2,3, 8, 9}, {2, 3, 8, 9}}, {{1, 4, 7, 10}, {2, 5, 8, 9}}, 
{{1, 4, 7, 10}, {2, 4, 7, 9}}, {{2, 4, 5, 8}, {3, 6, 7, 9}}, {{2, 5, 8, 9}, {2, 5, 8, 9}}, 
{{1, 3, 7, 10}, {4, 5, 8, 9}}, {{1, 6, 8, 9}, {2, 3, 6, 10}}, {{1, 6, 7, 12}, {4, 5, 9, 10}}, 
{{3, 4, 7, 8, 12}, {3, 4, 7, 8, 12}}, {{1, 5, 8, 9}, {4, 5, 10, 11}}, 
{{1, 5, 6, 9, 10}, {3, 4, 7, 8, 12}}, {{3, 4, 7, 9, 10}, {3, 4, 7, 9, 10}}}

They are not always the same for "manual" ones and those from Maximize, but then there is more than
one solution for an independent set. The results from Maximize are all independent sets, which is easily verified:

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}
我也只是我 2024-10-26 19:48:18

IMO,FindMaximum 在这里不起作用的原因是你的函数的野性。我尝试了在可变空间中包含 1,048,576 个样本的网格,但没有一个获得比零更高的值。您的最佳起始值为-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

输出[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}

IMO, the reason FindMaximum doesn't work here is the wild nature of your function. I tried a grid with 1,048,576 samples in variable space and none achieve a higher value than zero. Your optimum starting value gets -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}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文