# Simulated Annealing Convergence

I am using Simulated Annealing method for a simulation based optimization of a process that has 3 variables, using NMinimize. I print the input/output during every iteration using the "Evaluation Monitor". I have noticed that after about 3000 iterations, Mathematica gives me a convergence result. But checking the results from "Evaluation Monitor" shows that the ultimate convergence result is not the global minimal, but the process has visited a better minimal during one of the iterations. Why is this happening?

Here is a sample code:

demand[n_,k_]:=Min[k Vf,n capacity];
supply[n_,k_]:=Min[(n Kj-k) w, n capacity];
flo[n_,Ku_,Kd_]:=Min[demand[n,Ku],supply[n,Kd]];
dx=Vf*dt; n=Round[Flen/dx]; m=Round[SimTime/dt];
p=Round[Rlen/dx];   θ=Vf/w; capacity=w*Vf*Kj/(Vf+w); α[a1_]:=1800.; β[a2_]:=0.1; L=3.;
Flen=8.; Rlen=3.; SimTime=30./60.; Kj=150.; w=20.; Vf=100.; dt=12./3600.; d=1.;
RMLocation=Round[(2/3) p]; j=0;

f[a1_,a2_,a3_]:=Module[{b1=a1,b2=a2,b3=a3,TT=0,NtwrkTT=0,j=0},
RM[x_,t_]:=Piecewise[{{100 b1,x<=3},{100 b2,3<x<=6},{100 b3,True}}];
NtwrkTT=0; Clear[k0,kr,k,γ];
k0=ConstantArray[0,n];
kr=Table[Table[0,{k,1,p}],{i,1,n}];
γ=ConstantArray[1,n];
For[i=2, i<n, i++, kr[[i,1]]=α[i dx] d/Vf];
TT=Plus@@(Plus@@kr); NtwrkTT=TT; k=k0;
While[TT>0, TT=0;
For[i=2, i<n, i++, FQin=If[i==2,Min[demand[L,k0[[i-1]]],supply[L,k0[[i]]]],FQout];
dem=demand[L,k0[[i]]]; dem=If[dem==0,0.001,dem];
γ[[i]]=Min[1,supply[L,k0[[i+1]]]/dem];
ϕ=γ[[i]] demand[1,kr[[i,p]]]/d;
Qr=(ϕ-β[i dx] FQin) dx;
FQout=Min[demand[L,k0[[i]]],supply[L,k0[[i+1]]]];
k[[i]]=k0[[i]]+(FQin-FQout+Qr)/Vf;
kr0=kr[[i]];
For[ir=2,ir<=p,ir++,
MR=If[ir==RMLocation+1,RM[i dx,j dt],capacity];
RQin=Min[MR,If[ir==2,flo[1,kr0[[ir-1]],kr0[[ir]]],RQout]];
MR=If[ir==RMLocation,RM[i dx,j dt],capacity];
RQout=Min[MR,If[ir<p,flo[1,kr0[[ir]],kr0[[ir+1]]],ϕ d]];
kr[[i,ir]]=kr0[[ir]]+(RQin-RQout)/Vf];
kr[[i,1]]=If[j<=m,α[i dx] d/Vf,0]];
TT=Plus@@(Plus@@kr);
TT+=Plus@@k;
k0=k;NtwrkTT+=TT;j++];
NtwrkTT dt]
NMinimize[{f[a,b,c],3<=a<=12&&3<=b<=12&&3<=c<=12&&Element[a|b|c,Integers]},{a,b,c},Method->{"SimulatedAnnealing","SearchPoints"->5^5},EvaluationMonitor:>Print["a = ",a," , b = ",b," , c = ",c," , f[a,b,c] = ",f[a,b,c]]]


Hope this helps.

Ps. Any suggestions to improve the performance of this code will be greatly appreciated. Thank You.

edit:

As per @@Kuba's suggestion, I split the original question in to two. The second part is at Simulated Annealing Parameters and Results

• I think this may be interesting topic even that there are multiple quesitons. However I think you should provide small working example for this questions while moving your optimization question with that huge code to the separate topic. This will help you get better answers IMO.
– Kuba
Feb 25, 2014 at 7:19
• Does any one have a response or a comment? Feb 25, 2014 at 22:47
• I don't know about the Mathematica implementation, but one of the features of simulated annealing is that answers do not always improve; rather, it follows a probabilistic method that allows climbing uphill as well as descending. So you should expect to see ups and downs in any given run of a simulated annealing process. Mar 3, 2014 at 20:51

I found the solution on another website "http://eternaldisturbanceincosmos.wordpress.com/2011/04/27/nminimize-in-mathematica-could-drive-you-insane/" which says "It turns out that NMinimize does not hold its arguments. This means that as the list of arguments is read from left to right, each argument is evaluated and replaced by the result of the evaluation". So I used Hold[] in the NMinimize function that fixed the problem.

Edit:

As suggested by Szabolcs, it worked with ?NumericQ alone and no Hold[]

• Unfortunately the information in that blog post is incorrect (as people note in the comments below it). The solution there would have been this. Mar 3, 2014 at 20:39
• You are right!! It works when I used ?NumericQ. However, it worked when I used Hold[] too. Can you please elaborate on why it worked with the latter? Mar 3, 2014 at 20:57
• I don't know. It's weird. I wouldn't expect it to work at all but this does indeed work: NMinimize[Hold[x^2], x]. For some reason NMinimize is stripping away the Hold. I wouldn't count on this working in every situation and every version. Mar 3, 2014 at 21:03
• @Szabolcs the link is broken
– shrx
Jul 17, 2014 at 19:57
• @shrx Lots and lots of links got broken in the last few days, including documentation links. This is bad. Here's Google Cache: webcache.googleusercontent.com/… I referred to this KB article tens of times on this site, I'm not going to go through all those and update them. Jul 17, 2014 at 19:58