def _origami_for_leaves(self, attacker_type): # solve this singleton typespace with origami origami = Origami(self.game, attacker_type) origami.solve() attack_set = origami.opt_attack_set # save solution time self.solution_time += origami.solution_time # feasible strategies are all targets in attackset self.feasible_strategies[tuple([attacker_type])] = \ set([tuple([i]) for i in attack_set]) # bounds are defender payoffs for t in range(len(attack_set)): target = attack_set[t] attacker_types = tuple([attacker_type]) pure_strat = tuple([target]) # compute payoff for this pure_strategy pay_off = (origami.defender_covered[target] * \ origami.opt_coverage[target]) + \ ((1 - origami.opt_coverage[target]) * \ origami.defender_uncovered[target]) probability = self.attacker_type_probability[attacker_type] self._update_bound(attacker_types, pure_strat, pay_off, probability) # update opt_defender payoff for class self.opt_defender_payoff = origami.opt_defender_payoff self.opt_defender_mixed_strategy = origami.opt_coverage return (origami.opt_defender_payoff, origami.opt_coverage)
def load(): print("problem id:") problem_id = input() path = "./../problems/problem_" + str(problem_id).zfill(5) + ".txt" if os.path.exists(path): print("id: " + str(problem_id) + " exists.") else: print("id: " + str(problem_id) + " does not exist.") return Origami() origami = Origami() f = open(path) origami.polygon_num = map(int, f.readline().split())[0] v_num = map(int, f.readline().split())[0] for i in range(v_num): v = f.readline().split(',') origami.vertices.append(point(Fraction(v[0]), Fraction(v[1]))) e_num = map(int, f.readline().split())[0] for i in range(e_num): e = re.split('[, ]', f.readline()) origami.edges.append([ edge(Fraction(e[0]), Fraction(e[1])), edge(Fraction(e[2]), Fraction(e[3])) ]) f.close() # print(origami.vertices) # print(origami.edges) return origami
def EierlegendeWollmilchsau(): r""" Eierlegende Wollmilchsau origami. This origami is associated to the quaternion group and was discovered by Gaby Schmithüsen. EXAMPLES:: sage: from surface_dynamics.all import * sage: o = origamis.EierlegendeWollmilchsau() sage: o Eierlegende Wollmilchsau sage: print str(o) (1,2,3,4)(5,6,7,8) (1,5,3,7)(2,8,4,6) sage: o.veech_group().index() 1 sage: o.sum_of_lyapunov_exponents() 1 sage: oo = origamis.CyclicCover([1,1,1,1]) sage: o.is_isomorphic(oo) True """ r = [1,2,3,0,5,6,7,4] u = [4,7,6,5,2,1,0,3] positions = [(0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1)] name = "Eierlegende Wollmilchsau" o = Origami(r,u,check=False,as_tuple=True,positions=positions,name=name) return o
def Escalator(n): r""" Escalator origamis The escalator origami has 2n squares and is defined by r = (1 2)(3 4) ... (2n-1 2n) u = (2 3)(4 5) ... (2n 1) EXAMPLES:: sage: from surface_dynamics.all import * sage: o = origamis.Escalator(3) sage: o Escalator with 3 steps sage: print str(o) (1,2)(3,4)(5,6) (1,6)(2,3)(4,5) sage: o.veech_group().index() 3 """ lr = [(i,i+1) for i in xrange(1,2*n+1,2)] lu = [(1,2*n)] + [(i,i+1) for i in xrange(2,2*n,2)] positions = [((i+1)//2,i//2) for i in xrange(2*n)] name = "Escalator with %d steps" %n o = Origami(lr,lu,positions=positions,name=name) return o
def Stair(n): r""" Stair origamis The stair origami with n=2k squares is defined by the permutations r = (1 2)(3 4) ... (n-1 n) u = (1)(2 3) ... (n-2 n-1)(n) The stair origamis with n=2k+1 squares is defined by the permutations r = (1 2)(3 4) ... (n-2 n-1)(n) u = (1)(2 3) ... (n-1 n-2) EXAMPLES:: sage: from surface_dynamics.all import * sage: o = origamis.Stair(4) sage: o Stair origami with 4 squares sage: print str(o) (1,2)(3,4) (1)(2,3)(4) sage: o = origamis.Stair(5) sage: o Stair origami with 5 squares sage: print str(o) (1,2)(3,4)(5) (1)(2,3)(4,5) """ r = [] u = [0] for i in xrange(1,n-1,2): r.append(i) r.append(i-1) u.append(i+1) u.append(i) if n%2: r.append(n-1) else: r.append(n-1) r.append(n-2) u.append(n-1) positions = [((i+1)//2,i//2) for i in xrange(n)] o = Origami(r,u,as_tuple=True,positions=positions,name="Stair origami with %d squares" %n) return o
def load(): print("problem id:") problem_id = input() path = "./../problems/problem_" + str(problem_id).zfill(5) + ".txt" if os.path.exists(path): print("id: " + str(problem_id) + " exists.") else: print("id: " + str(problem_id) + " does not exist.") return Origami() origami = Origami() f = open(path) origami.polygon_num = map(int, f.readline().split())[0] v_num = map(int, f.readline().split())[0] for i in range(v_num): v = f.readline().split(',') origami.vertices.append(point(Fraction(v[0]), Fraction(v[1]))) e_num = map(int, f.readline().split())[0] for i in range(e_num): e = re.split('[, ]', f.readline()) origami.edges.append([edge(Fraction(e[0]), Fraction(e[1])), edge(Fraction(e[2]), Fraction(e[3]))]) f.close() # print(origami.vertices) # print(origami.edges) return origami
def Heisenberg(p): r""" Return the Heisenberg origami. EXAMPLES:: sage: from surface_dynamics.all import * sage: h2 = origamis.Heisenberg(2) sage: h2.stratum_component() H_3(1^4)^c sage: h2.veech_group().index() 3 sage: h2.sum_of_lyapunov_exponents() 2 sage: h3 = origamis.Heisenberg(3) sage: h3.stratum_component() H_10(2^9)^even sage: h3.veech_group().index() 1 sage: h3.sum_of_lyapunov_exponents() 5 sage: h5 = origamis.Heisenberg(5) sage: h5.stratum_component() H_51(4^25)^even sage: h5.veech_group().index() 1 sage: h5.sum_of_lyapunov_exponents() 15 """ p = ZZ(p) if not p.is_prime(): raise ValueError("p (={}) must be prime".format(p)) N = p**3 # map (a,b,d) -> a*p**2 + b*p + d pp = p*p r = [None]*N u = [None]*N for a in xrange(p): for b in xrange(p): for d in xrange(p): n = a*pp + b*p + d r[n] = ((a+1)%p)*pp + b*p + d u[n] = a*pp + ((b+1)%p)*p + ((a+d)%p) return Origami(r,u, as_tuple=True, name="Heisenberg origami on GF(%d)"%p)
def Podium(data): r""" If ``data`` is an integer than the standard podium with ``data`` steps is returned. Otherwise, ``data`` should be a weakly decreasing list of integers (i.e. a integer partition). EXAMPLES:: sage: from surface_dynamics.all import * sage: o = origamis.Podium([3,3,2,1]) sage: o Podium origami with partition [3, 3, 2, 1] sage: print o (1,2,3)(4,5,6)(7,8)(9) (1,4,7,9)(2,5,8)(3,6) """ from sage.combinat.partition import Partition if isinstance(data, (int,Integer)): p = Partition([i for i in xrange(data,0,-1)]) else: p = Partition(data) p = Partition(data) q = p.conjugate() r=[] positions = [] i = 0 for j,jj in enumerate(p): r.extend(xrange(i+1,i+jj)) r.append(i) i += jj positions.extend((k,j) for k in xrange(jj)) u = [None]*sum(p) for j in xrange(len(q)): k = j for jj in xrange(q[j]-1): u[k] = k+p[jj] k += p[jj] u[k] = j return Origami(r,u,positions=positions,name="Podium origami with partition %s" %str(p),as_tuple=True)
def ProjectiveLine(p, r=None, u=None): r""" Return the projective line with action given by the matrices ``r`` and ``u`` on the projective line over the field with ``p`` elements. If ``r`` and ``u`` are None, then r and u are choosen to be .. MATH:: r: z \mapsto z+1 \qquad u: z \mapsto 1/z The monodromy of this origami is included in `PGL(2,\ZZ/p\ZZ)`. EXAMPLES:: sage: from surface_dynamics.all import * By default, the matrix used to generate the projective line origami are given by `z -> z+1` and `z -> 1/z` which gives a family of origamis which belongs to the strata ``H(2^k)``:: sage: o = origamis.ProjectiveLine(3); o Projective line origami on GF(3) r = [1 1] u = [0 1] [0 1] [1 0] sage: o.stratum() H_2(2) sage: o.veech_group().index() 9 sage: o.sum_of_lyapunov_exponents() 4/3 sage: o = origamis.ProjectiveLine(5); o Projective line origami on GF(5) r = [1 1] u = [0 1] [0 1] [1 0] sage: o.stratum() H_3(2^2) sage: o.veech_group().index() 9 sage: o.sum_of_lyapunov_exponents() 5/3 sage: o = origamis.ProjectiveLine(7); o Projective line origami on GF(7) r = [1 1] u = [0 1] [0 1] [1 0] sage: o.stratum() H_3(2^2) sage: o.veech_group().index() 45 sage: o.sum_of_lyapunov_exponents() 5/3 Any invertible matrix mod p can be choosed to generate the origami:: sage: r = matrix([[1,3],[0,1]]) sage: u = matrix([[1,0],[3,1]]) sage: o = origamis.ProjectiveLine(5,r,u); o Projective line origami on GF(5) r = [1 3] u = [1 0] [0 1] [3 1] sage: o.veech_group().index() 10 sage: o.sum_of_lyapunov_exponents() 9/5 sage: o.stratum_component() H_3(4)^hyp """ from sage.arith.all import is_prime from sage.rings.finite_rings.finite_field_constructor import GF from sage.groups.matrix_gps.linear import GL from sage.modules.free_module import VectorSpace p = ZZ(p) if not p.is_prime(): raise ValueError("p (={}) must be a prime number".format(p)) G = GL(2,GF(p)) V = VectorSpace(GF(p),2) if r is None: mr = G([[1,1],[0,1]]) else: mr = G(r) if u is None: mu = G([[0,1],[1,0]]) else: mu = G(u) sr = str(mr).split('\n') su = str(mu).split('\n') mr = mr mu = mu if r is None and u is None: positions = [(i,0) for i in xrange(p+1)] else: positions = None r = [] u = [] for i in xrange(p): v = V((i,1)) * mr if v[1]: r.append(int(v[0]/v[1])) else: r.append(p) v = V((i,1)) * mu if v[1]: u.append(int(v[0]/v[1])) else: u.append(p) v = V((1,0)) * mr if v[1]: r.append(int(v[0]/v[1])) else: r.append(p) v = V((1,0)) * mu if v[1]: u.append(int(v[0]/v[1])) else: u.append(p) o = Origami(r,u, as_tuple=True, positions=positions, name="Projective line origami on GF(%d)\n r = %s u = %s\n %s %s"%(p,sr[0],su[0],sr[1],su[1])) return o
def CyclicCover(a, M=None): r""" Return the Abelian differential associated to the quadruple ``a`` INPUT: - ``a`` - quadruple of integers - ``M`` - positive integer (default: None) EXAMPLES: sage: from surface_dynamics.all import * There are two well known cyclic covers with completely degenerated Lyapunov spectrum:: sage: o = origamis.CyclicCover([1,1,1,1]) sage: o.sum_of_lyapunov_exponents() 1 sage: o = origamis.CyclicCover([1,1,1,3]) sage: o.sum_of_lyapunov_exponents() 1 """ from sage.arith.all import gcd if M is None: M = sum(a) a = map(Integer,a) if len(a) != 4: raise ValueError("a should be of length 4") if any(ai%2==0 for ai in a): raise ValueError("ai should be odd") if gcd([M]+a) != 1: raise ValueError("gcd(M,a) should be 0") if M%2: raise ValueError("M should be even") if sum(a) % M: raise ValueError("the sum of ai should be 0 mod M") r = [None] * (2*M) u = [None] * (2*M) # initialize horizontal cylinders i = 0 seen = set([]) pos = set([0]) neg = set([]) while pos or neg: # initialize pos 2i and 2i+1 if pos: i = pos.pop() seen.add(i) r[2*i] = 2*i+1 r[2*i+1] = (2*(i+a[0]+a[3])) % (2*M) # sigma_A + sigma_D j = (i + a[0] + a[3]) % M if j not in seen and j not in pos: pos.add(j) u[2*i] = (2*(i-a[3])+1) % (2*M) # sigma_D^-1 j = (i-a[3]) % M if j not in seen and j not in neg: neg.add(j) u[2*i+1] = (2*(i+a[3])) % (2*M) # sigma_D j = (i+a[3]) % M if j not in seen and j not in neg: neg.add(j) if neg: i = neg.pop() seen.add(i) r[2*i+1] = 2*i r[2*i] = (2*(i+a[1]+a[2]) + 1) % (2*M) # sigma_B + sigma_C j = (i+a[1]+a[2]) % M if j not in seen and j not in neg: neg.add(j) u[2*i] = (2*(i+a[2]) + 1) % (2*M) # sigma_C j = (i+a[2]) % M if j not in seen and j not in neg: pos.add(j) u[2*i+1] = (2*(i-a[2])) % (2*M) # sigma_C^-1 j = (i-a[2]) %M if j not in seen and j not in neg: pos.add(j) return Origami(r,u,as_tuple=True,name="M_%d(%d,%d,%d,%d)" %(M,a[0],a[1],a[2],a[3]))
from games import SecurityGame, NormalFormGame from dobbs import Dobbs from multipleLP import MultipleLP from origami import Origami from eraser import Eraser from origami_milp import OrigamiMILP import time start = time.time() comp_game = SecurityGame(12, 10, 2) # norm_game = NormalFormGame(game=comp_game, harsanyi=False) # hars_game = NormalFormGame(game=norm_game) ori = Origami(comp_game) ori.solve() # dob = Dobbs(norm_game) # dob.solve() # mlp = MultipleLP(hars_game) # mlp.solve() # ers = Eraser(comp_game) # ers.solve() oriMILP = OrigamiMILP(comp_game) oriMILP.solve() # print("dob attacked target: {}".format(dob.opt_attacked_targets)) # print("mlp attacked target: {}".format(mlp.opt_attacker_pure_strategy)) # print("MLP opt-value: {}".format(mlp.opt_defender_payoff)) # print("DOB opt-value: {}".format(dob.opt_defender_payoff)) print("ORI opt_defender_payoff: {}".format(ori.opt_defender_payoff))
def solve(): origami = Origami() origami.set_default() play(origami) print(origami.vertices) print(origami.edges)
def play(origami=Origami()): print(origami.vertices[0], origami.vertices[1]) origami.fold(origami.vertices[0], origami.vertices[1])
def setUpClass(self): """ Create Games: 1) Set up a security game, generate corresponding norm_form and harsanyi-transformed norm_form game. 2) Set up a large non-bayesian security game 3) Set up bayesian norm_form, generate corresponding harsanyi- transformed norm_form game. 4) Set up norm_form game. Solve Games: """ # construct games # part 1 self.sec_game = SecurityGame(num_targets=5, max_coverage=3, num_attacker_types=1) self.sec_norm_game = NormalFormGame(game=self.sec_game, harsanyi=False) self.sec_norm_hars_game = NormalFormGame(game=self.sec_norm_game) # part 2 self.large_sec_game = SecurityGame(num_targets=100, max_coverage=30, num_attacker_types=1) # part 3 self.bayse_sec_game = SecurityGame(num_targets=5, max_coverage=3, num_attacker_types=2) self.bayse_sec_norm_game = NormalFormGame(game=self.bayse_sec_game, harsanyi=False) self.bayse_sec_norm_hars_game = NormalFormGame( game=self.bayse_sec_norm_game) # part 4 self.bayse_norm_game = NormalFormGame(num_defender_strategies=10, num_attacker_strategies=3, num_attacker_types=3) self.bayse_norm_hars_game = NormalFormGame(game=self.bayse_norm_game) self.bayse_norm_partial_full_game = NormalFormGame( partial_game_from=self.bayse_norm_game, attacker_types=(0, 1, 2)) self.bayse_norm_partial_game = NormalFormGame( partial_game_from=self.bayse_norm_game, attacker_types=(1, 2)) # part 5 self.norm_game = NormalFormGame(num_defender_strategies=20, num_attacker_strategies=10, num_attacker_types=1) # solve games: # part 1 (non-bayesian security games) print("solving part 1") self.p1_eraser = Eraser(self.sec_game) self.p1_origami = Origami(self.sec_game) self.p1_origami_milp = OrigamiMILP(self.sec_game) self.p1_dobbs = Dobbs(self.sec_norm_game) self.p1_multLP = MultipleLP(self.sec_norm_hars_game) self.p1_multSingLP_sec_game = Multiple_SingleLP(self.sec_game) self.p1_multSingLP_sec_norm_game = Multiple_SingleLP( self.sec_norm_game) self.p1_multSingLP_sec_norm_hars_game = Multiple_SingleLP( self.sec_norm_hars_game) self.p1_eraser.solve() self.p1_origami.solve() self.p1_origami_milp.solve() self.p1_dobbs.solve() self.p1_multLP.solve() self.p1_multSingLP_sec_game.solve() self.p1_multSingLP_sec_norm_game.solve() self.p1_multSingLP_sec_norm_hars_game.solve() # part 2 (large security game) print("solving part 2") self.p2_large_origami = Origami(self.large_sec_game) self.p2_large_origami_milp = OrigamiMILP(self.large_sec_game) self.p2_large_eraser = Eraser(self.large_sec_game) self.p2_large_origami.solve() self.p2_large_origami_milp.solve() self.p2_large_eraser.solve() # part 3 (bayseian security games) print("solving part 3") self.p3_dobbs = Dobbs(self.bayse_sec_norm_game) self.p3_multLP = MultipleLP(self.bayse_sec_norm_hars_game) self.p3_multSingLP = Multiple_SingleLP(self.bayse_sec_game) self.p3_hbgs = HBGS(self.bayse_sec_game) self.p3_hbgs_origami = HBGS(self.bayse_sec_game, True) self.p3_hbgs_norm = HBGS(self.bayse_sec_norm_game) self.p3_dobbs.solve() self.p3_multLP.solve() self.p3_multSingLP.solve() self.p3_hbgs.solve() self.p3_hbgs_origami.solve() self.p3_hbgs_norm.solve() # part 4 (bayesian norm_form game) print("solving part 4") self.p4_dobbs = Dobbs(self.bayse_norm_game) self.p4_multLP = MultipleLP(self.bayse_norm_hars_game) self.p4_multSingLP = Multiple_SingleLP(self.bayse_norm_game) self.p4_dobbs_partial_full = Dobbs(self.bayse_norm_partial_full_game) self.p4_multSingLP_partial_full = \ Multiple_SingleLP(self.bayse_norm_partial_full_game) self.p4_dobbs_partial = Dobbs(self.bayse_norm_partial_game) self.p4_multSingLP_partial = \ Multiple_SingleLP(self.bayse_norm_partial_game) self.p4_hbgs = HBGS(self.bayse_norm_game) self.p4_dobbs.solve() self.p4_multLP.solve() self.p4_multSingLP.solve() self.p4_dobbs_partial.solve() self.p4_dobbs_partial_full.solve() self.p4_multSingLP_partial_full.solve() self.p4_dobbs_partial.solve() self.p4_multSingLP_partial.solve() self.p4_hbgs.solve() # part 5 print("solving part 5") self.p5_dobbs = Dobbs(self.norm_game) self.p5_multLP = MultipleLP(self.norm_game) self.p5_multSingLP = Multiple_SingleLP(self.norm_game) self.p5_dobbs.solve() self.p5_multLP.solve() self.p5_multSingLP.solve()
class TestSolvers(unittest.TestCase): @classmethod def setUpClass(self): """ Create Games: 1) Set up a security game, generate corresponding norm_form and harsanyi-transformed norm_form game. 2) Set up a large non-bayesian security game 3) Set up bayesian norm_form, generate corresponding harsanyi- transformed norm_form game. 4) Set up norm_form game. Solve Games: """ # construct games # part 1 self.sec_game = SecurityGame(num_targets=5, max_coverage=3, num_attacker_types=1) self.sec_norm_game = NormalFormGame(game=self.sec_game, harsanyi=False) self.sec_norm_hars_game = NormalFormGame(game=self.sec_norm_game) # part 2 self.large_sec_game = SecurityGame(num_targets=100, max_coverage=30, num_attacker_types=1) # part 3 self.bayse_sec_game = SecurityGame(num_targets=5, max_coverage=3, num_attacker_types=2) self.bayse_sec_norm_game = NormalFormGame(game=self.bayse_sec_game, harsanyi=False) self.bayse_sec_norm_hars_game = NormalFormGame( game=self.bayse_sec_norm_game) # part 4 self.bayse_norm_game = NormalFormGame(num_defender_strategies=10, num_attacker_strategies=3, num_attacker_types=3) self.bayse_norm_hars_game = NormalFormGame(game=self.bayse_norm_game) self.bayse_norm_partial_full_game = NormalFormGame( partial_game_from=self.bayse_norm_game, attacker_types=(0, 1, 2)) self.bayse_norm_partial_game = NormalFormGame( partial_game_from=self.bayse_norm_game, attacker_types=(1, 2)) # part 5 self.norm_game = NormalFormGame(num_defender_strategies=20, num_attacker_strategies=10, num_attacker_types=1) # solve games: # part 1 (non-bayesian security games) print("solving part 1") self.p1_eraser = Eraser(self.sec_game) self.p1_origami = Origami(self.sec_game) self.p1_origami_milp = OrigamiMILP(self.sec_game) self.p1_dobbs = Dobbs(self.sec_norm_game) self.p1_multLP = MultipleLP(self.sec_norm_hars_game) self.p1_multSingLP_sec_game = Multiple_SingleLP(self.sec_game) self.p1_multSingLP_sec_norm_game = Multiple_SingleLP( self.sec_norm_game) self.p1_multSingLP_sec_norm_hars_game = Multiple_SingleLP( self.sec_norm_hars_game) self.p1_eraser.solve() self.p1_origami.solve() self.p1_origami_milp.solve() self.p1_dobbs.solve() self.p1_multLP.solve() self.p1_multSingLP_sec_game.solve() self.p1_multSingLP_sec_norm_game.solve() self.p1_multSingLP_sec_norm_hars_game.solve() # part 2 (large security game) print("solving part 2") self.p2_large_origami = Origami(self.large_sec_game) self.p2_large_origami_milp = OrigamiMILP(self.large_sec_game) self.p2_large_eraser = Eraser(self.large_sec_game) self.p2_large_origami.solve() self.p2_large_origami_milp.solve() self.p2_large_eraser.solve() # part 3 (bayseian security games) print("solving part 3") self.p3_dobbs = Dobbs(self.bayse_sec_norm_game) self.p3_multLP = MultipleLP(self.bayse_sec_norm_hars_game) self.p3_multSingLP = Multiple_SingleLP(self.bayse_sec_game) self.p3_hbgs = HBGS(self.bayse_sec_game) self.p3_hbgs_origami = HBGS(self.bayse_sec_game, True) self.p3_hbgs_norm = HBGS(self.bayse_sec_norm_game) self.p3_dobbs.solve() self.p3_multLP.solve() self.p3_multSingLP.solve() self.p3_hbgs.solve() self.p3_hbgs_origami.solve() self.p3_hbgs_norm.solve() # part 4 (bayesian norm_form game) print("solving part 4") self.p4_dobbs = Dobbs(self.bayse_norm_game) self.p4_multLP = MultipleLP(self.bayse_norm_hars_game) self.p4_multSingLP = Multiple_SingleLP(self.bayse_norm_game) self.p4_dobbs_partial_full = Dobbs(self.bayse_norm_partial_full_game) self.p4_multSingLP_partial_full = \ Multiple_SingleLP(self.bayse_norm_partial_full_game) self.p4_dobbs_partial = Dobbs(self.bayse_norm_partial_game) self.p4_multSingLP_partial = \ Multiple_SingleLP(self.bayse_norm_partial_game) self.p4_hbgs = HBGS(self.bayse_norm_game) self.p4_dobbs.solve() self.p4_multLP.solve() self.p4_multSingLP.solve() self.p4_dobbs_partial.solve() self.p4_dobbs_partial_full.solve() self.p4_multSingLP_partial_full.solve() self.p4_dobbs_partial.solve() self.p4_multSingLP_partial.solve() self.p4_hbgs.solve() # part 5 print("solving part 5") self.p5_dobbs = Dobbs(self.norm_game) self.p5_multLP = MultipleLP(self.norm_game) self.p5_multSingLP = Multiple_SingleLP(self.norm_game) self.p5_dobbs.solve() self.p5_multLP.solve() self.p5_multSingLP.solve() def test_p1(self): """ Test if opt_defender_payoff is the same across all solutions """ self.assertAlmostEqual(self.p1_dobbs.opt_defender_payoff, self.p1_eraser.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p1_dobbs.opt_defender_payoff, self.p1_multLP.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p1_dobbs.opt_defender_payoff, self.p1_origami.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p1_dobbs.opt_defender_payoff, self.p1_origami_milp.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p1_dobbs.opt_defender_payoff, self.p1_multSingLP_sec_game.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p1_dobbs.opt_defender_payoff, self.p1_multSingLP_sec_norm_game.\ opt_defender_payoff, places=1) self.assertAlmostEqual(self.p1_dobbs.opt_defender_payoff, self.p1_multSingLP_sec_norm_hars_game.\ opt_defender_payoff, places=1) def test_p2(self): """ Test if solvers taking compact representations of large games are in agreement. """ # test that every opt_target is the same for all solvers ori_target = self.p2_large_origami.opt_attacked_target ori_milp_target = self.p2_large_origami_milp.opt_attacked_target ers_target = self.p2_large_eraser.opt_attacked_target print("ORIGAMI SOL: {}".format(self.p2_large_origami.solution_time)) print("ORIGAMI OH SOL: {}".format( self.p2_large_origami.solution_time_with_overhead)) print("ORI_MILP SOL: {}".format( self.p2_large_origami_milp.solution_time)) print("ORI_MILP OH SOL: {}".format( self.p2_large_origami_milp.solution_time_with_overhead)) self.assertEqual(ori_target, ori_milp_target, msg="opt target disagree: origami vs. origami_milp") self.assertEqual(ori_milp_target, ers_target, msg="opt target disagree: origami_milp vs. eraser") # test that coverage is the same for attacked target self.assertAlmostEqual( self.p2_large_origami.opt_coverage[ori_target], self.p2_large_origami_milp.opt_coverage[ori_milp_target], places=1, msg="cov for attacked target disagree: origami vs. origami_milp") self.assertAlmostEqual( self.p2_large_origami.opt_coverage[ori_target], self.p2_large_eraser.opt_coverage[ers_target], places=1, msg="cov for attacked target disagree: origami vs. eraser") # test that payoff is the same self.assertAlmostEqual(self.p2_large_origami.opt_defender_payoff, self.p2_large_origami_milp.opt_defender_payoff, places=1, msg="payoff disagreement: orig vs. orig-milp") self.assertAlmostEqual(self.p2_large_origami.opt_defender_payoff, self.p2_large_eraser.opt_defender_payoff, places=1, msg="payoff disagreement: ori vs. eraser") # test that attackset are the same for origami and origami-milp self.assertEqual( len(self.p2_large_origami.opt_attack_set), len(self.p2_large_origami_milp.opt_attack_set), msg="attackset diff. length: origami vs. origami-milp") def test_p3(self): """ Test if opt_defender_payoff is the same across all solutions """ self.assertAlmostEqual(self.p3_dobbs.opt_defender_payoff, self.p3_multLP.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p3_dobbs.opt_defender_payoff, self.p3_multSingLP.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p3_hbgs.opt_defender_payoff, self.p3_dobbs.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p3_hbgs_origami.opt_defender_payoff, self.p3_dobbs.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p3_hbgs_norm.opt_defender_payoff, self.p3_dobbs.opt_defender_payoff, places=1) def test_p4(self): """ Test if bayesian normal form game solvers are in agreement. """ # print("sol tim, dob, mltLP vs. Singl") # print(self.p4_dobbs.solution_time) # print(self.p4_multLP.solution_time) # print(self.p4_multSingLP.solution_time) # test that the expected opt defender payoff is the same self.assertAlmostEqual(self.p4_dobbs.opt_defender_payoff, self.p4_multLP.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p4_dobbs.opt_defender_payoff, self.p4_multSingLP.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p4_dobbs_partial_full.opt_defender_payoff, self.p4_multSingLP_partial_full.\ opt_defender_payoff, places=1) self.assertAlmostEqual(self.p4_dobbs_partial.opt_defender_payoff, self.p4_multSingLP_partial.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p4_hbgs.opt_defender_payoff, self.p4_dobbs.opt_defender_payoff, places=1) # test that opt defender strat. yields the same attacker pure strategy self.assertSequenceEqual(self.p4_dobbs.opt_attacker_pure_strategy, self.p4_multSingLP.opt_attacker_pure_strategy) # self.assertSequenceEqual(self.p4_dobbs.opt_attacker_pure_strategy, # self.bayse_norm_hars_game.\ # attacker_pure_strategy_tuples[self.p4_multLP.\ # opt_attacker_pure_strategy]) def test_p5(self): """ Test agreement between all solvers of non-bayesian normal form games. """ # test that the expected opt defender payoff is the same self.assertAlmostEqual(self.p5_dobbs.opt_defender_payoff, self.p5_multLP.opt_defender_payoff, places=1) self.assertAlmostEqual(self.p5_dobbs.opt_defender_payoff, self.p5_multSingLP.opt_defender_payoff, places=1) # test that opt defender strat. yields the same attacker pure strategy self.assertSequenceEqual(self.p5_dobbs.opt_attacker_pure_strategy, self.p5_multSingLP.opt_attacker_pure_strategy) self.assertEqual(self.p5_dobbs.opt_attacker_pure_strategy[0], self.p5_multLP.opt_attacker_pure_strategy)