-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLateAcceptedHillClimbing.py
78 lines (65 loc) · 2.6 KB
/
LateAcceptedHillClimbing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 21 20:27:07 2020
@author: prakh
"""
# LIBRARY IMPORT
import numpy as np
"""Late-acceptance hill-climbing (LAHC) is a stochastic hill-climbing
algorithm with a history mechanism, proposed by Bykov
[http://www.cs.nott.ac.uk/~yxb/LAHC/LAHC-TR.pdf].
The history mechanism is very simple but in some domains it seems to
provide a remarkable performance improvement compared to hill-climbing
itself and other heuristics. The big advantage is its simplicity:
fewer parameters to tune compared to many alternative methods.
In standard stochastic hill-climbing, we accept a move to a new
proposed point (created by mutation) if that point is as good as or
better than the current point.
In LAHC, we accept the move if the new point is as good as or better
than that we encountered L steps ago. L is the only new parameter
compared to hill-climbing: it stands for history length.
"""
"""
This is the LAHC pseudo-code from Bykov and Burke.
Produce an initial solution s
Calculate initial cost function C(s)
Specify Lfa
For all k in {0...Lfa-1} f_k := C(s)
First iteration I=0;
Do until a chosen stopping condition
Construct a candidate solution s*
Calculate its cost function C(s*)
v := I mod Lfa
If C(s*)<=fv or C(s*)<=C(s)
Then accept the candidate (s:=s*)
Else reject the candidate (s:=s)
Insert the current cost into the fitness array fv:=C(s)
Increment the iteration number I:=I+1
"""
# L is history length
# n is the budget of evaluations
# C is the cost function
# init is a function that creates an initial individual
# nbr is a neighbourhood function
def LAHC(L, n, C, init, nbr):
s = init() # initial solution
Cs = C(s) # cost of current solution
best = s # best-ever solution
Cbest = Cs # cost of best-ever
f = [Cs] * L # initial history
history = [] # create history
# print(0, Cbest, best)
for I in range(1, n): # number of iterations
s_ = nbr(s) # candidate solution
Cs_ = C(s_) # cost of candidate
if Cs_ < Cbest: # minimising
best = s_ # update best-ever
Cbest = Cs_
history.append((I, Cbest)) # save history
# print(I, Cbest, best)
v = I % L # v indexes I circularly
if Cs_ <= f[v] or Cs_ <= Cs:
s = s_ # accept candidate
Cs = Cs_ # (otherwise reject)
f[v] = Cs # update circular history
return best, Cbest,np.array(history)