-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptimize.py
83 lines (74 loc) · 2.71 KB
/
optimize.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
79
80
81
82
83
"""Generate Solomons Benchmark solutions for the
Vehicles Benchmark Problem with Time Windows
using https://github.com/dietmarwo/fast-cma-es.
See http://web.cba.neu.edu/~msolomon/problems.htm
"""
import numpy as np
import os
from numba import njit
from fcmaes.optimizer import crfmnes_bite, wrapper
from fcmaes import retry
from scipy.optimize import Bounds
from benchmark import Benchmark
@njit(fastmath=True)
def fitness_(seq, capacity, dtime, demands, readys, dues, services):
n = len(seq)
seq += 1
sum_demand = 0
sum_dtime = 0
time = 0
last = 0
vehicles = 1
for i in range(0, n+1):
customer = seq[i] if i < n else 0
demand = demands[customer]
ready = readys[customer]
due = dues[customer]
service = services[customer]
if sum_demand + demand > capacity or \
time + dtime[last, customer] > due:
# end vehicle tour, return to base
dt = dtime[last, 0]
sum_dtime += dt
time = 0
sum_demand = 0
vehicles += 1
last = 0
# go to customer
dt = dtime[last, customer]
time += dt
if time < ready:
time = ready
time += service
sum_demand += demand
sum_dtime += dt
last = customer
return np.array([float(vehicles), sum_dtime])
class Optimizer():
def __init__(self, problem):
self.problem = problem
self.benchmark = Benchmark(problem)
self.dim = len(self.benchmark.demand) - 1
self.bounds = Bounds([0]*self.dim, [1]*self.dim)
def fitness(self, x):
fit = fitness_(np.argsort(x), self.benchmark.capacity, \
self.benchmark.dtime, self.benchmark.demand, \
self.benchmark.ready, self.benchmark.due, self.benchmark.service)
# increasing the vehicle weight doesn't help much with the hierarchical objective
return 10*fit[0] + fit[1]
def optimize_so(problem, opt, num_retries = 64):
optimizer = Optimizer(problem)
ret = retry.minimize(wrapper(optimizer.fitness),
optimizer.bounds, num_retries = num_retries, optimizer=opt)
optimizer.benchmark.dump_opt(np.argsort(ret.x), ret.fun, problem, 'cont')
def opt_dir(dir):
files = os.listdir(dir)
files.sort()
for file in files:
problem = file.split('.')[0]
# used to generate the results
#optimize_so(problem, crfmnes_bite(10000000, popsize=500, M=6), num_retries = 64)
# sufficient for the clustered problem instances
optimize_so(problem, crfmnes_bite(1000000, popsize=500, M=6), num_retries = 64)
if __name__ == '__main__':
opt_dir('problems')