:- lib(ic). :- lib(repair). knapsack(N, Profits, Weights, Capacity, Opt) :- length(Vars, N), Vars :: 0..1, Capacity #>= Weights*Vars r_conflict cap, Profit tent_is Profits*Vars, local_search(<extra parameters>, Vars, Profit, Opt). |
local_search: set starting state while global_condition while local_condition select a move if acceptable do the move if new optimum remember it endwhile set restart state endwhile |
random_walk(MaxIter, VarArr, Profit, Opt) :- init_tent_values(VarArr, random), % starting point ( for(_,1,MaxIter), % do MaxIter steps fromto(0, Best, NewBest, Opt), % track the optimum param(Profit,VarArr) do ( conflict_constraints(cap,[]) -> % it's a solution! Profit tent_get CurrentProfit, % what is its profit? ( CurrentProfit > Best % new optimum? -> printf("Found solution with profit %w%n", [CurrentProfit]), NewBest=CurrentProfit % yes, remember it ; NewBest=Best % no, ignore ), change_random(VarArr, 0, 1) % add another item ; NewBest=Best, change_random(VarArr, 1, 0) % remove an item ) ). |
T
, the inner loop does random moves until MaxIter
steps have been
done without improvement of the objective.
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. |
tabu_search(TabuSize, MaxIter, VarArr, Profit, Opt) :- starting_solution(VarArr), % starting solution tabu_init(TabuSize, none, Tabu0), ( fromto(MaxIter, I0, I1, 0), fromto(Tabu0, Tabu1, Tabu2, _), fromto(0, Opt1, Opt2, Opt), param(VarArr,Profit) do ( try_set_best(VarArr, MoveId), % try uphill move conflict_constraints(cap,[]), % is it a solution? tabu_add(MoveId, Tabu1, Tabu2) % is it allowed? -> Profit tent_get CurrentProfit, ( CurrentProfit > Opt1 -> % is it new optimum? printf("Found solution with profit %w%n", [CurrentProfit]), Opt2=CurrentProfit % accept and remember ; Opt2=Opt1 % accept ), I1 is I0-1 ; ( try_clear_worst(VarArr, MoveId), % try downhill move tabu_add(MoveId, Tabu1, Tabu2) % is it allowed? -> I1 is I0-1, Opt2=Opt1 % reject ; I1=0, % no moves possible, stop Opt2=Opt1 % reject ) ) ). |
Repair can be used to implement a wide variety of local search and hybrid search techniques.
Figure 13.5: Implementing Search