When I previously did optimization with IPOPT, I only found one global minimum. It recently occurred to me that some problems have multiple global minima and these could be found by IPOPT, given enough random starting points. The code finds all the results with the lowest objective function value and then does a same test on the variable results to eliminate variable results which are close to each other.
The inputs to to iMin are the
objective (obj),
the constraints (cons),
the variables with bounds (vwb),
the startsIn, which is list of starting points or the number of random points and the random seed,
and the unionsametestval, which is used to remove nearly identical lists of variables in which the objective value is the global minimum.
objective (obj),
the constraints (cons),
the variables with bounds (vwb),
the startsIn, which is list of starting points or the number of random points and the random seed,
and the unionsametestval, which is used to remove nearly identical lists of variables in which the objective value is the global minimum.
Parametric IPOPT Minimize Code
Parametric IPOPT Minimize Code
In[]:=
Needs["IPOPTLink`"]
In[]:=
statusrl={0"Solve_Succeeded",1"Solved_To_Acceptable_Level",2"Infeasible_Problem_Detected",3"Search_Direction_Becomes_Too_Small",4"Diverging_Iterates",5"User_Requested_Stop",6"Feasible_Point_Found",-1"Maximum_Iterations_Exceeded",-2"Restoration_Failed",-3"Error_In_Step_Computation",-4"Maximum_CpuTime_Exceeded",-10"Not_Enough_Degrees_Of_Freedom",-11"Invalid_Problem_Definition",-12"Invalid_Option",-13"Invalid_Number_Detected",-100"Unrecoverable_Exception",-101"NonIpopt_Exception_Thrown",-102"Insufficient_Memory",-199"Internal_Error"};
In[]:=
iMin[obj_,cons_List,vwb_List,startsIn_List,unionsametestval_,opts___]:=Block{lecons,consviol,vars,lbubs,cfuns,clbubs,v,lb,ub,params,param,pip,starts,nrands,seed,pres,listres,status,goodres,finalres,resrl,minmin,minmins,minmins1,coords,ucoords},lecons=cons/. (a_==b_)->LessEqual[0,a-b,0], (a_<=b_)->LessEqual[-∞,a-b,0], (a_>=b_)->LessEqual[0,a-b,∞];consviol=cons/.{Equal[x_,y_]Abs[x-y],LessEqual[x_,y_]Max[x-y,0],GreaterEqual[x_,y_]Max[y-x,0],LessEqual[lb_,x_,ub_]Max[0,lb-x,x-ub]};{vars,lbubs}=Transpose[vwb/.{v_,lb_?NumericQ,ub_?NumericQ}{v,{lb,ub}}];If[Length[cons]0,{cfuns,clbubs}={{},{}},{cfuns,clbubs}=Transpose[lecons/.LessEqual[lb_,v_,ub_]{v,{lb,ub}}]];params=Table[param[i],{i,Length[vwb]}];pip=ParametricIPOPTMinimize[obj,vars,params,lbubs,cfuns,clbubs,params,"RuntimeOptions"{"WarningMessages"False},opts];If[MatrixQ[startsIn],starts=startsIn,{nrands,seed}=startsIn;SeedRandom[seed];starts=Transpose[BlockRandom[RandomReal[#,nrands]&/@lbubs]]];pres=pip@@@starts;listres={IPOPTMinValue[#],IPOPTArgMin[#],IPOPTReturnCode[#]}&/@pres;IPOPTDataDelete/@pres;status=listresAll,3;Print[Tally[status]/.{s_,n_Integer}{s/.statusrl,n}];goodres=Select[listres,Or[#〚3〛0,#〚3〛1]&];minmin=Min[goodres[[All,1]]];minmins=Selectgoodres,#[[1]]<=minmin+&;coords=minmins[[All,2]];ucoords=Union[coords,SameTest->(Norm[#1-#2]<=10^-1&)];Table[{minmin,Thread[vars->ucoords[[i]]]},{i,Length[ucoords]}]
-4
10
Circle PackingCode
Circle PackingCode
xyvars[nCircs_Integer]:=Flatten@Table[{x[i],y[i]},{i,nCircs}]xyvarswb[nCircs_Integer]:=Thread[{xyvars[nCircs],-1.5,1.5}]varswb[nCircs_Integer]:=Join[xyvarswb[nCircs],{{s,1,4}}]inCons[s_,radii_List]:=Flatten@Table[Thread[s>=2(radii[[i]]+{x[i],-x[i],y[i],-y[i]})],{i,Length[radii]}]nOvLapCons[radii_List]:=Flatten@Table+>=,{i,Length[radii]-1},{j,i+1,Length[radii]}allCons[s_,radii_List]:=Join[inCons[s,radii],nOvLapCons[radii]]plt[sln_,radii_List]:=ShowGraphics@Line{{-1,-1},{1,-1},{1,1},{-1,1},{-1,-1}}/.sln[[2]],Graphics@TableHue,Disk[{x[i],y[i]}/.sln[[2]],radii[[i]]],{i,Length[radii]},Frame->True,ImageSize->Small
2
(x[i]-x[j])
2
(y[i]-y[j])
2
(radii[[i]]+radii[[j]])
s
2
i-1
Length[radii]
Test with Function
Test with Function
In[]:=
iMin+++x*y*z,++>=,{{x,-1,1},{y,-1,1},{z,-1,1}},{100,0},//TableForm
4
x
4
y
4
z
2
x
2
y
2
z
1
4
-8
10
{{Solve_Succeeded,100}}
Out[]//TableForm=
-0.00322293 |
| |||
-0.00322293 |
| |||
-0.00322293 |
| |||
-0.00322293 |
|
Circle Packing Test
Circle Packing Test
Circle Packing requires a higher value for union same test, as some of the circles can move freely among the other circles.
2 Circles
2 Circles
In[]:=
n=2;radii=;
-1/2
Range[n]
In[]:=
AbsoluteTiming[sln[n]=iMin[s,allCons[s,radii],varswb[n],{10,0},0.1];]
{{Solve_Succeeded,10}}
Out[]=
{0.0721173,Null}
In[]:=
Table[plt[sln[n][[i]],radii],{i,Length@sln[n]}]
Out[]=
,
,
,
3 Circles
3 Circles
In[]:=
n=3;radii=;
-1/2
Range[n]
In[]:=
AbsoluteTiming[sln[n]=iMin[s,allCons[s,radii],varswb[n],{100,0},0.1];]
{{Solve_Succeeded,100}}
Out[]=
{0.725482,Null}
In[]:=
Table[plt[sln[n][[i]],radii],{i,Length@sln[n]}]
Out[]=
,
,
,
,
,
,
,
4 Circles
4 Circles
5 Circles
5 Circles
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
Finding all global minima with IPOPT (Interior Point OPTimizer)
by Frank Kampas
Wolfram Community, STAFF PICKS, August 31, 2026
https://community.wolfram.com/groups/-/m/t/3790113
by Frank Kampas
Wolfram Community, STAFF PICKS, August 31, 2026
https://community.wolfram.com/groups/-/m/t/3790113