9

我对Mathematica的全局优化功能有疑问。我遇到了与NAG工具箱(kind of white paper)相关的文本。Mathematica优化模块的限制

现在我试着从论文中解决测试案例。正如预期的那样,Mathematica解决这个问题的速度非常快。

n=2; 
fun[x_,y_]:=10 n+(x-2)^2-10Cos[2 Pi(x-2)]+(y-2)^2-10 Cos[2 Pi(y-2)]; 
NMinimize[{fun[x,y],-5<= x<= 5&&-5<= y<= 5},{x,y},Method->{"RandomSearch","SearchPoints"->13}]//AbsoluteTiming 

产量为

{0.0470026,{0.,{x->2.,y->2.}}} 

可以看到通过优化程序访问点。

{sol, pts}=Reap[NMinimize[{fun[x,y],-5<= x<= 5&&-5<= y<= 5},{x,y},Method->`{"RandomSearch","SearchPoints"->13},EvaluationMonitor:>Sow[{x,y}]]];Show[ContourPlot[fun[x,y],{x,-5.5,5.5},{y,-5.5,5.5},ColorFunction->"TemperatureMap",Contours->Function[{min,max},Range[min,max,5]],ContourLines->True,PlotRange-> All],ListPlot[pts,Frame-> True,Axes-> False,PlotRange-> All,PlotStyle-> Directive[Red,Opacity[.5],PointSize[Large]]],Graphics[Map[{Black,Opacity[.7],Arrowheads[.026],Arrow[#]}&,Partition[pts//First,2,1]],PlotRange-> {{-5.5,5.5},{-5.5,5.5}}]]` 

Convergence path of NMinimize

现在我想在更高的层面解决同一问题的。对于五个变量的数学问题,即使在允许大量搜索点的情况下,数学开始陷入局部最小值的陷阱。

n=5;funList[x_?ListQ]:=Block[{i,symval,rule}, 
i=Table[ToExpression["x$"<>ToString[j]],{j,1,n}];symval=10 n+Sum[(i[[k]]-2)^2-10Cos[2Pi(i[[k]]-2)],{k,1,n}];rule=MapThread[(#1-> #2)&,{i,x}];symval/.rule]val=Table[RandomReal[{-5,5}],{i,1,n}];vars=Table[ToExpression["x$"<>ToString[j]],{j,1,n}];cons=Table[-5<=ToExpression["x$"<>ToString[j]]<= 5,{j,1,n}]/.List-> And;NMinimize[{funList[vars],cons},vars,Method->{"RandomSearch","SearchPoints"->4013}]//AbsoluteTiming 

输出不是我们希望看到的。在我的core2duo机器上花了49秒,仍然是当地的最低要求。

{48.5157750,{1.98992,{x$1->2.,x$2->2.,x$3->2.,x$4->2.99496,x$5->1.00504}}} 

然后尝试使用SimulatedAnealing进行100000次迭代。

NMinimize[{funList[vars],cons},vars,Method->"SimulatedAnnealing",MaxIterations->100000]//AbsoluteTiming 

产量仍不理想。

{111.0733530,{0.994959,{x$1->2.,x$2->2.99496,x$3->2.,x$4->2.,x$5->2.}}} 

现在Mathematica有一个名为Minimize的精确优化算法。正如预期的那样,实际上会失败,但随着问题规模的增加,它会很快失败。

n=3;funList[x_?ListQ]:=Block[{i,symval,rule},i=Table[ToExpression["x$"<>ToString[j]],{j,1,n}];symval=10 n+Sum[(i[[k]]-2)^2-10Cos[2 Pi(i[[k]]-2)],{k,1,n}];rule=MapThread[(#1-> #2)&,{i,x}];symval/.rule]val=Table[RandomReal[{-5,5}],{i,1,n}];vars=Table[ToExpression["x$"<>ToString[j]],{j,1,n}];cons=Table[-5<=ToExpression["x$"<>ToString[j]]<= 5,{j,1,n}]/.List-> And;Minimize[{funList[vars],cons},vars]//AbsoluteTiming 

输出完全没问题。

{5.3593065,{0,{x$1->2,x$2->2,x$3->2}}} 

但是,如果将n = 4更进一步改变问题的大小,您会看到结果。我的笔记本中很久没有出现解决方案。

现在的问题很简单,这里有人认为有一种方法数字在Mathematica高效解决这个问题的高维情况?让我们分享我们的想法和经验。但是应该记住,它是一个基准非线性全局优化问题。大多数数值根发现/最小化算法通常搜索局部最小值。

BR

P

回答

4

增加初始点可以让我获得全球最低:

n = 5; 

funList[x_?ListQ] := Total[10 + (x - 2)^2 - 10 Cos[2 Pi (x - 2)]] 

val = Table[RandomReal[{-5, 5}], {i, 1, n}]; 
vars = Array[Symbol["x$" <> ToString[#]] &, n]; 
cons = Apply[And, Thread[-5 <= vars <= 5]]; 

这些都是调用。虽然时间可能不太有效,但随机算法必须有足够的初始样本,或者对函数有良好的感觉。

In[27]:= NMinimize[{funList[vars], cons}, vars, 
    Method -> {"DifferentialEvolution", 
    "SearchPoints" -> 5^5}] // AbsoluteTiming 

Out[27]= {177.7857768, {0., {x$1 -> 2., x$2 -> 2., x$3 -> 2., 
    x$4 -> 2., x$5 -> 2.}}} 

In[29]:= NMinimize[{funList[vars], cons}, vars, 
    Method -> {"RandomSearch", "SearchPoints" -> 7^5}] // AbsoluteTiming 

Out[29]= {609.3419281, {0., {x$1 -> 2., x$2 -> 2., x$3 -> 2., 
    x$4 -> 2., x$5 -> 2.}}} 
+0

手动命名像'x $ 1','x $ 2'等变量不是不安全,因为'Module'也通过类似的重命名进行本地化吗?这样做是否会导致可变的冲突? – Szabolcs

+0

@Szabolcs我不会推荐在程序中使用它,但在交互式会话中是安全的。我的小实验表明'Module'知道躲避碰撞。 'Set @@ {Symbol [“x”<> ToString [$ ModuleNumber]],17};打印[{$ ModuleNumber,Symbol [“x”<> ToString [$ ModuleNumber]]}];模块[{x},x]' – Sasha

2

你见过的文件this page?它回顾了NMinimize支持的方法,并给出了每个方法的示例。其中一个SimulatedAnnealing示例是Rastgrin的函数(或者一个非常相似),并且文档建议您需要增加扰动大小以获得良好结果。