BEGIN { srand(); Nudge=0.01; #ranges 0 to 1. Decrease to reduce jump distance. Steps=5000; #temperature moves 1 to 0 in, say, 1000 steps ReportEvery=2; #how often to print our progress Sedative=4 } function accept(dE,t) { if (dE < 0) return 1; return (rand() < 2.718281828^(-1*dE/t)) } function metropolis(best, t,bestS,new,newS,current,currentS, runs,sum,sumSq,n) { t=1; bestS = currentS = 10^32 ; run(); copy(Memo,current); while(t > 0) { newS=nearBy(t,current,new); if (newS < bestS) { copy(new,best); bestS = newS; }; if (accept(newS - currentS,t)) { copy(new,current); currentS = newS; }; t = t - 1/Steps; } return bestS; } function nearBy(t,old,new, size,item,b4) { delete new; delete Memo; size=least(1,most(0,Nudge + t^Sedative)) for(item in old) { b4=old[item]; nudgep = 1; if ( nudgep ) new[item]=call(item,nudgep,b4,size); }; return score(new); } function score(new) { copy(new,Memo); return run() } function copy(old,new, i,j) { delete new; for(i in old) {j++; new[i]=old[i]}; return j } function report (s,t) { print int(t/ReportEvery+0.5)*ReportEvery " " s } function lastReport() {print "#EOF"};