Skip to content

Commit 67c9918

Browse files
committed
opt2 added as an option
1 parent 894d422 commit 67c9918

File tree

5 files changed

+34
-11
lines changed

5 files changed

+34
-11
lines changed

aco.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ACO:
1818

1919
name = 'ACO'
2020

21-
def __init__(self, graph, nAnts = 10 , doPlot = True, multiprocess = True, nProfile = 0):
21+
def __init__(self, graph, nAnts = 10 , opt2=False, doPlot = True, multiprocess = True, nProfile = 0):
2222
# reset seed to have 'true' random
2323
random.seed()
2424
np.random.seed()
@@ -46,7 +46,7 @@ def __init__(self, graph, nAnts = 10 , doPlot = True, multiprocess = True, nProf
4646
createPool = Pool if multiprocess else DummyPool
4747

4848
# create a pool of processes of workers
49-
args = (nNodes, log,
49+
args = (nNodes, log, opt2,
5050
SharedMatWorker(graph.sharedMatDist),
5151
SharedMatWorker(graph.sharedMatWeight),
5252
SharedMatWorker(sharedPaths))
@@ -129,7 +129,7 @@ def do_step(self, step):
129129

130130
def simulate(self, nStep=200, alpha=1.0,
131131
beta=3.0, rho=.1, tau=1.0, q=.6,
132-
nAvg=10, termination = True):
132+
nAvg=10, termination=True):
133133

134134
log (f'simulate {nStep} steps')
135135

graphMap.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class GraphMAP(Graph):
1414

1515
cachedir = 'cache'
1616

17-
def __init__(self, nNodes = 50, seed = 1000, address = 'Nimes, France',
17+
def __init__(self, nNodes = 50, seed = 1000, address = 'Montpellier, France',
1818
radius = 1500, ntype = 'drive', footprints = True, folium = False):
1919

2020
# imports only when the class is intancied

main.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
# [0] = GraphRND
3636
# [1] = GraphTSP
3737
# [2] = GraphMAP
38-
GraphCls = GraphClasses[1]
38+
GraphCls = GraphClasses[0]
3939
gclsname = GraphCls.__name__
4040

4141
if gclsname == 'GraphRND':
@@ -69,6 +69,7 @@
6969
acoCls = AcoClasses[2]
7070

7171
acokwargs = dict(nAnts = graph.nNodes,
72+
opt2 = False,
7273
doPlot = True,
7374
multiprocess = True,
7475
nProfile = 0)

mainhelper.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ def print_defaults(txt, func, override = None):
4545
key_val = get_defaults(func)
4646

4747
if override is not None:
48-
key_val = [(k, override.get(k, v)) for k, v in key_val]
48+
key_val = ((k, override.get(k, v)) for k, v in key_val)
4949

50+
key_val = list(key_val)
5051
width = max(len(k) for k, v in key_val)
5152
args = (f'{k}'.ljust(width) + f' = {v}' for k, v in key_val)
5253

@@ -58,7 +59,7 @@ def print_defaults(txt, func, override = None):
5859
def copy_paste_helper():
5960
log ('TO COPY PASTE !')
6061
tab ('# generated with mainhelper.py')
61-
tab ('from mainHelper import GraphClasses, TspOpts, AcoClasses')
62+
tab ('from mainhelper import GraphClasses, TspOpts, AcoClasses')
6263
print ()
6364
for i, gtype in enumerate(GraphClasses):
6465
tab (f'# [{i}] = {gtype.__name__}')

worker.py

+25-4
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ def update(self, mat):
4646
class Worker:
4747

4848
@staticmethod
49-
def init(nNodes, log, sharedMatDist, sharedMatWeight, sharedPaths):
49+
def init(nNodes, log, opt2, sharedMatDist, sharedMatWeight, sharedPaths):
5050
Worker.nNodes = nNodes
5151
Worker.log = log
52+
Worker.opt2 = opt2
5253

5354
# sharedMatDist, sharedMatWeight and sharedPaths are shared in memory by all processes
5455
Worker.MatDist = sharedMatDist.get() # read only
@@ -113,8 +114,28 @@ def ant_do_tour(ant, start, q):
113114
# back to the start
114115
path[-1] = start
115116

116-
# path length rounded with 2 digits, since equivalent paths (by rotation or inversion)
117-
# might have slightly different lengths due to the sum imprecision
118117
# rows = (array 'from nodes'), columns = (array 'to nodes') of the path
119118
rows, cols = path[:-1], path[1:]
120-
return round(Worker.MatDist[rows, cols].sum(), 2)
119+
length = Worker.MatDist[rows, cols].sum()
120+
121+
# 2-opt permutations to find a better path
122+
# optims for symmetric path
123+
if Worker.opt2:
124+
dist = Worker.MatDist
125+
126+
for i in range(1, nNodes):
127+
for j in range(i + 1, nNodes):
128+
129+
pi, pj, piprev, pjnext = path[i], path[j], path[i-1], path[j+1]
130+
gain = dist[pi][pjnext] + dist[piprev][pj] - dist[piprev][pi] - dist[pj][pjnext]
131+
132+
if gain < 0:
133+
# invert i,j and everything in between
134+
path[i:j+1] = path[j:i-1:-1]
135+
136+
# add the gain
137+
length += gain
138+
139+
# path length rounded with 2 digits, since equivalent paths (by rotation or inversion)
140+
# might have slightly different lengths due to the sum imprecision
141+
return round(length, 2)

0 commit comments

Comments
 (0)