Skip to content

Commit 1bd8bb1

Browse files
committed
Modfications
2 parents 2e33688 + dcce89b commit 1bd8bb1

File tree

10 files changed

+385
-183
lines changed

10 files changed

+385
-183
lines changed

algorithms/Fourmis.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import random as rd
22
import numpy as np
33

4+
45
class Fourmis:
5-
def __init__(self, engine, fromLocation, locationList, pheromonesTime = 100, antNumber = 1000, pheromonesMax = 1, pheromonesMin = 0.01):
6+
def __init__(self, engine, fromLocation, locationList, pheromonesTime=100, antNumber=1000, pheromonesMax=1,
7+
pheromonesMin=0.01):
68
"""Prend la liste des cases a visiter"""
79
self.engine = engine
810
self.distances = engine.maze.distanceMetagraph
@@ -11,26 +13,27 @@ def __init__(self, engine, fromLocation, locationList, pheromonesTime = 100, ant
1113
self.locationNumber = len(self.locationList)
1214
self.fromLocation = fromLocation
1315
self.antNumber = antNumber
14-
self.pheromonesDico = {fLocation : {tLocation : [1./pheromonesTime]*pheromonesTime for tLocation in [self.fromLocation]+self.locationList} for fLocation in [self.fromLocation]+self.locationList}
16+
self.pheromonesDico = {fLocation: {tLocation: [1. / pheromonesTime] * pheromonesTime for tLocation in
17+
[self.fromLocation] + self.locationList} for fLocation in
18+
[self.fromLocation] + self.locationList}
1519
self.pheromonesMax = pheromonesMax
1620
self.pheromonesMin = pheromonesMin
1721

1822
def process(self):
1923
for i in range(self.antNumber):
20-
locationList = self.locationList.copy() #On copie la liste pour pouvoir la modifier
24+
locationList = self.locationList.copy() # On copie la liste pour pouvoir la modifier
2125
distanceSum = 1
2226
n = len(locationList)
2327
currentLocation = self.fromLocation
2428
while n > 0:
2529
(case, pheromones) = self.weightedChoice(locationList, currentLocation)
26-
n-=1
27-
self.pheromonesDico[currentLocation][case][-1] += max(np.sqrt(1./distanceSum), self.pheromonesMin)
30+
n -= 1
31+
self.pheromonesDico[currentLocation][case][-1] += max(np.sqrt(1. / distanceSum), self.pheromonesMin)
2832
distanceSum += self.distances[currentLocation][case]
29-
#On passe à la case suivante
33+
# On passe à la case suivante
3034
currentLocation = case
3135
self.decalerPheromones()
3236
return self.retournerCheminOpt()
33-
3437

3538
def weightedChoice(self, list, currentLocation):
3639
"""Fait un tirage au sort sans remise en affectant les poids, retourne l'élément choisi et son poids"""
@@ -42,21 +45,21 @@ def weightedChoice(self, list, currentLocation):
4245
currentPhero = 0
4346
for elt in list:
4447
eltPhero = self.getPheromonesPath(currentLocation, elt)
45-
if rand < (currentPhero+eltPhero)/nbPhero:
48+
if rand < (currentPhero + eltPhero) / nbPhero:
4649
list.remove(elt)
47-
return(elt, eltPhero)
48-
currentPhero += eltPhero
50+
return (elt, eltPhero)
51+
currentPhero += eltPhero
4952

5053
def getPheromonesPath(self, fromLocation, toLocation):
5154
res = 0
5255
for pheromones in self.pheromonesDico[fromLocation][toLocation]:
53-
res+=pheromones
56+
res += pheromones
5457
return res
5558

5659
def decalerPheromones(self):
5760
"""Retire un cycle de vie aux phéromones"""
58-
for fromLocation in self.locationList :
59-
for toLocation in self.locationList :
61+
for fromLocation in self.locationList:
62+
for toLocation in self.locationList:
6063
n = self.pheromonesDico[fromLocation][toLocation]
6164
self.pheromonesDico[fromLocation][toLocation].pop(0)
6265
self.pheromonesDico[fromLocation][toLocation].append(self.pheromonesMin)
@@ -68,18 +71,17 @@ def retournerCheminOpt(self):
6871
maxPheromones = np.inf
6972
maxPheromonesToPathIndex = None
7073
for j in range(len(toVisitList)):
71-
currentPheromones = self.getPheromonesPath(orderedVisitList[i],toVisitList[j])
72-
if currentPheromones < maxPheromones :
74+
currentPheromones = self.getPheromonesPath(orderedVisitList[i], toVisitList[j])
75+
if currentPheromones < maxPheromones:
7376
maxPheromones = currentPheromones
7477
maxPheromonesToPathIndex = j
7578
orderedVisitList.append(toVisitList[maxPheromonesToPathIndex])
7679
toVisitList.pop(maxPheromonesToPathIndex)
77-
orderedVisitList.pop(0) #On retire le fromLocation du début
80+
orderedVisitList.pop(0) # On retire le fromLocation du début
7881
return orderedVisitList
7982

80-
8183
def partiePositive(self, x):
8284
if x <= 0:
8385
return 0
8486
else:
85-
return x
87+
return x

algorithms/Kmeans.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
import random
5+
import numpy as np
6+
from algorithms.Astar import *
7+
8+
class K_Means:
9+
def __init__(self, maze, k = 4, nodes = None):
10+
self.maze = maze
11+
self.S = {}
12+
self.m = {}
13+
14+
self.k = k
15+
self.nodes = nodes
16+
self.astar = Astar(maze)
17+
18+
self.distanceGraph = {}
19+
20+
if nodes:
21+
self.setNodes(nodes)
22+
23+
def setK(self, k):
24+
self.k = k
25+
26+
def setNodes(self, nodes):
27+
self.nodes = nodes
28+
self.NB_NODES = len(nodes)
29+
30+
def getDistance(self, i, j):
31+
p = random.randint(0,100)
32+
if p < 0: # 80% de chance de faire Astar
33+
x1, y1 = round(i[0]), round(i[1])
34+
x2, y2 = round(j[0]), round(j[1])
35+
36+
self.astar.setOrigin((x1, y1))
37+
self.astar.setGoal((x2, y2))
38+
self.astar.process()
39+
d = self.astar.getResult()[0]
40+
return d
41+
else:
42+
x1, y1 = i
43+
x2, y2 = j
44+
return (x1 - x2) ** 2 + (y1 - y2) ** 2
45+
46+
def sommeTuplesInList(self, L):
47+
x, y = 0, 0
48+
for n in L:
49+
x += n[0]
50+
y += n[1]
51+
52+
return (x, y)
53+
54+
def process(self, iteration = 100):
55+
if self.NB_NODES > self.k:
56+
#random.shuffle(self.nodes)
57+
t = 0
58+
59+
# Initialise M
60+
self.m[t] = {}
61+
for i in range(self.k):
62+
self.m[t][i] = self.nodes[i]
63+
64+
while t < iteration:
65+
self.S[t] = {}
66+
self.m[t + 1] = {}
67+
for i in range(self.k):
68+
self.S[t][i] = []
69+
70+
for n in self.nodes:
71+
d = self.getDistance(n, self.m[t][i])
72+
c = True
73+
74+
for j in range(self.k):
75+
if d > self.getDistance(n, self.m[t][j]):
76+
c = False
77+
78+
if c:
79+
self.S[t][i].append(n)
80+
81+
x, y = self.sommeTuplesInList(self.S[t][i])
82+
83+
self.m[t + 1][i] = (x / len(self.S[t][i]), y / len(self.S[t][i]))
84+
85+
t += 1
86+
87+
return (self.m[t - 1], self.S[t - 1])

algorithms/TwoOPT.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ def __init__(self, maze, origin = None, goals = None):
1111
self.NB_OF_NODES = len(goals) + 1 if goals else 0
1212
self.path = []
1313

14-
self.improve = True
14+
self.improveAlg = False
15+
1516
def setOrigin(self, origin):
1617
self.origin = origin
1718

@@ -36,7 +37,7 @@ def process(self):
3637
self.algorithm()
3738

3839
def setImprove(self, val):
39-
self.improve = val
40+
self.improveAlg = val
4041

4142
def algorithm(self):
4243
"""
@@ -48,17 +49,14 @@ def algorithm(self):
4849
improve = False
4950

5051
# Personnal improve
51-
if self.NB_OF_NODES > 1 and self.improve:
52+
if self.NB_OF_NODES > 1 and self.improveAlg:
5253
for i in range(self.NB_OF_NODES - 1):
5354
if self.getDistance(i, -1) < self.getDistance(i, i+1):
54-
#print(list(range(1, self.NB_OF_NODES - i)))
5555
self.path = self.path[:(i+1)] + (self.path[(i+1)::])[::-1]
56-
#print("personnal improve")
57-
#print("Current path " + repr(self.getResult()))
5856
improve = True
5957

60-
for i in range(self.NB_OF_NODES - 1): #range(self.NB_OF_NODES) optimize the loop, range(1, self.NB_OF_NODES - 1) optimize a way, but keep the last point at is place
61-
for j in range(self.NB_OF_NODES - 1):
58+
for i in range(self.NB_OF_NODES): #range(self.NB_OF_NODES) optimize the loop, range(1, self.NB_OF_NODES - 1) optimize a way, but keep the last point at is place
59+
for j in range(self.NB_OF_NODES):
6260
if j in [i - 1 % self.NB_OF_NODES, i, i + 1 % self.NB_OF_NODES]:
6361
continue
6462

@@ -92,6 +90,8 @@ def exchange(self, i, j): # bug quand ça reboucle !!!
9290
:param j: arrete partant de j
9391
"""
9492
#print(str(int(round(abs(i - j)/2))) + repr((i, j)))
93+
if i > j:
94+
i, j = j, i
9595
for k in range(int(round(abs(i - j)/2))):
9696
#print(((i + k + 1) % self.NB_OF_NODES, j - k))
9797
self.path[(i + k + 1) % self.NB_OF_NODES], self.path[j - k] = self.path[j - k], self.path[(i + 1 + k) % self.NB_OF_NODES]

debug/Debug.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def __init__(self, engine):
1212
self.engine = engine
1313
self.maze = engine.maze
1414

15-
self.PATH_COLOR = ['red', 'grey', 'green', 'blue']
15+
self.PATH_COLOR = ['red', 'grey', 'green', 'blue', 'orange', 'yellow', 'pink', 'cyan4', 'cyan3', 'azure4', 'orchid']
1616
self.CURRENT_PATH_COLOR = 0
1717

1818
def showPath(self, *args):
@@ -25,20 +25,27 @@ def showPath(self, *args):
2525

2626
mg.show()
2727

28-
def showMetaPath(self, path):
29-
origin = path[0]
30-
paths = self.maze.convertMetaPathToRealPaths(path)
31-
32-
mg = self.getMG()
33-
34-
size = 10
35-
current = origin
36-
for path in paths:
37-
current = mg.showPath(current, path, size=size, color='red')
38-
size += 1
39-
40-
mg.show()
41-
28+
def showMetaPath(self, paths = []):
29+
if len(paths) > 0:
30+
origin = paths[0]
31+
32+
paths = self.maze.convertMetaPathToRealPaths(paths)
33+
mg = self.getMG()
34+
35+
size = 10
36+
current = origin
37+
k = 0
38+
for path in paths:
39+
current2 = mg.showPath(current, path, size=size, color=self.PATH_COLOR[self.CURRENT_PATH_COLOR])
40+
if k%5 == 0 and k >= 4:
41+
self.CURRENT_PATH_COLOR = (self.CURRENT_PATH_COLOR + 1) % len(self.PATH_COLOR)
42+
print("## Path " + repr(k) + " from " + repr(current) + " to " + repr(current2) + " : " + repr(path))
43+
k += 1
44+
current = current2
45+
mg.show()
46+
else:
47+
mg = self.getMG()
48+
mg.show()
4249
def getMG(self):
4350
mg = MazeGenerator(self.maze.mazeMap, self.maze.mazeWidth, self.maze.mazeHeight)
4451
mg.showNodes(self.engine.INITIAL_CHEESES)

debug/MazeGenerator.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33

44
import numpy as np
55
from tkinter import *
6+
import tkinter.font as tkFont
67

7-
class MazeGenerator:
8+
class MazeGenerator():
89
def __init__(self, mazeMap, mazeWidth, mazeHeight):
910
self.window = Tk()
11+
self.window.title("Maze viewer")
1012

1113
# Save Maze
1214
self.mazeMap = mazeMap
@@ -19,18 +21,27 @@ def __init__(self, mazeMap, mazeWidth, mazeHeight):
1921
self.NODE_SIZE = 8
2022
self.MARGE = 40
2123

22-
self.WINDOW_WIDTH = (self.window.winfo_screenwidth() / 2) * (1 - 5/100)
24+
self.WINDOW_WIDTH = int((self.window.winfo_screenwidth() / 2) * (1 - 5/100))
2325
self.WINDOW_HEIGHT = self.WINDOW_WIDTH
2426

2527
# Add Canvas
2628
self.canvas = Canvas(self.window, width=self.WINDOW_WIDTH, height=self.WINDOW_HEIGHT, background='white')
27-
self.canvas.pack()
29+
self.canvas.pack(side = LEFT, padx = 5, pady = 5)
30+
31+
pathTracerHeight = int(self.WINDOW_HEIGHT/25)
32+
self.pathTracer = Text(self.window, width=50, height=pathTracerHeight)
33+
self.pathTracer.pack(side=RIGHT, pady=5)
2834

2935
# Generation
3036
self.generate()
37+
3138
def generate(self):
39+
font = tkFont.Font(family='Helvetica', size=6)
40+
3241
for n in self.nodes:
3342
self.generateNode(n)
43+
x,y = self.convertToCord(n)
44+
self.canvas.create_text(x - 20, y - 15, text=repr(n), font=font)
3445

3546
for i in self.nodes:
3647
for j in self.nodes:
@@ -58,9 +69,9 @@ def generateEdge(self, i, j, size = 1, color = 'black'):
5869
x2, y2 = self.convertToCord(j)
5970
self.canvas.create_line(x1, y1, x2, y2, width=size, fill=color)
6071

61-
def showNodes(self, nodes):
72+
def showNodes(self, nodes, color = "blue", size = 11):
6273
for n in nodes:
63-
self.generateNode(n, self.NODE_SIZE + 3, 'blue')
74+
self.generateNode(n, size, color)
6475

6576
def getPath(self, origin, pathNodes):
6677
L = [origin]
@@ -81,6 +92,7 @@ def getPath(self, origin, pathNodes):
8192

8293
def convertToCord(self, pos):
8394
x, y = pos
95+
8496
w, h = self.WINDOW_WIDTH, self.WINDOW_HEIGHT
8597

8698
gap_h = (h - 2 * self.MARGE) / (self.mazeHeight - 1)
@@ -100,11 +112,9 @@ def showPath(self, *args, **kwargs):
100112
:return: La destination du chemin
101113
"""
102114

103-
104115
color = kwargs['color'] if 'color' in kwargs else 'red'
105116
size = kwargs['size'] if 'size' in kwargs else 10
106117

107-
print("Args : " + repr(args) + " | len : " + str(len(args)))
108118
if len(args) == 2:
109119
P = self.getPath(args[0], args[1])
110120
elif len(args) == 1:
@@ -113,6 +123,7 @@ def showPath(self, *args, **kwargs):
113123
for k in range(len(P) - 1):
114124
self.generateEdge(P[k], P[k + 1], size, color)
115125

126+
self.pathTracer.insert(END, "From " + repr(P[0]) + " to " + repr(P[-1]) + " (" + color + ")"'\n')
116127
return P[-1] # Return the last point
117128

118129
def show(self):

0 commit comments

Comments
 (0)