-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathga.py
89 lines (78 loc) · 2.87 KB
/
ga.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
84
85
86
87
88
89
# ga.py
from random import randint
class Gene:
def __init__(self, trafficInfo, randomGenerate=True, geneStr=""):
self.geneStr = ""
self.geneLen = 0
self.trafficInfo = trafficInfo
self.matched = {}
self.roadToLight = {}
self.roadInfo = {}
self.lightInfo = {}
if randomGenerate:
self.buildUpGene()
else:
self.buildFromStr(geneStr)
def buildUpGene(self):
for trafficLight, intersections in self.trafficInfo:
self.geneLen += len(intersections)
lightlist = []
for _ in range(len(intersections)):
duration = randint(2, 20)
lightlist.append(duration)
self.geneStr += "{0:02d}".format(duration)
self.lightInfo[trafficLight] = lightlist
self.roadInfo[trafficLight] = intersections
for road in intersections:
self.roadToLight[road] = trafficLight
def buildFromStr(self, geneStr):
index = 0
self.geneStr = geneStr
for trafficLight, intersections in self.trafficInfo:
self.geneLen += len(intersections)
lightlist = []
for i in range(len(intersections)):
duration = int(geneStr[i*2 : i*2 + 2])
lightlist.append(duration)
index += 1
self.lightInfo[trafficLight] = lightlist
self.roadInfo[trafficLight] = intersections
for road in intersections:
self.roadToLight[road] = trafficLight
class GeneInfo:
def __init__(self, gene):
self.gene = gene
def isGreen(self, road, tick):
intersection = self.gene.roadToLight[road]
roadlist = self.gene.roadInfo[intersection]
lightlist = self.gene.lightInfo[intersection]
cycle = sum(lightlist)
tick = tick % cycle
for i in range(len(roadlist)):
if tick > lightlist[i]:
tick -= lightlist[i]
elif road == roadlist[i]:
return True
else:
return False
return False
class GeneEvolve:
@classmethod
def evolve(cls, g1, g2, mutateRate=0.2):
newGen = cls.merge(g1, g2)
geneStr = cls.mutate(newGen, mutateRate)
return Gene(g1.trafficInfo, False, geneStr)
@classmethod
def merge(cls, g1, g2):
newGen = ""
genLen = len(g1.geneStr)
geneStr = [g1.geneStr, g2.geneStr]
for i in range( len(g1.geneStr)/2 ):
newGen += geneStr[randint(0,1)][i*2 : i*2 + 2]
return newGen
@classmethod
def mutate(cls, geneStr, mutateRate):
for i in range(randint(0, int(len(geneStr)/2 * mutateRate) )):
pos = randint(0, len(geneStr)/2 - 1)
geneStr = geneStr[: pos*2] + "{0:02d}".format(randint(2,20)) + geneStr[pos*2+2 :]
return geneStr