sim_anneal(Tinit, Tend, MaxIter, VarArr, Profit, Opt) :-
starting_solution(VarArr), % starting solution
( fromto(Tinit, T, Tnext, Tend),
fromto(0, Opt1, Opt4, Opt),
param(MaxIter,Profit,VarArr,Tend)
do
printf("Temperature is %d%n", [T]),
( fromto(MaxIter, J0, J1, 0),
fromto(Opt1, Opt2, Opt3, Opt4),
param(VarArr,Profit,T)
do
Profit tent_get PrevProfit,
( flip_random(VarArr), % try a move
Profit tent_get CurrentProfit,
exp((CurrentProfit-PrevProfit)/T) > frandom,
conflict_constraints(cap,[]) % is it a solution?
->
( CurrentProfit > Opt2 -> % is it new optimum?
printf("Found solution with profit %w%n",
[CurrentProfit]),
Opt3=CurrentProfit, % accept and remember
J1=J0
; CurrentProfit > PrevProfit ->
Opt3=Opt2, J1=J0 % accept
;
Opt3=Opt2, J1 is J0-1 % accept
)
;
Opt3=Opt2, J1 is J0-1 % reject
)
),
Tnext is max(fix(0.8*T),Tend)
).
flip_random(VarArr) :-
functor(VarArr, _, N),
X is VarArr[random mod N + 1],
X tent_get Old,
New is 1-Old,
X tent_set New.