Skip to content

Instantly share code, notes, and snippets.

@arjun-prakash
Last active March 10, 2018 00:43
Show Gist options
  • Save arjun-prakash/2a99f1e4137234932f3a08e5485e0c2a to your computer and use it in GitHub Desktop.
Save arjun-prakash/2a99f1e4137234932f3a08e5485e0c2a to your computer and use it in GitHub Desktop.
import random
from pyswarm import pso
import numpy as np
def RandoStrat1(soldiers,castles):
"""
generates random strategies without biases (according to paper)
the search space was too large for this to be viable
"""
res = soldiers
strat = []
for i in range(castles - 1):
rand = random.randint(0,res)
strat.append(rand)
res-=rand
strat.append(res)
random.shuffle(strat)
return strat
def RandoStrat2(soldiers,castles,trials) :
"""
generates random strategies
"""
strats = []
potential = []
while len(strats) < trials: #keep g o i n g u n t i l we pu t w s t r a t e g i e s in s t r a t s
for i in range(castles):
potential.append(random.randint(0,soldiers))
if sum(potential) == soldiers:
strats.append(potential)
potential = []
else:
potential = []
return strats
def BlottoGame(strat1,strat2,n) :
"""
the game is played
"""
p1score = p2score = 0
for i in range(n) :
if strat1[i] > strat2[i]:
p1score += (i+1)*(i+1)
elif strat1[i] < strat2[i] :
p2score += (i+1)*(i+1)
else:
p1score+= 0
p2score += 0
break
return p1score
def SortScores(n,stratset):
"""sets score, with tuple of score and index"""
scoretuples = []
for i in range(len(stratset)):
scoretuples.append((stratset[i],i))
scoretuples = sorted(scoretuples,reverse=True)
return scoretuples
def lp(x,**kwargs):
"""
linear prgram to be optimized
(minimizing the negative score = maximising score)
"""
strats = kwargs['strats']
castles = kwargs['castles']
total_score = 0
for s in strats:
total_score+=BlottoGame(x,s,castles)
return -total_score
def round_robin_B(strats, castles):
"""
Second round robbin, each strategy plays eachother
winner is declared
"""
scores = []
for strat1 in strats:
running_score = 0
for strat2 in strats:
running_score+=(BlottoGame(strat1,strat2,castles))
scores.append(running_score/len(strats))
sc = SortScores(castles,scores)
l = np.array(sc)
print("B mean:", np.mean(l[:,0]))
print('Winner Score Against B:',sc[0][0])
return strats[sc[0][1]]
def round_robin_A(soldiers,castles,trials):
"""
First Round robbin, each strategy playes each other
the top 3rd go to round B
"""
s1 = []
for i in range(trials):
s = RandoStrat1(soldiers,castles)
s1.append(s)
i+=1
scores = []
for strat1 in s1:
running_score = 0
for strat2 in s1:
running_score+=(BlottoGame(strat1,strat2,castles))
scores.append(running_score/len(s1))
sc = SortScores(castles,scores)
l = np.array(sc)
print("A mean:", np.mean(l[:,0]))
print('Winner Score Against A:',sc[0][0])
best = []
for i in range(trials//3):
best.append(s1[sc[i][1]])
winner = round_robin_B(best,castles)
print(winner)
def resources(x, **kwargs):
"""
resource constraints
"""
return(100 - sum(map(int, x)))
def con(x,**kwargs):
"""
LP constraints
"""
return[resources(x,**kwargs)]
def swarm(soldiers,castles,trials):
""""
Particle Swarm optimization to solve Linear Program
"""
s1 = []
for i in range(trials):
s = RandoStrat1(soldiers,castles)
s1.append(s)
i+=1
kwargs= {
"strats" : s1,
'castles': castles
}
lb = [0]*castles
ub = [100]*castles
xopt, fopt = pso(lp, lb, ub,f_ieqcons=con, kwargs=kwargs,maxiter=1e4)
print(xopt)
if __name__ == "__main__":
print('---Running Simulation---')
castles = 10
soldiers = 100
trials = 100000
print('Num Trials:',trials)
round_robin_A(soldiers,castles,trials)
"""
Implementation of this paper, with modifications to fit specific challenge:
https://pdfs.semanticscholar.org/241b/a18a3819a3341ef091eb99b10dc510f28ef0.pdf
Idea of Lp came from here:
https://www2.stetson.edu/~efriedma/research/jones.pdf
but search space was too big to be viable
Algorithm:
100000 random strategies generated
first round robbin of all strategies
all strategies are scored
top third are selected for second round robin
second round robin played
Top scorer of second round is declared winner
Output:
---Running Simulation---
Num Trials: 100000
A mean: 28.0859253702
Winner Score Against A: 272.62244
B mean: 75.8993500402
Winner Score Against B: 244.95769957699576
[6, 3, 8, 7, 15, 10, 16, 8, 10, 17]
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment