Ejemplo n.º 1
0
def basic_different_dec_cardinality() -> MACID:
    macid = MACID([('D1', 'D2'), ('D1', 'U1'), ('D1', 'U2'), ('D2', 'U2'),
                   ('D2', 'U1')], {
                       0: {
                           'D': ['D1'],
                           'U': ['U1']
                       },
                       1: {
                           'D': ['D2'],
                           'U': ['U2']
                       }
                   })

    cpd_d1 = DecisionDomain('D1', [0, 1])
    cpd_d2 = DecisionDomain('D2', [0, 1, 2])

    cpd_u1 = TabularCPD('U1',
                        4,
                        np.array([[0, 0, 1, 0, 0, 0], [0, 1, 0, 1, 0, 0],
                                  [0, 0, 0, 0, 1, 0], [1, 0, 0, 0, 0, 1]]),
                        evidence=['D1', 'D2'],
                        evidence_card=[2, 3])
    cpd_u2 = TabularCPD('U2',
                        4,
                        np.array([[0, 0, 0, 0, 1, 0], [1, 0, 1, 1, 0, 0],
                                  [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1]]),
                        evidence=['D1', 'D2'],
                        evidence_card=[2, 3])

    macid.add_cpds(cpd_d1, cpd_d2, cpd_u1, cpd_u2)

    return macid
Ejemplo n.º 2
0
def get_insufficient_recall_cid() -> CID:
    cid = CID([('A', 'U'), ('B', 'U')],
              decision_nodes=['A', 'B'],
              utility_nodes=['U'])
    cid.add_cpds(DecisionDomain('A', [0, 1]), DecisionDomain('B', [0, 1]),
                 FunctionCPD('U', lambda a, b: a * b, evidence=['A', 'B']))
    return cid
Ejemplo n.º 3
0
def modified_taxi_competition() -> MACID:
    """ Modifying the payoffs in the taxi competition example
    so that there is a tie break (if taxi 1 chooses to stop
    in front of the expensive hotel, taxi 2 is indifferent
    between their choices.)

    - There are now two SPNE

                              D1
        +----------+----------+----------+
        |  taxi 1  | expensive|  cheap   |
        +----------+----------+----------+
        |expensive |     2    |   3      |
    D2  +----------+----------+----------+
        | cheap    |     5    |   1      |
        +----------+----------+----------+

                              D1
        +----------+----------+----------+
        |  taxi 2  | expensive|  cheap   |
        +----------+----------+----------+
        |expensive |     2    |   5      |
    D2  +----------+----------+----------+
        | cheap    |     3    |   5      |
        +----------+----------+----------+

    """
    macid = MACID([('D1', 'D2'), ('D1', 'U1'), ('D1', 'U2'), ('D2', 'U2'),
                   ('D2', 'U1')], {
                       1: {
                           'D': ['D1'],
                           'U': ['U1']
                       },
                       2: {
                           'D': ['D2'],
                           'U': ['U2']
                       }
                   })

    d1_domain = ['e', 'c']
    d2_domain = ['e', 'c']
    cpd_d1 = DecisionDomain('D1', d1_domain)
    cpd_d2 = DecisionDomain('D2', d2_domain)

    agent1_payoff = np.array([[2, 3], [5, 1]])
    agent2_payoff = np.array([[2, 5], [3, 5]])

    cpd_u1 = FunctionCPD('U1',
                         lambda d1, d2: agent1_payoff[d2_domain.index(d2),
                                                      d1_domain.index(d1)],
                         evidence=['D1', 'D2'])
    cpd_u2 = FunctionCPD('U2',
                         lambda d1, d2: agent2_payoff[d2_domain.index(d2),
                                                      d1_domain.index(d1)],
                         evidence=['D1', 'D2'])

    macid.add_cpds(cpd_d1, cpd_d2, cpd_u1, cpd_u2)
    return macid
Ejemplo n.º 4
0
def taxi_competition() -> MACID:
    """ A MACIM for the "Taxi Competition" example
    introduced in "Equilibrium Refinements for Multi-Agent
    Influence Diagrams: Theory and Practice" by Hammond, Fox,
    Everitt, Abate & Wooldridge, 2021:

                              D1
        +----------+----------+----------+
        |  taxi 1  | expensive|  cheap   |
        +----------+----------+----------+
        |expensive |     2    |   3      |
    D2  +----------+----------+----------+
        | cheap    |     5    |   1      |
        +----------+----------+----------+

                              D1
        +----------+----------+----------+
        |  taxi 2  | expensive|  cheap   |
        +----------+----------+----------+
        |expensive |     2    |   5      |
    D2  +----------+----------+----------+
        | cheap    |     3    |   1      |
        +----------+----------+----------+

    - There are 3 pure startegy NE and 1 pure SPE.
    """
    macid = MACID([('D1', 'D2'), ('D1', 'U1'), ('D1', 'U2'), ('D2', 'U2'),
                   ('D2', 'U1')], {
                       1: {
                           'D': ['D1'],
                           'U': ['U1']
                       },
                       2: {
                           'D': ['D2'],
                           'U': ['U2']
                       }
                   })

    d1_domain = ['e', 'c']
    d2_domain = ['e', 'c']
    cpd_d1 = DecisionDomain('D1', d1_domain)
    cpd_d2 = DecisionDomain('D2', d2_domain)

    agent1_payoff = np.array([[2, 3], [5, 1]])
    agent2_payoff = np.array([[2, 5], [3, 1]])

    cpd_u1 = FunctionCPD('U1',
                         lambda d1, d2: agent1_payoff[d2_domain.index(d2),
                                                      d1_domain.index(d1)],
                         evidence=['D1', 'D2'])
    cpd_u2 = FunctionCPD('U2',
                         lambda d1, d2: agent2_payoff[d2_domain.index(d2),
                                                      d1_domain.index(d1)],
                         evidence=['D1', 'D2'])

    macid.add_cpds(cpd_d1, cpd_d2, cpd_u1, cpd_u2)
    return macid
Ejemplo n.º 5
0
def battle_of_the_sexes() -> MACID:
    """ This macim is a representation of the
    battle of the sexes game (also known as Bach or Stravinsky).
    It is a simultaneous symmetric two-player game with payoffs
    corresponding to the following normal
    form game - the row player is Female and the
    column player is Male:
        +----------+----------+----------+
        |          |Opera     | Football |
        +----------+----------+----------+
        |  Opera   | 3, 2     |   0, 0   |
        +----------+----------+----------+
        | Football | 0, 0     | 2, 3     |
        +----------+----------+----------+
    - This game has two pure NE: (Opera, Football) and (Football, Opera)
    """
    macid = MACID([('D_F', 'U_F'), ('D_F', 'U_M'), ('D_M', 'U_M'),
                   ('D_M', 'U_F')], {
                       'M': {
                           'D': ['D_F'],
                           'U': ['U_F']
                       },
                       'F': {
                           'D': ['D_M'],
                           'U': ['U_M']
                       }
                   })

    d_f_domain = ['O', 'F']
    d_m_domain = ['O', 'F']
    cpd_d_f = DecisionDomain('D_F', d_f_domain)
    cpd_d_m = DecisionDomain('D_M', d_m_domain)

    agent_f_payoff = np.array([[3, 0], [0, 2]])
    agent_m_payoff = np.array([[2, 0], [0, 3]])

    cpd_u_f = FunctionCPD(
        'U_F',
        lambda d_f, d_m: agent_f_payoff[d_f_domain.index(d_f),
                                        d_m_domain.index(d_m)],
        evidence=['D_F', 'D_M'])
    cpd_u_m = FunctionCPD(
        'U_M',
        lambda d_f, d_m: agent_m_payoff[d_f_domain.index(d_f),
                                        d_m_domain.index(d_m)],
        evidence=['D_F', 'D_M'])

    macid.add_cpds(cpd_d_f, cpd_d_m, cpd_u_f, cpd_u_m)
    return macid
Ejemplo n.º 6
0
def matching_pennies() -> MACID:
    """ This macim is a representation of the
    matching pennies game.
    It is symmetric two-player game with payoffs
    corresponding to the following normal
    form game - the row player is agent 1 and the
    column player is agent 2:
        +----------+----------+----------+
        |          |Heads     | Tails    |
        +----------+----------+----------+
        |  Heads   | +1, -1   | -1, +1   |
        +----------+----------+----------+
        | Tails    | -1, +1   | +1, -1   |
        +----------+----------+----------+
    - This game has no pure NE, but has a mixed NE where
    each player chooses Heads or Tails with equal probability.
    """
    macid = MACID([('D1', 'U1'), ('D1', 'U2'), ('D2', 'U2'), ('D2', 'U1')], {
        1: {
            'D': ['D1'],
            'U': ['U1']
        },
        2: {
            'D': ['D2'],
            'U': ['U2']
        }
    })

    d1_domain = ['H', 'T']
    d2_domain = ['H', 'T']
    cpd_d1 = DecisionDomain('D1', d1_domain)
    cpd_d2 = DecisionDomain('D2', d2_domain)

    agent1_payoff = np.array([[1, -1], [-1, 1]])
    agent2_payoff = np.array([[-1, 1], [1, -1]])

    cpd_u1 = FunctionCPD('U1',
                         lambda d1, d2: agent1_payoff[d1_domain.index(d1),
                                                      d2_domain.index(d2)],
                         evidence=['D1', 'D2'])
    cpd_u2 = FunctionCPD('U2',
                         lambda d1, d2: agent2_payoff[d1_domain.index(d1),
                                                      d2_domain.index(d2)],
                         evidence=['D1', 'D2'])

    macid.add_cpds(cpd_d1, cpd_d2, cpd_u1, cpd_u2)
    return macid
Ejemplo n.º 7
0
def prisoners_dilemma() -> MACID:
    """ This macim is a representation of the canonical
    prisoner's dilemma. It is a simultaneous
    symmetric two-player game with payoffs
    corresponding to the following normal
    form game - the row player is agent 1 and the
    column player is agent 2:
        +----------+----------+----------+
        |          |Cooperate | Defect   |
        +----------+----------+----------+
        |Cooperate | -1, -1   | -3, 0    |
        +----------+----------+----------+
        |  Defect  | 0, -3    | -2, -2   |
        +----------+----------+----------+
    - This game has one pure NE: (defect, defect)
    """
    macid = MACID([('D1', 'U1'), ('D1', 'U2'), ('D2', 'U2'), ('D2', 'U1')], {
        1: {
            'D': ['D1'],
            'U': ['U1']
        },
        2: {
            'D': ['D2'],
            'U': ['U2']
        }
    })

    d1_domain = ['c', 'd']
    d2_domain = ['c', 'd']
    cpd_d1 = DecisionDomain('D1', d1_domain)
    cpd_d2 = DecisionDomain('D2', d2_domain)

    agent1_payoff = np.array([[-1, -3], [0, -2]])
    agent2_payoff = np.transpose(agent1_payoff)

    cpd_u1 = FunctionCPD('U1',
                         lambda d1, d2: agent1_payoff[d1_domain.index(d1),
                                                      d2_domain.index(d2)],
                         evidence=['D1', 'D2'])
    cpd_u2 = FunctionCPD('U2',
                         lambda d1, d2: agent2_payoff[d1_domain.index(d1),
                                                      d2_domain.index(d2)],
                         evidence=['D1', 'D2'])

    macid.add_cpds(cpd_d1, cpd_d2, cpd_u1, cpd_u2)
    return macid
Ejemplo n.º 8
0
 def make_decision(self, node: str, agent: Union[str, int] = 0) -> None:
     """"Turn a chance or utility node into a decision node."""
     if hasattr(self, "cpds") and isinstance(self.get_cpds(node),
                                             DecisionDomain):
         pass
     elif hasattr(self, "cpds") and not isinstance(self.get_cpds(node),
                                                   DecisionDomain):
         cpd_new = DecisionDomain(node,
                                  self.get_cpds(node).state_names[node])
         self.decision_nodes_agent[agent].append(node)
         self.whose_node[node] = agent
         self.add_cpds(cpd_new)
     else:
         raise Exception(f"node {node} has not yet been assigned a domain.")
Ejemplo n.º 9
0
def c2d() -> MACID:
    macid = MACID([('C1', 'U1'), ('C1', 'U2'), ('C1', 'D1'), ('D1', 'U1'),
                   ('D1', 'U2'), ('D1', 'D2'), ('D2', 'U1'), ('D2', 'U2'),
                   ('C1', 'D2')], {
                       0: {
                           'D': ['D1'],
                           'U': ['U1']
                       },
                       1: {
                           'D': ['D2'],
                           'U': ['U2']
                       }
                   })

    cpd_c1 = TabularCPD('C1', 2, np.array([[.5], [.5]]))
    cpd_d1 = DecisionDomain('D1', [0, 1])
    cpd_d2 = DecisionDomain('D2', [0, 1])
    cpd_u1 = TabularCPD('U1',
                        4,
                        np.array([[0, 0, 0, 0, 1, 0, 0, 0],
                                  [1, 0, 1, 0, 0, 1, 0, 0],
                                  [0, 1, 0, 1, 0, 0, 1, 0],
                                  [0, 0, 0, 0, 0, 0, 0, 1]]),
                        evidence=['C1', 'D1', 'D2'],
                        evidence_card=[2, 2, 2])
    cpd_u2 = TabularCPD('U2',
                        6,
                        np.array([[0, 0, 0, 0, 0, 0, 0, 0],
                                  [1, 0, 0, 0, 0, 0, 1, 0],
                                  [0, 1, 0, 0, 0, 0, 0, 0],
                                  [0, 0, 1, 0, 0, 1, 0, 1],
                                  [0, 0, 0, 1, 0, 0, 0, 0],
                                  [0, 0, 0, 0, 1, 0, 0, 0]]),
                        evidence=['C1', 'D1', 'D2'],
                        evidence_card=[2, 2, 2])
    macid.add_cpds(cpd_c1, cpd_d1, cpd_d2, cpd_u1, cpd_u2)
    return macid
Ejemplo n.º 10
0
def random_cid(n_all: int,
               n_decisions: int,
               n_utilities: int,
               edge_density: float = 0.4,
               add_sr_edges: bool = True,
               add_cpds: bool = True,
               seed: int = None) -> CID:
    """Generates a random Cid with the specified number of nodes and edges"""

    all_names, decision_names, utility_names = get_node_names(
        n_all, n_decisions, n_utilities)
    edges = get_edges(all_names,
                      utility_names,
                      edge_density,
                      seed=seed,
                      allow_u_edges=False)
    cid = CID(edges, decision_names, utility_names)

    for uname in utility_names:
        for edge in edges:
            assert uname != edge[0]

    for i, d1 in enumerate(decision_names):
        for j, d2 in enumerate(decision_names[i + 1:]):
            assert d2 not in cid._get_ancestors_of(d1)

    if add_sr_edges:
        add_sufficient_recalls(cid)

    if add_cpds:
        for node in cid.nodes:
            if node in cid.all_decision_nodes:
                cid.add_cpds(DecisionDomain(node, [0, 1]))
            elif not cid.get_parents(node):  # node is a root node
                cid.add_cpds(UniformRandomCPD(node, [0, 1]))
            else:
                cid.add_cpds(
                    RandomlySampledFunctionCPD(node, cid.get_parents(node)))
    return cid
Ejemplo n.º 11
0
def get_introduced_bias() -> CID:

    cid = CID(
        [
            ('A', 'X'),  # defining the graph's nodes and edges
            ('Z', 'X'),
            ('Z', 'Y'),
            ('X', 'D'),
            ('X', 'Y'),
            ('D', 'U'),
            ('Y', 'U')
        ],
        decision_nodes=['D'],
        utility_nodes=['U'])

    cpd_a = UniformRandomCPD('A', [0, 1])
    cpd_z = UniformRandomCPD('Z', [0, 1])
    cpd_x = FunctionCPD('X', lambda a, z: a * z, evidence=['A', 'Z'])
    cpd_d = DecisionDomain('D', [0, 1])
    cpd_y = FunctionCPD('Y', lambda x, z: x + z, evidence=['X', 'Z'])
    cpd_u = FunctionCPD('U', lambda d, y: -(d - y)**2, evidence=['D', 'Y'])

    cid.add_cpds(cpd_a, cpd_d, cpd_z, cpd_x, cpd_y, cpd_u)
    return cid
Ejemplo n.º 12
0
def basic2agent_3() -> MACID:
    macid = MACID(
        [
            ('D1', 'D2'),  # KM_NE should = {'D1': 1, 'D2': 0, 'D3': 1}
            ('D1', 'D3'),
            ('D2', 'D3'),
            ('D1', 'U1'),
            ('D1', 'U2'),
            ('D1', 'U3'),
            ('D2', 'U1'),
            ('D2', 'U2'),
            ('D2', 'U3'),
            ('D3', 'U1'),
            ('D3', 'U2'),
            ('D3', 'U3')
        ],
        {
            0: {
                'D': ['D1'],
                'U': ['U1']
            },
            1: {
                'D': ['D2'],
                'U': ['U2']
            },
            2: {
                'D': ['D3'],
                'U': ['U3']
            }
        })

    cpd_d1 = DecisionDomain('D1', [0, 1])
    cpd_d2 = DecisionDomain('D2', [0, 1])
    cpd_d3 = DecisionDomain('D3', [0, 1])

    cpd_u1 = TabularCPD('U1',
                        7,
                        np.array([[0, 0, 0, 1, 0, 0, 0, 1],
                                  [1, 1, 0, 0, 0, 0, 1, 0],
                                  [0, 0, 0, 0, 0, 1, 0, 0],
                                  [0, 0, 1, 0, 0, 0, 0, 0],
                                  [0, 0, 0, 0, 0, 0, 0, 0],
                                  [0, 0, 0, 0, 1, 0, 0, 0],
                                  [0, 0, 0, 0, 0, 0, 0, 0]]),
                        evidence=['D1', 'D2', 'D3'],
                        evidence_card=[2, 2, 2])
    cpd_u2 = TabularCPD('U2',
                        7,
                        np.array([[0, 0, 0, 0, 0, 0, 0, 0],
                                  [0, 0, 0, 0, 1, 0, 1, 0],
                                  [0, 1, 1, 1, 0, 0, 0, 0],
                                  [1, 0, 0, 0, 0, 0, 0, 1],
                                  [0, 0, 0, 0, 0, 1, 0, 0],
                                  [0, 0, 0, 0, 0, 0, 0, 0],
                                  [0, 0, 0, 0, 0, 0, 0, 0]]),
                        evidence=['D1', 'D2', 'D3'],
                        evidence_card=[2, 2, 2])
    cpd_u3 = TabularCPD('U3',
                        7,
                        np.array([[0, 0, 0, 0, 0, 0, 0, 1],
                                  [0, 0, 1, 0, 0, 0, 1, 0],
                                  [0, 0, 0, 0, 0, 0, 0, 0],
                                  [0, 0, 0, 0, 1, 0, 0, 0],
                                  [0, 1, 0, 0, 0, 0, 0, 0],
                                  [0, 0, 0, 1, 0, 0, 0, 0],
                                  [1, 0, 0, 0, 0, 1, 0, 0]]),
                        evidence=['D1', 'D2', 'D3'],
                        evidence_card=[2, 2, 2])

    macid.add_cpds(cpd_d1, cpd_d2, cpd_d3, cpd_u1, cpd_u2, cpd_u3)

    return macid