first genetic algo bot

This commit is contained in:
Barak Michener 2017-12-29 17:05:18 -08:00
parent 7c429fb0eb
commit 5256ff7091
5 changed files with 129 additions and 3 deletions

View file

@ -8,6 +8,7 @@ name = "pypi"
[packages] [packages]
matplotlib = "*" matplotlib = "*"
numpy = "*"
[dev-packages] [dev-packages]

2
Pipfile.lock generated
View file

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "aed9c28be63899aa45429206673c5a773fc0eca0acea8ec8909e1f1fcd6b4e7c" "sha256": "1a39e45c62576713be6123d9287975b50115164b6bad65cf1b5c879588893f83"
}, },
"host-environment-markers": { "host-environment-markers": {
"implementation_name": "cpython", "implementation_name": "cpython",

88
genetic.py Normal file
View file

@ -0,0 +1,88 @@
import supply
import random
import matrixbot
import numpy as np
from operator import itemgetter
SOLD_BENEFIT = 2
def run_generation(pop, i):
print("Generation %d" % i)
ranking = []
for x in pop:
score = evaluate(x)
ranking.append((score, x))
ranking.sort(key=itemgetter(0))
print("Best of generation: ", ranking[0])
newpop = [x[1] for x in ranking[:len(ranking)//2]]
newpop = breed(newpop, len(pop), i)
return newpop
def evaluate(mem):
g = supply.variableRequestGenerator(supply.TURNS, 8, 14)
#chain = [StupidAI(12), PlayerChain("Manufacturer", 12), Base()]
chain = [matrixbot.MatrixBot(mem[:25], mem[25:], 12), supply.Base()]
total_sold = 0
history = []
for topreq in g:
requests = [x.request() for x in chain]
requests = requests[:-1]
requests.insert(0, topreq)
got = 0
for i, c in reversed(list(enumerate(chain))):
got = c.reconcile(requests[i], got)
#print("Sold ", got, " units.")
total_sold += got
history.append([x.cost() for x in chain])
total_cost = [sum([x[0] * supply.SUPPLY_COST + x[1] * supply.BACKLOG_COST for x in y]) for y in history]
cost = supply.integrate(total_cost)[-1] - (total_sold * SOLD_BENEFIT)
return cost
def mate(a, b):
out = []
for x in range(len(a)):
if random.random() < 0.5:
out.append(a[x])
else:
out.append(b[x])
return np.array(out)
def mutate(a):
for i in range(5):
x = random.randint(0, len(a) - 1)
amt = random.uniform(-0.5, 0.5)
a[x] = a[x] + amt
WEIGHT = 0.9
LATE_WEIGHT = 0.2
GENS = 500
def breed(pop, n, i):
global WEIGHT
mut_chance = (WEIGHT - LATE_WEIGHT) * (GENS - i / GENS) + LATE_WEIGHT
total = n - len(pop)
newbies = []
while total != 0:
a = random.choice(pop)
b = random.choice(pop)
c = mate(a, b)
if random.random() < mut_chance:
mutate(c)
newbies.append(c)
total -= 1
c = pop[:]
c.extend(newbies)
return c
def main():
starting_pop = []
for i in range(300):
x = np.random.uniform(low=-2, high=2, size=30)
starting_pop.append(x)
pop = starting_pop
for gen in range(GENS):
pop = run_generation(pop, gen+1)
if __name__ == "__main__":
main()

22
matrixbot.py Normal file
View file

@ -0,0 +1,22 @@
import supply
import numpy as np
class MatrixBot(supply.Chain):
def __init__(self, hidden1, hidden2, initial):
a = np.matrix(hidden1).reshape(5,5)
b = np.matrix(hidden2).reshape(1,5)
self.mat = np.matmul(b, a)
super().__init__(initial)
def request(self):
x = [self.backlog, self.last_got, self.last_req, self.last_ship, self.supply]
out = np.matmul(self.mat, np.matrix(x).transpose())
n = out.tolist()[0][0]
if n < 0:
return 0
if n > 200:
return 200
return int(n)
if __name__ == "__main__":
m = MatrixBot(np.random.uniform(low=-3, high=3, size=25), np.random.uniform(low=-3, high=3, size=5), 12)
print(m.request())

View file

@ -1,6 +1,7 @@
import math import math
import random import random
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import matrixbot
BACKLOG_COST = 25 BACKLOG_COST = 25
SUPPLY_COST = 5 SUPPLY_COST = 5
@ -100,8 +101,22 @@ def main():
global SUPPLY_COST global SUPPLY_COST
global BACKLOG_COST global BACKLOG_COST
g = variableRequestGenerator(TURNS, 8, 14) g = variableRequestGenerator(TURNS, 8, 14)
#chain = [StupidAI(12), PlayerChain("Manufacturer", 12), Base()] #chain = [PlayerChain("Manufacturer", 12), Base()]
chain = [PlayerChain("me", 12), LessStupidAI(12), LessStupidAI(12), LessStupidAI(12), Base()] #chain = [PlayerChain("me", 12), LessStupidAI(12), LessStupidAI(12), LessStupidAI(12), Base()]
mb1 = matrixbot.MatrixBot([ 0.29963248, 0.08142691, -0.86641011, 0.23675042, 0.7086182 ,
-0.06441882, 0.03062067, -1.18299915, 0.68115478, 0.16068485,
-1.7178326 , -0.29003603, -0.83202861, 1.73222139, -1.98878473,
-0.96036021, 0.65793096, 1.50552035, -1.18544224, 0.03207729,
0.78074126, -0.91446605, 2.92469872, 0.48680479, -0.34067442],
[-0.07150818, -0.10019835, -0.02610447, -0.02049193, 0.42415006], 12)
mb2 = matrixbot.MatrixBot([ 0.29963248, 0.08142691, -0.86641011, 0.23675042, 0.7086182 ,
-0.06441882, 0.03062067, -1.18299915, 0.68115478, 0.16068485,
-1.7178326 , -0.29003603, -0.83202861, 1.73222139, -1.98878473,
-0.96036021, 0.65793096, 1.50552035, -1.18544224, 0.03207729,
0.78074126, -0.91446605, 2.92469872, 0.48680479, -0.34067442],
[-0.07150818, -0.10019835, -0.02610447, -0.02049193, 0.42415006], 12)
chain = [mb1, PlayerChain("me", 12), mb2, Base()]
import pdb; pdb.set_trace()
turn = 0 turn = 0
total_sold = 0 total_sold = 0
history = [] history = []