Example #1
0
 def test_multidigraph_ignore(self):
     G = nx.MultiDiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation='ignore'))
     x_ = [(0, 1, 0, FORWARD), (1, 0, 0, FORWARD)]  # or (1, 0, 1, 1)
     assert_equal(x[0], x_[0])
     assert_equal(x[1][:2], x_[1][:2])
     assert_equal(x[1][3], x_[1][3])
Example #2
0
 def test_multigraph(self):
     G = nx.MultiGraph(self.edges)
     x = list(find_cycle(G, self.nodes))
     x_ = [(0, 1, 0), (1, 0, 1)]  # or (1, 0, 2)
     # Hash randomization...could be any edge.
     assert_equal(x[0], x_[0])
     assert_equal(x[1][:2], x_[1][:2])
 def test_multigraph(self):
     G = nx.MultiGraph(self.edges)
     x = list(find_cycle(G, self.nodes))
     x_ = [(0, 1, 0), (1, 0, 1)]  # or (1, 0, 2)
     # Hash randomization...could be any edge.
     assert_equal(x[0], x_[0])
     assert_equal(x[1][:2], x_[1][:2])
 def test_multidigraph_ignore(self):
     G = nx.MultiDiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation='ignore'))
     x_ = [(0, 1, 0, FORWARD), (1, 0, 0, FORWARD)]  # or (1, 0, 1, 1)
     assert_equal(x[0], x_[0])
     assert_equal(x[1][:2], x_[1][:2])
     assert_equal(x[1][3], x_[1][3])
Example #5
0
 def test_dag(self):
     G = nx.DiGraph([(0, 1), (0, 2), (1, 2)])
     pytest.raises(
         nx.exception.NetworkXNoCycle, find_cycle, G, orientation="original"
     )
     x = list(find_cycle(G, orientation="ignore"))
     assert x == [(0, 1, FORWARD), (1, 2, FORWARD), (0, 2, REVERSE)]
Example #6
0
 def test_multidigraph_ignore(self):
     G = nx.MultiDiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation="ignore"))
     x_ = [(0, 1, 0, FORWARD), (1, 0, 0, FORWARD)]  # or (1, 0, 1, 1)
     assert x[0] == x_[0]
     assert x[1][:2] == x_[1][:2]
     assert x[1][3] == x_[1][3]
Example #7
0
def resolve(edges, order):

    graph = DiGraph()
    graph.add_edges_from(edges)

    removed = []
    for node in order:

        try:
            find_cycle(graph)
            graph.remove_node(node)
            removed.append(node)
        except NetworkXNoCycle:
            break

    return RESOLVE_RESULT([*graph.node, *removed], removed,
                          sum(COSTS[key] for key in removed))
 def test_dag(self):
     G = nx.DiGraph([(0, 1), (0, 2), (1, 2)])
     assert_raises(nx.exception.NetworkXNoCycle,
                   find_cycle,
                   G,
                   orientation='original')
     x = list(find_cycle(G, orientation='ignore'))
     assert_equal(x, [(0, 1, FORWARD), (1, 2, FORWARD), (0, 2, REVERSE)])
Example #9
0
def _ancestors_in_topological_sort_order(module_name):
    ancestral_module_names = ancestors(_dependency_graph, module_name)
    subgraph = _dependency_graph.subgraph(ancestral_module_names)
    try:
        sorted_nodes = topological_sort(subgraph)
    except nx.NetworkXUnfeasible as ex:
        try:
            cycle = find_cycle(subgraph)
        except Exception as ex:
            log_error(f'find_cycle: error: {ex.__class__.__name__}({ex})')
        else:
            log_error(f'cycle: {cycle}')
        finally:
            raise
    else:
        return list(reversed(list(sorted_nodes)))
Example #10
0
def _build_diagram(
    g_sel,
    avl_att,
    tgt_att=None,
    imputation_nodes=True,
    merge_nodes=False,
    prune=False,
    test=False,
):
    if imputation_nodes:
        q_desc = np.where(avl_att)[0]
        for g in g_sel:
            add_imputation_nodes(g, q_desc)

    q_diagram = compose_all(g_sel)

    if merge_nodes:
        add_merge_nodes(q_diagram)

    if prune:
        assert tgt_att is not None, "If you prune, you need to provide tgt_att"
        q_targ = np.where(tgt_att)[0]
        _prune(q_diagram, q_targ)

    if test:
        try:
            cycles = find_cycle(q_diagram)
            msg = """
            Found a cycle!
            Cycle was: {}
            """.format(cycles)
            raise ValueError(msg)
        except NetworkXNoCycle:
            pass

    q_diagram.graph["desc_ids"] = get_ids(q_diagram, kind="desc")
    q_diagram.graph["targ_ids"] = get_ids(q_diagram, kind="targ")

    return q_diagram
Example #11
0
 def test_multidigraph_ignore2(self):
     # Loop traversed an edge while ignoring its orientation.
     G = nx.MultiDiGraph([(0, 1), (1, 2), (1, 2)])
     x = list(find_cycle(G, [0, 1, 2], orientation='ignore'))
     x_ = [(1, 2, 0, FORWARD), (1, 2, 1, REVERSE)]
     assert_equal(x, x_)
Example #12
0
 def test_graph_orientation_none(self):
     G = nx.Graph(self.edges)
     G.add_edge(2, 0)
     x = list(find_cycle(G, self.nodes, orientation=None))
     x_ = [(0, 1), (1, 2), (2, 0)]
     assert_equal(x, x_)
Example #13
0
 def test_digraph_ignore(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation='ignore'))
     x_ = [(0, 1, FORWARD), (1, 0, FORWARD)]
     assert_equal(x, x_)
Example #14
0
 def test_graph_cycle(self):
     G = nx.Graph(self.edges)
     G.add_edge(2, 0)
     x = list(find_cycle(G, self.nodes))
     x_ = [(0, 1), (1, 2), (2, 0)]
     assert x == x_
 def test_multidigraph_ignore2(self):
     # Loop traversed an edge while ignoring its orientation.
     G = nx.MultiDiGraph([(0, 1), (1, 2), (1, 2)])
     x = list(find_cycle(G, [0, 1, 2], orientation='ignore'))
     x_ = [(1, 2, 0, FORWARD), (1, 2, 1, REVERSE)]
     assert_equal(x, x_)
 def test_digraph_ignore(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation='ignore'))
     x_ = [(0, 1, FORWARD), (1, 0, FORWARD)]
     assert_equal(x, x_)
Example #17
0
 def test_graph_cycle(self):
     G = nx.Graph(self.edges)
     G.add_edge(2, 0)
     x = list(find_cycle(G, self.nodes))
     x_ = [(0, 1), (1, 2), (2, 0)]
     assert_equal(x, x_)
Example #18
0
 def test_digraph_reverse(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation="reverse"))
     x_ = [(1, 0, REVERSE), (0, 1, REVERSE)]
     assert x == x_
Example #19
0
 def test_digraph_orientation_original(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation="original"))
     x_ = [(0, 1, FORWARD), (1, 0, FORWARD)]
     assert x == x_
Example #20
0
 def test_digraph_orientation_none(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation=None))
     x_ = [(0, 1), (1, 0)]
     assert x == x_
Example #21
0
 def test_graph_orientation_original(self):
     G = nx.Graph(self.edges)
     G.add_edge(2, 0)
     x = list(find_cycle(G, self.nodes, orientation="original"))
     x_ = [(0, 1, FORWARD), (1, 2, FORWARD), (2, 0, FORWARD)]
     assert x == x_
Example #22
0
 def test_graph_orientation_none(self):
     G = nx.Graph(self.edges)
     G.add_edge(2, 0)
     x = list(find_cycle(G, self.nodes, orientation=None))
     x_ = [(0, 1), (1, 2), (2, 0)]
     assert x == x_
Example #23
0
 def test_dag(self):
     G = nx.DiGraph([(0, 1), (0, 2), (1, 2)])
     assert_raises(nx.exception.NetworkXNoCycle,
                   find_cycle, G, orientation='original')
     x = list(find_cycle(G, orientation='ignore'))
     assert_equal(x, [(0, 1, FORWARD), (1, 2, FORWARD), (0, 2, REVERSE)])
 def test_digraph(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes))
     x_ = [(0, 1), (1, 0)]
     assert_equal(x, x_)
Example #25
0
 def test_digraph_orientation_none(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation=None))
     x_ = [(0, 1), (1, 0)]
     assert_equal(x, x_)
 def test_multidigraph(self):
     G = nx.MultiDiGraph(self.edges)
     x = list(find_cycle(G, self.nodes))
     x_ = [(0, 1, 0), (1, 0, 0)]  # (1, 0, 1)
     assert_equal(x[0], x_[0])
     assert_equal(x[1][:2], x_[1][:2])
Example #27
0
 def test_digraph(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes))
     x_ = [(0, 1), (1, 0)]
     assert_equal(x, x_)
Example #28
0
def find_po_and_prop1_allocation(Gx: bipartite,
                                 fpo_alloc: FractionalAllocation,
                                 items: Bundle) -> FractionalAllocation:
    """
    This function implements the algorithm starting at step 3.

    INPUT:
    * Gx - An acyclic consumption graph: a bipartite graph describing which agent consumes which object. 
    * fpo_alloc: A fractionally-Pareto-optimal fractional allocation corresponding to the given consumption graph.
        NOTE: Converting a general allocation to an fPO allocation with an acyclic consumption graph should be done by a different algorithm in a previous step (step 2).
    * items: Set of items to allocate.

    OUTPUT:
    * Fractional allocation which is an integral allocation (since all fractions are 0.0 or 1.0),
    which is PO and PROP1

    First example:
    Case 1: Only one player(must get everything),Items with positive utility.
    >>> agent1 = AdditiveAgent({"x": 1, "y": 2, "z": 4}, name="agent1")
    >>> list_of_agents_for_func = [agent1]
    >>> items_for_func ={'x','y','z'}
    >>> alloc_y_for_func = FractionalAllocation(list_of_agents_for_func, [{'x':1.0,'y':1.0, 'z':1.0}])
    >>> G = nx.Graph()
    >>> G.add_node(agent1)
    >>> G.add_node('x')
    >>> G.add_node('y')
    >>> G.add_node('z')
    >>> G.add_edge(agent1, 'x')
    >>> G.add_edge(agent1, 'y')
    >>> G.add_edge(agent1, 'z')
    >>> alloc = find_po_and_prop1_allocation(G, alloc_y_for_func, items_for_func)
    >>> print(alloc)
    agent1's bundle: {x,y,z},  value: 7.0
    <BLANKLINE>
    >>> alloc.is_complete_allocation()
    True

    Case 2: Only one player(must get everything),Items with negative utility.
    >>> agent1= AdditiveAgent({"x": -1, "y": -2, "z": -4}, name="agent1")
    >>> list_of_agents_for_func = [agent1]
    >>> items_for_func ={'x','y','z'}
    >>> alloc_y_for_func = FractionalAllocation(list_of_agents_for_func, [{'x':1.0,'y':1.0, 'z':1.0}])
    >>> G = nx.Graph()
    >>> G.add_node(agent1)
    >>> G.add_node('x')
    >>> G.add_node('y')
    >>> G.add_node('z')
    >>> G.add_edge(agent1, 'x')
    >>> G.add_edge(agent1, 'y')
    >>> G.add_edge(agent1, 'z')
    >>> alloc = find_po_and_prop1_allocation(G, alloc_y_for_func, items_for_func)
    >>> print(alloc)
    agent1's bundle: {x,y,z},  value: -7.0
    <BLANKLINE>
    >>> alloc.is_complete_allocation()
    True

    Case 3: Only one player(must get everything),Items with negative and positive utilitys.
    >>> agent1 = AdditiveAgent({"x": -1, "y": 2, "z": -4}, name="agent1")
    >>> list_of_agents_for_func = [agent1]
    >>> items_for_func ={'x','y','z'}
    >>> alloc_y_for_func = FractionalAllocation(list_of_agents_for_func, [{'x':1.0,'y':1.0, 'z':1.0}])
    >>> G = nx.Graph()
    >>> G.add_node(agent1)
    >>> G.add_node('x')
    >>> G.add_node('y')
    >>> G.add_node('z')
    >>> G.add_edge(agent1, 'x')
    >>> G.add_edge(agent1, 'y')
    >>> G.add_edge(agent1, 'z')
    >>> alloc = find_po_and_prop1_allocation(G, alloc_y_for_func, items_for_func)
    >>> print(alloc)
    agent1's bundle: {x,y,z},  value: -3.0
    <BLANKLINE>
    >>> alloc.is_complete_allocation()
    True

    Second example:
    (example 3 in the second part of the work)
    >>> agent1 = AdditiveAgent({"a": 10, "b": 100, "c": 80, "d": -100}, name="agent1")
    >>> agent2 = AdditiveAgent({"a": 20, "b": 100, "c": -40, "d": 10}, name="agent2")
    >>> G = nx.Graph()
    >>> all_agents = [agent1, agent2]
    >>> all_items = {'a', 'b', 'c', 'd'}
    >>> G.add_nodes_from(all_agents + list(all_items))
    >>> G.add_edges_from([[agent1, 'b'], [agent1, 'c'], [agent2, 'a'], [agent2, 'b'], [agent2, 'd']])
    >>> alloc_y_for_func = FractionalAllocation(all_agents, [{'a':0.0,'b':0.3,'c':1.0,'d':0.0},{'a':1.0,'b':0.7,'c':0.0,'d':1.0}])
    >>> alloc = find_po_and_prop1_allocation(G, alloc_y_for_func, all_items)
    >>> print(alloc)
    agent1's bundle: {b,c},  value: 180.0
    agent2's bundle: {a,d},  value: 30.0
    <BLANKLINE>
    >>> alloc.is_complete_allocation()
    True


    Third example:
    Case 1:
    (example 5 in the second part of the work)
    >>> agent1= AdditiveAgent({"a": 100, "b": 10, "c": 50, "d": 100 ,"e": 70,"f": 100, "g": 300, "h": 40, "i": 30}, name="agent1")
    >>> agent2= AdditiveAgent({"a": 20, "b": 20, "c": 40, "d": 90 ,"e": 90,"f": 100, "g": 30, "h": 80, "i": 90}, name="agent2")
    >>> agent3= AdditiveAgent({"a": 10, "b": 30, "c": 30, "d": 40 ,"e": 180,"f": 100, "g": 300, "h": 20, "i": 90}, name="agent3")
    >>> agent4= AdditiveAgent({"a": 200, "b": 40, "c": 20, "d": 80 ,"e": 300,"f": 100, "g": 30, "h": 60, "i": 180}, name="agent4")
    >>> agent5= AdditiveAgent({"a": 50, "b": 50, "c": 10, "d": 60 ,"e": 90,"f": 100, "g": 300, "h": 120, "i": 180}, name="agent5")
    >>> list_of_agents_for_func = [agent1, agent2, agent3, agent4, agent5]
    >>> items_for_func = {'a','b','c','d','e','f','g','h','i'}
    >>> alloc_y_for_func = FractionalAllocation(list_of_agents_for_func, [{'a':0.0,'b':0.0,'c':1.0,'d':1.0,'e':0.0,'f':0.2,'g':0.0,'h':0.0,'i':0.0},{'a':0.0,'b':0.0,'c':0.0,'d':0.0,'e':0.8,'f':0.4,'g':0.0,'h':0.0,'i':0.0},{'a':0.0,'b':0.0,'c':0.0,'d':0.0,'e':0.0,'f':0.2,'g':1.0,'h':0.0,'i':0.0},{'a':1.0,'b':0.0,'c':0.0,'d':0.0,'e':0.2,'f':0.0,'g':0.0,'h':0.0,'i':0.0},{'a':0.0,'b':1.0,'c':0.0,'d':0.0,'e':0.0,'f':0.2,'g':0.0,'h':1.0,'i':1.0}])
    >>> G = nx.Graph()
    >>> G.add_node(agent1)
    >>> G.add_node(agent2)
    >>> G.add_node(agent3)
    >>> G.add_node(agent4)
    >>> G.add_node(agent5)
    >>> G.add_node('a')
    >>> G.add_node('b')
    >>> G.add_node('c')
    >>> G.add_node('d')
    >>> G.add_node('e')
    >>> G.add_node('f')
    >>> G.add_node('g')
    >>> G.add_node('h')
    >>> G.add_node('i')
    >>> G.add_edge(agent1, 'c')
    >>> G.add_edge(agent1, 'd')
    >>> G.add_edge(agent1, 'f')
    >>> G.add_edge(agent2, 'e')
    >>> G.add_edge(agent2, 'f')
    >>> G.add_edge(agent3, 'f')
    >>> G.add_edge(agent3, 'g')
    >>> G.add_edge(agent4, 'a')
    >>> G.add_edge(agent4, 'e')
    >>> G.add_edge(agent5, 'b')
    >>> G.add_edge(agent5, 'h')
    >>> G.add_edge(agent5, 'i')
    >>> G.add_edge(agent5, 'f')
    >>> alloc = find_po_and_prop1_allocation(G, alloc_y_for_func, items_for_func)
    >>> # print(alloc)  # Below is ONE possible output.
    # agent1's bundle: {c,d,f},  value: 250.0
    # agent2's bundle: {e},  value: 90.0
    # agent3's bundle: {g},  value: 300.0
    # agent4's bundle: {a},  value: 200.0
    # agent5's bundle: {b,h,i},  value: 350.0
    # <BLANKLINE>
    >>> alloc.is_complete_allocation()
    True

    Case 2:
    (example 4 in the second part of the work)
    >>> agent1= AdditiveAgent({"a": -100, "b": -10, "c": -50, "d":-100 ,"e": -70,"f": -100, "g": -200, "h": -40, "i": -30}, name="agent1")
    >>> agent2= AdditiveAgent({"a": -20, "b": -20, "c": -40, "d": -90 ,"e": -90,"f": -100, "g": -100, "h": -80, "i": -90}, name="agent2")
    >>> agent3= AdditiveAgent({"a": -10, "b": -30, "c": -30, "d": -40 ,"e": -180,"f": -100, "g": -200, "h": -20, "i": -90}, name="agent3")
    >>> agent4= AdditiveAgent({"a": -200, "b": -40, "c": -20, "d": -80 ,"e": -300,"f": -100, "g": -100, "h": -60, "i": -180}, name="agent4")
    >>> agent5= AdditiveAgent({"a": -50, "b": -50, "c": -10, "d": -60 ,"e": -90,"f": -100, "g": -200, "h": -120, "i": -180}, name="agent5")
    >>> list_of_agents_for_func = [agent1, agent2, agent3, agent4, agent5]
    >>> items_for_func = {'a','b','c','d','e','f','g','h','i'}
    >>> alloc_y_for_func = FractionalAllocation(list_of_agents_for_func, [{'a':0.0,'b':1.0,'c':0.0,'d':0.0,'e':1.0,'f':0.2,'g':0.0,'h':0.0,'i':1.0},{'a':0.0,'b':0.0,'c':0.0,'d':0.0,'e':0.0,'f':0.2,'g':0.0,'h':0.0,'i':0.0},{'a':1.0,'b':0.0,'c':0.0,'d':1.0,'e':0.0,'f':0.2,'g':0.0,'h':1.0,'i':0.0},{'a':0.0,'b':0.0,'c':0.0,'d':0.0,'e':0.0,'f':0.2,'g':1.0,'h':0.0,'i':0.0},{'a':0.0,'b':0.0,'c':1.0,'d':0.0,'e':0.0,'f':0.2,'g':0.0,'h':0.0,'i':0.0}])
    >>> G = nx.Graph()
    >>> G.add_node(agent1)
    >>> G.add_node(agent2)
    >>> G.add_node(agent3)
    >>> G.add_node(agent4)
    >>> G.add_node(agent5)
    >>> G.add_node('a')
    >>> G.add_node('b')
    >>> G.add_node('c')
    >>> G.add_node('d')
    >>> G.add_node('e')
    >>> G.add_node('f')
    >>> G.add_node('g')
    >>> G.add_node('h')
    >>> G.add_node('i')
    >>> G.add_edge(agent1, 'b')
    >>> G.add_edge(agent1, 'e')
    >>> G.add_edge(agent1, 'f')
    >>> G.add_edge(agent1, 'i')
    >>> G.add_edge(agent2, 'f')
    >>> G.add_edge(agent3, 'a')
    >>> G.add_edge(agent3, 'd')
    >>> G.add_edge(agent3, 'f')
    >>> G.add_edge(agent3, 'h')
    >>> G.add_edge(agent4, 'g')
    >>> G.add_edge(agent4, 'f')
    >>> G.add_edge(agent5, 'c')
    >>> G.add_edge(agent5, 'f')
    >>> alloc = find_po_and_prop1_allocation(G, alloc_y_for_func, items_for_func)
    >>> print(alloc) #in my example I gave f to agent1, but the algorithm gave it to agent2
    agent1's bundle: {b,e,i},  value: -110.0
    agent2's bundle: {f},  value: -100.0
    agent3's bundle: {a,d,h},  value: -70.0
    agent4's bundle: {g},  value: -100.0
    agent5's bundle: {c},  value: -10.0
    <BLANKLINE>
    >>> alloc.is_complete_allocation()
    True

    Case 3:
    (example 6 in the second part of the work)
    >>> agent1= AdditiveAgent({"a": -100, "b": 10, "c": 50, "d": -100 ,"e": 70,"f": 300, "g": -300, "h": -40, "i": 30}, name="agent1")
    >>> agent2= AdditiveAgent({"a": 20, "b": 20, "c": -40, "d": 90 ,"e": -90,"f": -100, "g": 300, "h": 80, "i": 90}, name="agent2")
    >>> agent3= AdditiveAgent({"a": 10, "b": -30, "c": 30, "d": 40 ,"e": 180,"f": 300, "g": 30, "h": 20, "i": -90}, name="agent3")
    >>> agent4= AdditiveAgent({"a": -200, "b": 40, "c": -20, "d": 80 ,"e": -300,"f": 300, "g": 300, "h": 60, "i": -180}, name="agent4")
    >>> agent5= AdditiveAgent({"a": 50, "b": 50, "c": 10, "d": 60 ,"e": 90,"f": 100, "g": 300, "h": -120, "i": 180}, name="agent5")
    >>> list_of_agents_for_func = [agent1, agent2, agent3, agent4, agent5]
    >>> items_for_func = {'a','b','c','d','e','f','g','h','i'}
    >>> alloc_y_for_func = FractionalAllocation(list_of_agents_for_func, [{'a':0.0,'b':0.0,'c':1.0,'d':0.0,'e':0.0,'f':0.4,'g':0.0,'h':0.0,'i':0.0},{'a':0.0,'b':0.0,'c':0.0,'d':1.0,'e':0.0,'f':0.0,'g':0.5,'h':1.0,'i':0.0},{'a':0.0,'b':0.0,'c':0.0,'d':0.0,'e':1.0,'f':0.4,'g':0.0,'h':0.0,'i':0.0},{'a':0.0,'b':0.0,'c':0.0,'d':0.0,'e':0.0,'f':0.0,'g':0.5,'h':0.0,'i':0.0},{'a':1.0,'b':1.0,'c':0.0,'d':0.0,'e':0.0,'f':0.2,'g':0.0,'h':0.0,'i':1.0}])
    >>> G = nx.Graph()
    >>> G.add_node(agent1)
    >>> G.add_node(agent2)
    >>> G.add_node(agent3)
    >>> G.add_node(agent4)
    >>> G.add_node(agent5)
    >>> G.add_node('a')
    >>> G.add_node('b')
    >>> G.add_node('c')
    >>> G.add_node('d')
    >>> G.add_node('e')
    >>> G.add_node('f')
    >>> G.add_node('g')
    >>> G.add_node('h')
    >>> G.add_node('i')
    >>> G.add_edge(agent1, 'c')
    >>> G.add_edge(agent1, 'f')
    >>> G.add_edge(agent2, 'd')
    >>> G.add_edge(agent2, 'h')
    >>> G.add_edge(agent2, 'g')
    >>> G.add_edge(agent3, 'e')
    >>> G.add_edge(agent3, 'f')
    >>> G.add_edge(agent4, 'g')
    >>> G.add_edge(agent5, 'a')
    >>> G.add_edge(agent5, 'b')
    >>> G.add_edge(agent5, 'i')
    >>> G.add_edge(agent5, 'f')
    >>> alloc = find_po_and_prop1_allocation(G, alloc_y_for_func, items_for_func)
    >>> print(alloc)
    agent1's bundle: {c,f},  value: 350.0
    agent2's bundle: {d,g,h},  value: 470.0
    agent3's bundle: {e},  value: 180.0
    agent4's bundle: {},  value: 0.0
    agent5's bundle: {a,b,i},  value: 280.0
    <BLANKLINE>
    >>> alloc.is_complete_allocation()
    True

    Fourth example: A general situation, in which the new division is indeed a pareto improvement of the original division
    (example 7 in the second part of the work)
    >>> agent1= AdditiveAgent({"a": -100, "b": 10, "c": 50, "d": -100 ,"e": 70,"f": 100, "g": -300, "h": -40, "i": 30}, name="agent1")
    >>> agent2= AdditiveAgent({"a": 20, "b": 20, "c": -40, "d": 90 ,"e": -90,"f": -100, "g": 30, "h": 80, "i": 90}, name="agent2")
    >>> agent3= AdditiveAgent({"a": 10, "b": -30, "c": 30, "d": 40 ,"e": 180,"f": 100, "g": 300, "h": 20, "i": -90}, name="agent3")
    >>> agent4= AdditiveAgent({"a": -200, "b": 40, "c": -20, "d": 80 ,"e": -300,"f": 100, "g": 30, "h": 60, "i": -180}, name="agent4")
    >>> agent5= AdditiveAgent({"a": 50, "b": 50, "c": 10, "d": 60 ,"e": 90,"f": -100, "g": 300, "h": -120, "i": 180}, name="agent5")
    >>> list_of_agents_for_func = [agent1, agent2, agent3, agent4, agent5]
    >>> items_for_func = {'a','b','c','d','e','f','g','h','i'}
    >>> alloc_y_for_func = FractionalAllocation(list_of_agents_for_func, [{'a':0.0,'b':1.0,'c':0.0,'d':0.0,'e':1.0,'f':1.0,'g':0.0,'h':0.0,'i':0.4},{'a':0.0,'b':0.0,'c':0.0,'d':1.0,'e':0.0,'f':0.0,'g':0.0,'h':1.0,'i':0.0},{'a':0.0,'b':0.0,'c':1.0,'d':0.0,'e':0.0,'f':0,'g':1.0,'h':0.0,'i':0.0},{'a':0.0,'b':0.0,'c':0.0,'d':0.0,'e':0.0,'f':0.0,'g':0.0,'h':0.0,'i':0.0},{'a':1.0,'b':0.0,'c':0.0,'d':0.0,'e':0.0,'f':0.0,'g':0.0,'h':0.0,'i':0.6}])
    >>> G = nx.Graph()
    >>> G.add_node(agent1)
    >>> G.add_node(agent2)
    >>> G.add_node(agent3)
    >>> G.add_node(agent4)
    >>> G.add_node(agent5)
    >>> G.add_node('a')
    >>> G.add_node('b')
    >>> G.add_node('c')
    >>> G.add_node('d')
    >>> G.add_node('e')
    >>> G.add_node('f')
    >>> G.add_node('g')
    >>> G.add_node('h')
    >>> G.add_node('i')
    >>> G.add_edge(agent1, 'e')
    >>> G.add_edge(agent1, 'b')
    >>> G.add_edge(agent1, 'f')
    >>> G.add_edge(agent1, 'i')
    >>> G.add_edge(agent2, 'd')
    >>> G.add_edge(agent2, 'h')
    >>> G.add_edge(agent3, 'c')
    >>> G.add_edge(agent3, 'g')
    >>> G.add_edge(agent5, 'a')
    >>> G.add_edge(agent5, 'i')
    >>> alloc = find_po_and_prop1_allocation(G, alloc_y_for_func, items_for_func)
    >>> print(alloc)
    agent1's bundle: {b,e,f,i},  value: 210.0
    agent2's bundle: {d,h},  value: 170.0
    agent3's bundle: {c,g},  value: 330.0
    agent4's bundle: {},  value: 0.0
    agent5's bundle: {a},  value: 50.0
    <BLANKLINE>
    >>> alloc.is_complete_allocation()
    True

    """
    # Check input
    try:
        find_cycle(Gx)
        raise Exception("There are cycles in the given graph")
    except nx.NetworkXNoCycle:
        pass

    #Algorithm
    Q = queue.Queue()
    while Gx.number_of_edges() > len(
            items
    ):  #If each item belongs to exactly one agent, the number of edges in the graph will necessarily be the same as the number of items
        agent = find_agent_sharing_item(Gx, items)
        Q.put(
            agent
        )  #Because of the deletion of edges in the graph we will never put again an agent who has previously entered Q
        while len(Q.queue) != 0:  #If the queue is not empty
            curr_agent = Q.get(0)  #Get the first agent from the queue
            dict_of_items_curr_agent_share = get_dict_of_items_curr_agent_share(
                curr_agent, fpo_alloc)
            add_neighbors_to_Q(Q, dict_of_items_curr_agent_share)
            if dict_of_items_curr_agent_share != {}:  #Check that the agent is actually sharing items
                for item, agents in dict_of_items_curr_agent_share.items():
                    if curr_agent.value(item) > 0:  #If a positive utility
                        update_fpo_alloc_and_Gx(
                            curr_agent, item, agents, fpo_alloc,
                            Gx)  #Gave to the curr_agent the item
                    else:  #If a negative utility
                        other_agent = agents[0]  #Gave another agent the item
                        agents.remove(other_agent)
                        agents.append(curr_agent)
                        update_fpo_alloc_and_Gx(other_agent, item, agents,
                                                fpo_alloc, Gx)
    return fpo_alloc
Example #29
0
 def test_graph_orientation_original(self):
     G = nx.Graph(self.edges)
     G.add_edge(2, 0)
     x = list(find_cycle(G, self.nodes, orientation='original'))
     x_ = [(0, 1, FORWARD), (1, 2, FORWARD), (2, 0, FORWARD)]
     assert_equal(x, x_)
Example #30
0
 def test_multidigraph(self):
     G = nx.MultiDiGraph(self.edges)
     x = list(find_cycle(G, self.nodes))
     x_ = [(0, 1, 0), (1, 0, 0)]  # (1, 0, 1)
     assert_equal(x[0], x_[0])
     assert_equal(x[1][:2], x_[1][:2])
Example #31
0
 def test_digraph_reverse(self):
     G = nx.DiGraph(self.edges)
     x = list(find_cycle(G, self.nodes, orientation='reverse'))
     x_ = [(1, 0, REVERSE), (0, 1, REVERSE)]
     assert_equal(x, x_)