-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmonogeneticalgorithm.py
More file actions
114 lines (101 loc) · 3.47 KB
/
Copy pathmonogeneticalgorithm.py
File metadata and controls
114 lines (101 loc) · 3.47 KB
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# -*- coding: utf-8 -*-
"""
Created on Sun Dec 31 02:49:12 2017
@author: Reuben
"""
# -*- coding: utf-8 -*-
"""
Created on Fri Dec 29 17:38:01 2017
@author: Reuben
"""
#Simulation of monomono machine
import random
from itertools import accumulate
from collections import Counter
repeat = 0
coins = 0
lessen = .0109
found = 1/92
C = []
coinAmt = []
turns = []
class player():
def __init__(self):
self.coins = 0
self.repeat = 1/92
self.turns = {}
for i in range(0, 93):
self.turns[i] = 0
self.level = {}
self.numFound = 0
self.lessen = .0109
for i in range(0, 93):
self.level[i] = random.randint(1, (i*2)+1)
def play(self):
while self.numFound < 92:
self.turns[self.numFound]+=1
self.coins += self.level[self.numFound]
chance = 1-(self.repeat*self.numFound-
lessen*
(self.level[self.numFound]-1))
if(random.random() < chance):
self.numFound+=1
if self.turns[self.numFound] > 10000:
break
def fitness():
return self.coins
class pool():
def __init__(self, n):
self.n = n
self.players = [player() for x in range(n)]
self.generationNum = 0
def evolve(self):
for p in self.players:
p.play()
def selection(self):
total = sum(p.coins for p in self.players)
total += 10*sum(sum(p.turns.values()) for p in self.players)
self.players.sort(key = lambda x: x.coins+10*(sum(x.turns.values())))
select = []
for i in self.players:
select.append((i.coins+sum(i.turns.values())*10)/total)
#select.sort(key = lambda x: x)
select = select[::-1]
select = list(accumulate(select))
print("Top 10 in Generation "+str(self.generationNum)+":")
for i in range(10):
print(str(self.players[-i-1].coins)+" coins used in "+str(sum(self.players[-i-1].turns.values())) +" turns")
select[-1] = 1
results = []
for i in range(self.n):
firstChoice = next(x[0] for x in enumerate(select) if x[1] >= random.random())
secondChoice= next(x[0] for x in enumerate(select) if x[1] >= random.random())
results.append((firstChoice, secondChoice))
self.breed(results)
def breed(self, results):
newPlayers = []
self.generationNum+=1
for i in range(self.n):
level1 = self.players[results[i][0]].level
level2 = self.players[results[i][1]].level
newLevel = {}
for k in level1:
newLevel[k] = self.mutate(level1[k], level2[k])
newPlayers.append(player())
newPlayers[-1].level = newLevel
self.players = newPlayers
def randSign(self):
if(random.random() < .5):
return -1
else:
return 1
def mutate(self, v1, v2):
avg = (v1+v2)/2
return max(1, int(avg + random.randint(0,max(1,int(avg/2)))*self.randSign()))
def reportBack(self):
results = [Counter(i.level) for i in self.players]
results = sum(results, Counter())
for k in results:
results[k] = results[k]/self.n
print("For level "+str(k)+", "+str(results[k])+" number of coins is recommended")
return results