Beispiel #1
0
    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)
Beispiel #2
0
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
Beispiel #6
0
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))
Beispiel #12
0
def solve():
    origami = Origami()
    origami.set_default()
    play(origami)
    print(origami.vertices)
    print(origami.edges)
Beispiel #13
0
def play(origami=Origami()):
    print(origami.vertices[0], origami.vertices[1])
    origami.fold(origami.vertices[0], origami.vertices[1])
Beispiel #14
0
def solve():
    origami = Origami()
    origami.set_default()
    play(origami)
    print(origami.vertices)
    print(origami.edges)
Beispiel #15
0
    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()
Beispiel #16
0
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)