Пример #1
0
def find_matchings(graph, n=5):
    best_matching = nx.max_weight_matching(graph, True)
    matchings = [best_matching]

    for u, v in best_matching.items():
        if v <= u:
            continue
        smaller_graph = nx.Graph(graph)
        smaller_graph.remove_edge(u, v)
        matching = nx.max_weight_matching(smaller_graph, True)
        if len(matching) > 0:
            matchings.append(matching)

    matching_costs = [(matching_cost(graph, matching), matching) for matching in matchings]
    matching_costs.sort()

    final_matchings = []
    last_cost = None
    for cost, matching in matching_costs:
        if cost == last_cost:
            continue
        last_cost = cost
        final_matchings.append((cost, matching))

    return final_matchings
Пример #2
0
def find_matchings(graph, n=5):
    """
    Find the n best matchings for a graph. The best matching is guaranteed to be the best, but the others are only
    estimates.
    """
    best_matching = nx.max_weight_matching(graph, True)
    matchings = [best_matching]
    for u, v in best_matching.items():
        if v <= u:
            continue
        # Remove the matching
        smaller_graph = nx.Graph(graph)
        smaller_graph.remove_edge(u, v)
        matching = nx.max_weight_matching(smaller_graph, True)
        matchings.append(matching)

    matching_costs = [(matching_cost(graph, matching), matching) for matching in matchings]
    matching_costs.sort()

    # HACK: The above code end up giving duplicates of the same path, even though the matching is different. To prevent
    # this, we remove matchings with the same cost.
    final_matchings = []
    last_cost = None
    for cost, matching in matching_costs:
        if cost == last_cost:
            continue
        last_cost = cost
        final_matchings.append((cost, matching))

    return final_matchings
Пример #3
0
    def test_s_blossom(self):
        """Create S-blossom and use it for augmentation:"""
        G = nx.Graph()
        G.add_weighted_edges_from([(1, 2, 8), (1, 3, 9), (2, 3, 10), (3, 4, 7)])
        assert_equal(nx.max_weight_matching(G), {1: 2, 2: 1, 3: 4, 4: 3})

        G.add_weighted_edges_from([(1, 6, 5), (4, 5, 6)])
        assert_equal(nx.max_weight_matching(G), {1: 6, 2: 3, 3: 2, 4: 5, 5: 4, 6: 1})
Пример #4
0
 def test_trivial5(self):
     """Path"""
     G = nx.Graph()
     G.add_edge(1, 2, weight=5)
     G.add_edge(2, 3, weight=11)
     G.add_edge(3, 4, weight=5)
     assert_equal(nx.max_weight_matching(G), {2: 3, 3: 2})
     assert_equal(nx.max_weight_matching(G, 1), {1: 2, 2: 1, 3: 4, 4: 3})
Пример #5
0
 def test_negative_weights(self):
     """Negative weights"""
     G = nx.Graph()
     G.add_edge(1, 2, weight=2)
     G.add_edge(1, 3, weight=-2)
     G.add_edge(2, 3, weight=1)
     G.add_edge(2, 4, weight=-1)
     G.add_edge(3, 4, weight=-6)
     assert_equal(nx.max_weight_matching(G), {1: 2, 2: 1})
     assert_equal(nx.max_weight_matching(G, 1), {1: 3, 2: 4, 3: 1, 4: 2})
Пример #6
0
 def test_s_t_blossom(self):
     """Create S-blossom, relabel as T-blossom, use for augmentation:"""
     G = nx.Graph()
     G.add_weighted_edges_from([(1, 2, 9), (1, 3, 8), (2, 3, 10), (1, 4, 5), (4, 5, 4), (1, 6, 3)])
     assert_equal(nx.max_weight_matching(G), {1: 6, 2: 3, 3: 2, 4: 5, 5: 4, 6: 1})
     G.add_edge(4, 5, weight=3)
     G.add_edge(1, 6, weight=4)
     assert_equal(nx.max_weight_matching(G), {1: 6, 2: 3, 3: 2, 4: 5, 5: 4, 6: 1})
     G.remove_edge(1, 6)
     G.add_edge(3, 6, weight=4)
     assert_equal(nx.max_weight_matching(G), {1: 2, 2: 1, 3: 6, 4: 5, 5: 4, 6: 3})
 def test050_linear(self):
     """ Multiple edges, linear. """
     g = nx.Graph()
     g.add_edges_from([(0,1),(1,2),(2,3),(3,4),(4,5),(5,6)])
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     self.assertEqual( len(mate1), len(mate2) )
Пример #8
0
 def test_nasty_blossom_augmenting(self):
     """Create nested blossom, relabel as T in more than one way"""
     # expand outer blossom such that inner blossom ends up on an
     # augmenting path:
     G = nx.Graph()
     G.add_weighted_edges_from(
         [
             (1, 2, 45),
             (1, 7, 45),
             (2, 3, 50),
             (3, 4, 45),
             (4, 5, 95),
             (4, 6, 94),
             (5, 6, 94),
             (6, 7, 50),
             (1, 8, 30),
             (3, 11, 35),
             (5, 9, 36),
             (7, 10, 26),
             (11, 12, 5),
         ]
     )
     assert_equal(
         nx.max_weight_matching(G), {1: 8, 2: 3, 3: 2, 4: 6, 5: 9, 6: 4, 7: 10, 8: 1, 9: 5, 10: 7, 11: 12, 12: 11}
     )
 def test030_twoedges(self):
     """ Two edges. """
     g = nx.Graph()
     g.add_edges_from([(0,1),(1,2)])
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     self.assertEqual( len(mate1), len(mate2) )
Пример #10
0
 def test020_singleedge(self):
     """ Single edge. """
     g = nx.Graph()
     g.add_edge(0,1)
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     self.assertEqual( len(mate1), len(mate2) )
Пример #11
0
 def test200_icosahedralgraph(self):
     """ Icosahedral graph. """
     g = nx.icosahedral_graph()
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     #td.showGraph(g, mate1, "test200_icosahedralgraph")
     self.assertEqual( len(mate1), len(mate2) )
Пример #12
0
 def test190_octahedralgraph(self):
     """ Octahedral graph. """
     g = nx.octahedral_graph()
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     td.showGraph(g, mate1, "test190_octahedralgraph")
     self.assertEqual( len(mate1), len(mate2) )
Пример #13
0
def weightedBipartite(matches, source, target):
    """
    Weighted Bipartite Matching Filter.
    Adapted from @WeiFoo's HDP codebase. See https://goo.gl/3AN2Qd.
    :param matches: Dictionary. Key is a pair (source, target). Value is p-value.
                    Obtained from KSAnalyzer
    :return: Best bipartite pair from the matches.
    """

    # Tags for source and target metrics.
    s_tag = "_s"
    t_tag = "_t"
    G = nx.Graph()
    for key, val in matches.iteritems():
        G.add_edge(key[0] + s_tag, key[1] + t_tag, weight=val)  # add suffix to make it unique
    result = nx.max_weight_matching(G)

    """
    We only want matched pairs with (S->T) and (T<-S). Remove singletons;
    i.e., only (S->T) or only (T->S)
    """
    pairs = []
    for attr_1, attr_2 in result.iteritems():
        if attr_1[:-2] in source and attr_2[:-2] in target:
            if (attr_1[:-2], attr_2[:-2]) not in pairs:
                pairs.append((attr_1[:-2], attr_2[:-2]))
        elif attr_1[:-2] in target and attr_2[:-2] in source:
            if (attr_2[:-2], attr_1[:-2]) not in pairs:
                pairs.append((attr_2[:-2], attr_1[:-2]))
    return pairs
def add_edges_for_euler(in_g, out_g):
  # optimize_dead_ends(in_g, out_g)
  temp_graph = graph_of_odd_nodes(in_g, out_g)
  print "DEBUG: Finished calculating shortest paths, now calculating matching..."
  matching = networkx.max_weight_matching(temp_graph, maxcardinality=True)
  print "DEBUG: Finished calculating matching, now adding new edges..."
  short_matching = {}
  for k in matching:
    if k not in short_matching and matching[k] not in short_matching:
      short_matching[k] = matching[k]
  for source in short_matching:
    add_artificial_edge(in_g, out_g, source, short_matching[source])
  #assert(networkx.is_connected(out_g))
  nodes = odd_nodes(out_g)
  num_odd_nodes = len(nodes)
  print "DEBUG: After all that we have %s odd-degree nodes." % num_odd_nodes
#  reachable_nodes = set(networkx.dfs_preorder_nodes(out_g, 105437194))
#  unreachable_nodes = set(out_g.nodes()) - reachable_nodes
#  for n in unreachable_nodes:
#    print "%s (%s) is unreachable." % (n, out_g.node[n]['pretty_name'])
#    path = networkx.dijkstra_path(in_g, 105437194,  n, weight='length')
#    print "Here is how we would get there on the original graph: %s" % [(pn, in_g.node[pn]['pretty_name']) for pn in path]
#    print "Here are the nodes we have purged from that path: %s" % [(pn, in_g.node[pn]['pretty_name']) for pn in path if pn not in out_g]
  if not networkx.is_connected(out_g):
    print "The graph is still not connected. Components: %s" % [[(n, in_g.node[n]['pretty_name']) for n in comp] for comp in networkx.connected_components(out_g)]
  return out_g
Пример #15
0
 def _pairs_from_graph(graph):
     mate = nx.max_weight_matching(graph, maxcardinality=True)
     # Extract pairs
     matched_players = []
     pairs = []
     for k, v in mate:
         if (k, v) not in pairs:
             pairs.append((k, v))
     # Sort pairs by wins
     for i, pair in enumerate(pairs):
         wins_zero = match_log.times_match_win(pair[0])
         wins_one = match_log.times_match_win(pair[1])
         if wins_zero < wins_one:
             pairs[i] = (pair[1], pair[0])
     # Format as matchups
     matchups = Matchups()
     for e in pairs:
         cost = cost_map[e[0]][e[1]]
         if e[0] == bye_dummy():
             assert(matchups.bye_player is None)
             matchups.bye_player = e[1]
         elif e[1] == bye_dummy():
             assert(matchups.bye_player is None)
             matchups.bye_player = e[0]
         else:
             num_0 = tournament.player_number_of_player(e[0])
             num_1 = tournament.player_number_of_player(e[1])
             player_a = e[0] if num_0 < num_1 else e[1]
             player_b = e[1] if player_a == e[0] else e[0]
             matchups.pairs.append(Matchup(player_a, player_b, cost))
     # Set bye player
     return matchups
Пример #16
0
 def test070_circle(self):
     """ Multiple edges, circle of even length. """
     g = nx.Graph()
     g.add_edges_from([(0,1),(1,2),(2,3),(3,4),(4,5),(5,0)])
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     self.assertEqual( len(mate1), len(mate2) )
 def test025_barbell_graph(self):
     """ Very small barbell graph. """
     g = nx.barbell_graph(9, 2)
     mate2 = nx.max_weight_matching( g, True )
     td.showGraph(g, mate2, "test025_barbell_graph_edmonds")
     mate1 = mv.max_cardinality_matching( g )
     self.assertEqual( len(mate1), len(mate2) )
 def test180_tutte_cage_graph(self):
     """ Tutte 12-cage graph. """
     g = nx.LCF_graph(126, [17, 27, -13, -59, -35, 35, -11, 13, -53\
                            , 53, -27, 21, 57, 11, -21, -57, 59, -17], 7)
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     self.assertEqual( len(mate1), len(mate2) )
 def test142_utility_graph(self):
     """ Larger utility graph from LCF notation. """
     g = nx.LCF_graph(60, [3, -3], 3)
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     td.showGraph(g, mate1, "test142_utility_graph")
     self.assertEqual( len(mate1), len(mate2) )
Пример #20
0
 def test_nested_s_blossom_relabel(self):
     """Create S-blossom, relabel as S, include in nested S-blossom:"""
     G = nx.Graph()
     G.add_weighted_edges_from(
         [(1, 2, 10), (1, 7, 10), (2, 3, 12), (3, 4, 20), (3, 5, 20), (4, 5, 25), (5, 6, 10), (6, 7, 10), (7, 8, 8)]
     )
     assert_equal(nx.max_weight_matching(G), {1: 2, 2: 1, 3: 4, 4: 3, 5: 6, 6: 5, 7: 8, 8: 7})
Пример #21
0
 def test090_singlebloom(self):
     """ Single bloom, two edge extensions, case 1. """
     g = nx.Graph()
     g.add_edges_from([(0,1),(1,2),(2,3),(3,4),(4,5),(5,1),(3,6)])
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     self.assertEqual( len(mate1), len(mate2) )
Пример #22
0
def match_candidates_and_characters(characters, candidates):
    matches = dict([(character, {}) for character in characters])

    # generate a graph that connects candidates and characters that match
    G = nx.Graph()
    G.add_nodes_from(characters, bipartite=0)
    G.add_nodes_from(candidates, bipartite=1)
    for character in characters:
        names = []
        for name in [character] + characters[character]:
            names.append(tuple(name.replace(',', ' ').replace('\'s ', ' \'s ').replace('s\'', 's \' ').split()))
        for cand in candidates:
            score = match_to_any_names(names, cand)
            if score > 0:
                G.add_edge(character, cand, weight=score)
        # if don't find any match, try the other direction
        # sparknote character name might be contained by some candidate names
        if len(matches[character]) == 0 and len(candidates) > 0:
            scores = [strict_fuzzy_match_reference(cand, names[0]) for cand in candidates]
            index, score = max(enumerate(scores), key=operator.itemgetter(1))
            if score > 0:
                G.add_edge(character, candidates[index], weight=score)

    max_matching = nx.max_weight_matching(G, maxcardinality=True)

    return (max_matching, G)
Пример #23
0
 def test160_petersengraph(self):
     """ Petersen graph. """
     g = nx.petersen_graph()
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     td.showGraph(g, mate1, "test160_petersengraph")
     self.assertEqual( len(mate1), len(mate2) )
Пример #24
0
 def test170_bullgraph(self):
     """ Bull graph. """
     g = nx.bull_graph()
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     #td.showGraph(g, mate1, "test170_bullgraph")
     self.assertEqual( len(mate1), len(mate2) )
Пример #25
0
Файл: hdp.py Проект: ai-se/HDP
def maximumWeighted(match, target_lst, source_lst):
  """
  using max_weighted_bipartite to select a group of matched metrics
  :param match : matched metrics with p values, key is the tuple of matched metrics
  :type match : dict
  :param target_lst : matched target metrics
  :type target_lst: list
  :param source_lst : matched source metcis
  :type source_lst: list
  :return : matched metrics as well as corresponding values
  :rtype: class o
  """
  value = 0
  attr_source, attr_target = [], []
  G = nx.Graph()
  for key, val in match.iteritems():
    G.add_edge(key[0] + "source", key[1] + "target", weight=val)  # add suffix to make it unique
  result = nx.max_weight_matching(G)
  for key, val in result.iteritems():  # in Results, (A:B) and (B:A) both exist
    if key[:-6] in source_lst and val[:-6] in target_lst \
        and (key[:-6], val[:-6]) in match : # get rid of (A:B) exists but (B:A) not
      if key[:-6] in attr_source and val[:-6] in attr_target and\
        attr_source.index(key[:-6]) == attr_target.index(val[:-6]):
        continue # this is (A:B) already in attr_source and attr_target
      attr_target.append(val[:-6])
      attr_source.append(key[:-6])
      value += match[(key[:-6], val[:-6])]
  # pdb.set_trace()
  return o(score=value, attr_source=attr_source, attr_target=attr_target)
Пример #26
0
 def test040_threeedges(self):
     """ Three edges, linear. """
     g = nx.Graph()
     g.add_edges_from([(0,1),(1,2),(2,3)])
     mate1 = mv.max_cardinality_matching( g )
     mate2 = nx.max_weight_matching( g, True )
     self.assertEqual( len(mate1), len(mate2) )
Пример #27
0
 def test_nested_s_blossom_relabel_expand(self):
     """Create nested S-blossom, relabel as T, expand:"""
     G = nx.Graph()
     G.add_weighted_edges_from(
         [(1, 2, 19), (1, 3, 20), (1, 8, 8), (2, 3, 25), (2, 4, 18), (3, 5, 18), (4, 5, 13), (4, 7, 7), (5, 6, 7)]
     )
     assert_equal(nx.max_weight_matching(G), {1: 8, 2: 3, 3: 2, 4: 7, 5: 6, 6: 5, 7: 4, 8: 1})
Пример #28
0
 def test_s_blossom_relabel_expand(self):
     """Create S-blossom, relabel as T, expand:"""
     G = nx.Graph()
     G.add_weighted_edges_from(
         [(1, 2, 23), (1, 5, 22), (1, 6, 15), (2, 3, 25), (3, 4, 22), (4, 5, 25), (4, 8, 14), (5, 7, 13)]
     )
     assert_equal(nx.max_weight_matching(G), {1: 6, 2: 3, 3: 2, 4: 8, 5: 7, 6: 1, 7: 5, 8: 4})
Пример #29
0
 def test_trivial4(self):
     """Small graph"""
     G = nx.Graph()
     G.add_edge('one', 'two', weight=10)
     G.add_edge('two', 'three', weight=11)
     assert_equal(nx.max_weight_matching(G),
                  {'three': 'two', 'two': 'three'})
Пример #30
0
 def test_trivial6(self):
     """Small graph with arbitrary weight attribute"""
     G = nx.Graph()
     G.add_edge('one', 'two', weight=10, abcd=11)
     G.add_edge('two', 'three', weight=11, abcd=10)
     assert_equal(nx.max_weight_matching(G, weight='abcd'),
                  {'one': 'two', 'two': 'one'})
Пример #31
0
def Get_Min_Weight_Matching(G):
    "Get_Min_Weight_Matching takes as input a complete weighted undirected networkx graph G, and returns a dictionary called matching, such that matching[v] == w if and only if the node v of G is matched with node w."
    nodes = G.nodes()
    # Get negative of distance matrix
    NegDistMat = -nx.to_numpy_matrix(G, weight='length')
    # Form new graph to obtain the matching
    Gnew = nx.from_numpy_matrix(NegDistMat, create_using=None)
    # Get min-weight matching
    matching = nx.max_weight_matching(Gnew, maxcardinality=True)
    # Return the matching
    matching_with_correct_nodes = {
        nodes[i]: nodes[matching[i]]
        for i in matching.keys()
    }

    return matching_with_correct_nodes
Пример #32
0
 def match(self):
     import networkx as nx
     G = nx.Graph()
     G.add_nodes_from(self.V)
     for e in self.E:
         e.match = False
         [v, w] = e.end
         G.add_edge(v, w)
     M = nx.max_weight_matching(G, maxcardinality=True)
     print(G)
     print(M)
     for (v, w) in M:
         e = self.get_edge(v, w)
         print("\nv:", v, "\nw:", w, "\ne:", e)
         if e is not None:
             e.match = True
Пример #33
0
def assignment_random(cands, pos, fitness, G):

    bi_edges, edge_weights, l = UW.update_weights_simple(pos, cands, fitness)
    bi_G = nx.Graph()
    bi_edges = [(u, v, w) for (u, v, w) in bi_edges if w != 0]
    bi_G.add_weighted_edges_from(bi_edges)
    final_matched = nx.max_weight_matching(bi_G)
    gender = nx.get_node_attributes(G, 'att')
    for (u, v) in final_matched:
        if u in pos:
            gender.update({u: cands[v]})
        else:
            gender.update({v: cands[u]})

    nx.set_node_attributes(G, gender, 'att')
    return G, final_matched
Пример #34
0
    def get_UA_pairs(UA, AC):
        """
        find the largest list of bonds in which all atom appears at most once

        :param UA:
        :param AC:
        :return:
        """
        bonds = ACParser.get_bonds(UA, AC)
        if len(bonds) == 0:
            return [()]

        G = nx.Graph()
        G.add_edges_from(bonds)
        UA_pairs = [list(nx.max_weight_matching(G))]
        return UA_pairs
Пример #35
0
def _get_ua_pairs(ua, ac):
    bonds = []

    for k, i in enumerate(ua):
        for j in ua[k + 1:]:
            if ac[i, j] == 1:
                bonds.append(tuple(sorted([i, j])))

    if len(bonds) == 0:
        return [()]

    G = nx.Graph()
    G.add_edges_from(bonds)
    ua_pairs = [list(nx.max_weight_matching(G))]

    return ua_pairs
Пример #36
0
	def get_max_weight_match(sim: np.ndarray) -> np.ndarray:
		if nx is None:
			raise ValueError("networkx must be installed to use match algorithm.")
		def permute(edge):
			if edge[0] < sim.shape[0]:
				return edge[0], edge[1] - sim.shape[0]
			else:
				return edge[1], edge[0] - sim.shape[0]
		G = from_biadjacency_matrix(csr_matrix(sim))
		matching = nx.max_weight_matching(G, maxcardinality=True)
		matching = [permute(x) for x in matching]
		matching = sorted(matching, key=lambda x: x[0])
		res_matrix = np.zeros_like(sim)
		for edge in matching:
			res_matrix[edge[0], edge[1]] = 1
		return res_matrix
Пример #37
0
    def matching(self, matching_graph, syndrome_key):
        """Return matches of minimum weight perfect matching (MWPM) on matching_graph.

        Args:
            matching_graph (nx.Graph): Graph to run MWPM.
            syndrome_key (char): Which X/Z syndrome subgraph these nodes are from.

        Returns:
            [(node, node),]: List of matchings found from MWPM
        """
        matches = nx.max_weight_matching(matching_graph, maxcardinality=True)
        filtered_matches = [
            (source, target) for (source, target) in matches
            if not (len(source) > 3 and len(target) > 3)
        ]  # remove 0 weighted matched edges between virtual syndrome nodes
        return filtered_matches
Пример #38
0
 def test_nested_s_blossom_relabel_expand(self):
     """Create nested S-blossom, relabel as T, expand:"""
     G = nx.Graph()
     G.add_weighted_edges_from([(1, 2, 19), (1, 3, 20), (1, 8, 8),
                                (2, 3, 25), (2, 4, 18), (3, 5, 18),
                                (4, 5, 13), (4, 7, 7), (5, 6, 7)])
     assert_equal(nx.max_weight_matching(G), {
         1: 8,
         2: 3,
         3: 2,
         4: 7,
         5: 6,
         6: 5,
         7: 4,
         8: 1
     })
Пример #39
0
 def test_nested_s_blossom_relabel(self):
     """Create S-blossom, relabel as S, include in nested S-blossom:"""
     G = nx.Graph()
     G.add_weighted_edges_from([(1, 2, 10), (1, 7, 10), (2, 3, 12),
                                (3, 4, 20), (3, 5, 20), (4, 5, 25),
                                (5, 6, 10), (6, 7, 10), (7, 8, 8)])
     assert_equal(nx.max_weight_matching(G), {
         1: 2,
         2: 1,
         3: 4,
         4: 3,
         5: 6,
         6: 5,
         7: 8,
         8: 7
     })
Пример #40
0
 def test_trivial6(self):
     """Small graph with arbitrary weight attribute"""
     G = nx.Graph()
     G.add_edge("one", "two", weight=10, abcd=11)
     G.add_edge("two", "three", weight=11, abcd=10)
     assert edges_equal(
         nx.max_weight_matching(G, weight="abcd"),
         matching_dict_to_set({
             "one": "two",
             "two": "one"
         }),
     )
     assert edges_equal(
         nx.min_weight_matching(G, weight="abcd"),
         matching_dict_to_set({"three": "two"}),
     )
Пример #41
0
 def test_s_blossom_relabel_expand(self):
     """Create S-blossom, relabel as T, expand:"""
     G = nx.Graph()
     G.add_weighted_edges_from([(1, 2, 23), (1, 5, 22), (1, 6, 15),
                                (2, 3, 25), (3, 4, 22), (4, 5, 25),
                                (4, 8, 14), (5, 7, 13)])
     assert_equal(nx.max_weight_matching(G), {
         1: 6,
         2: 3,
         3: 2,
         4: 8,
         5: 7,
         6: 1,
         7: 5,
         8: 4
     })
Пример #42
0
    def test_nested_s_blossom(self):
        """Create nested S-blossom, use for augmentation:"""

        G = nx.Graph()
        G.add_weighted_edges_from([(1, 2, 9), (1, 3, 9), (2, 3, 10), (2, 4, 8),
                                   (3, 5, 8), (4, 5, 10), (5, 6, 6)])
        assert_equal(
            nx.max_weight_matching(G),
            matching_dict_to_set({
                1: 3,
                2: 4,
                3: 1,
                4: 2,
                5: 6,
                6: 5
            }))
Пример #43
0
def maximal_matching(assembly_points_by_sources, acyclic=True, min_cw=0.0):
    assembly_points_by_sources = [
        ap for ap_list in assembly_points_by_sources.values() for ap in ap_list
    ]
    scaffold_edges = get_scaffold_edges(
        assembly_points=assembly_points_by_sources)
    unoriented_assembly_points = get_un_oriented_assembly_points(
        assembly_points=assembly_points_by_sources)

    assembly_edges_graph = MergedScaffoldAssemblyGraph()
    for ap in assembly_points_by_sources:
        for (u, v, weight) in ap.get_edges(sort=True, weight=True):
            assembly_edges_graph.add_edge(u, v, weight=weight)
    assembly_edges_graph.remove_edges_with_low_cw(cw_threshold=min_cw)
    matching = networkx.max_weight_matching(G=assembly_edges_graph.graph)
    cover_graph = networkx.Graph()
    cover_graph.add_edges_from(scaffold_edges)
    edges = matching
    for u, v in edges:
        cover_graph.add_edge(u,
                             v,
                             weight=assembly_edges_graph.graph[u][v]['weight'])
    # sanity check
    for vertex in cover_graph.nodes():
        assert cover_graph.degree[vertex] <= 2
    # checking for any issues with unoriented assembly points
    for assembly_point in unoriented_assembly_points:
        participating_edges = []
        for (u, v) in assembly_point.get_edges():
            if cover_graph.has_edge(u=u, v=v):
                participating_edges.append((u, v))
        assert len(participating_edges) <= 2  # this is just a sanity check
        if len(participating_edges) == 2:
            cover_graph.remove_edge(participating_edges[0][0],
                                    participating_edges[0][1])
    if acyclic:
        edges_to_delete = []
        for cc in networkx.connected_component_subgraphs(G=cover_graph,
                                                         copy=True):
            if networkx.number_of_nodes(cc) == networkx.number_of_edges(cc):
                assembly_edges = filter(lambda entry: "weight" in entry[2],
                                        cc.edges(data=True))
                edges_to_delete.append(
                    min(assembly_edges, key=lambda entry: entry[2]["weight"]))
        for u, v, data in edges_to_delete:
            cover_graph.remove_edge(u, v)
    return cover_graph
Пример #44
0
def swissPairings(tournament):
    """Returns a list of pairs of players for the next round of a match.

    Each player appears exactly once in the pairings. Each player is paired with
    another player with and equal or nearly-equal points record, that is, a player
    adjacent to him or her in the standings.
    For matching resuls Blossom algorithm is used and it is provided by "networkx"
    library (http://networkx.github.io/).

    Args:
      tournament: the id number of the tournament

    Returns:
      A list of tuples, each of which contains (id1, name1, id2, name2)
        id1: the first player's unique id
        name1: the first player's name
        id2: the second player's unique id
        name2: the second player's name
    """
    pairs = []
    players = playerTournamentStandings(tournament)
    players_number = countTournamentPlayers(tournament)
    if players_number % 2 != 0:
        players.append((None, None, 'Bye', 0, 0, 0, 0))
    # use Blossom algorighm to generrate best matches
    graph = nx.complete_graph(len(players))
    player_to_node = {players[key][1]: key for key, row in enumerate(players)}
    # exclude already played games
    for pair in playedMatches(tournament):
        for opponent in pair[1]:
            if graph.has_edge(player_to_node[pair[0]],
                              player_to_node[opponent]):
                graph.remove_edge(player_to_node[pair[0]],
                                  player_to_node[opponent])
    #add weight to each pair (edge)
    for n1, n2, data in graph.edges(data=True):
        weight = 1 + min(players[n1][6], players[n2][6])
        if players[n1][6] != players[n2][6]:
            weight += 1
        data['weight'] = weight
    # generate pairs
    for n1, n2 in nx.max_weight_matching(graph).iteritems():
        if n1 < n2: continue
        pairs.append(
            (players[n1][1], players[n1][2], players[n2][1], players[n2][2]))

    return pairs
Пример #45
0
 def matching(self,weights={}):
     
     if not weights:
         for pair in self.links:
             weights[pair] = random.random()
     
     G=nx.Graph()
     for pair in self.links:
         G.add_edge(self.links[pair][0],self.links[pair][1],weight=weights[pair])
         
     raw_pairs = nx.max_weight_matching(G, maxcardinality=True)
     
     pairs = []
     for pair in raw_pairs:
         pairs.append(list(pair))
     
     return pairs
Пример #46
0
 def test_gnp_random_against_networkx_with_negative_weight(self):
     for i in range(1024):
         with self.subTest(i=i):
             random.seed(i)
             rx_graph = retworkx.undirected_gnp_random_graph(10,
                                                             0.75,
                                                             seed=42 + i)
             for edge in rx_graph.edge_list():
                 rx_graph.update_edge(*edge, random.randint(-5000, 5000))
             nx_graph = networkx.Graph([(x[0], x[1], {
                 "weight": x[2]
             }) for x in rx_graph.weighted_edge_list()])
             nx_matches = networkx.max_weight_matching(nx_graph)
             rx_matches = retworkx.max_weight_matching(
                 rx_graph, weight_fn=lambda x: x, verify_optimum=True)
             self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches,
                                     42 + i, nx_graph)
Пример #47
0
def align_columns(A, B):
    k = A.shape[1]
    G = nx.Graph()
    G.add_nodes_from(range(0, k), bipartite=0)
    G.add_nodes_from(range(k, k * 2), bipartite=1)
    elist = []
    for i in range(0, k):
        for j in range(0, k):
            # elist.append((i,k+j,wasserstein_distance(L2[h,:,i],L2R3[h,:,j])))
            elist.append((i, k + j, np.abs(A[:, i] - B[:, j]).sum()))
    maximum = max(elist, key=lambda t: t[2])[2]
    elist = list(map(lambda x: (x[0], x[1], maximum - x[2]), elist))
    G.add_weighted_edges_from(elist)
    matching = nx.max_weight_matching(G)
    sorted_matching = sorted([sorted(pair) for pair in matching])
    indexes = np.array(list(map(lambda x: x[1] - k, sorted_matching)))
    return indexes
Пример #48
0
 def get_maximum_weighted_matching(self):
     graph = nx.Graph()
     matching_graph = nx.Graph()
     for idx, node in enumerate(self.nodes1):
         graph.add_node(node.index, pos=(0, idx))
         matching_graph.add_node(node.index, pos=(0, idx))
     for idx, node in enumerate(self.nodes2):
         graph.add_node(node.index, pos=(20, idx))
         matching_graph.add_node(node.index, pos=(20, idx))
     for edge in self.edges:
         graph.add_edge(edge.node1_index,
                        edge.node2_index,
                        weight=edge.weight)
     matching_edges_set = nx.max_weight_matching(graph, maxcardinality=True)
     for node1, node2 in matching_edges_set:
         matching_graph.add_edge(node1, node2)
     return matching_graph
Пример #49
0
    def find_matches(self):
        searching = self.filter(state=self.model.SEARCHING)

        G = nx.Graph()
        for search in searching:
            G.add_node(search)
            for other in searching:
                G.add_node(other)

                can_match, score = search.matching_score(other)
                if can_match:
                    # 1 / score because there is only max_weight_matching and no min version
                    G.add_edge(search, other, weight=1 / score)

        matches = nx.max_weight_matching(G)
        for search, other in matches:
            self.suggest_match(search, other)
Пример #50
0
    def test_nested_s_blossom(self):
        """Create nested S-blossom, use for augmentation:"""

        G = nx.Graph()
        G.add_weighted_edges_from([
            (1, 2, 9),
            (1, 3, 9),
            (2, 3, 10),
            (2, 4, 8),
            (3, 5, 8),
            (4, 5, 10),
            (5, 6, 6),
        ])
        dict_format = {1: 3, 2: 4, 3: 1, 4: 2, 5: 6, 6: 5}
        expected = {frozenset(e) for e in matching_dict_to_set(dict_format)}
        answer = {frozenset(e) for e in nx.max_weight_matching(G)}
        assert answer == expected
Пример #51
0
 def test_nested_s_blossom_expand(self):
     """Create nested S-blossom, augment, expand recursively:"""
     G = nx.Graph()
     G.add_weighted_edges_from([(1, 2, 8), (1, 3, 8), (2, 3, 10),
                                (2, 4, 12), (3, 5, 12), (4, 5, 14),
                                (4, 6, 12), (5, 7, 12), (6, 7, 14),
                                (7, 8, 12)])
     assert_equal(nx.max_weight_matching(G), {
         1: 2,
         2: 1,
         3: 5,
         4: 6,
         5: 3,
         6: 4,
         7: 8,
         8: 7
     })
    def update(self, boxes):
        redetected_boxes = [0] * len(boxes)
        redetected_objects = [0] * len(self.tracked_objects)

        if len(boxes) > 0 and len(self.tracked_objects) > 0:
            # create complete bipartite graph G of boxes to tracked objects,
            # where edge weight is (maxint - euclidian_distance),
            # such that max-matching can be performed to find closest matches
            G = nx.Graph()
            for i in range(len(boxes)):
                for j in range(len(self.tracked_objects)):
                    tracked_box = self.tracked_objects[j].box
                    euclid_dist = vector_euclidian_distance(
                        box_centre_point(boxes[i]),
                        box_centre_point(tracked_box))
                    weight = sys.maxint - euclid_dist

                    # set weight = 0 if box is more than one box away (discard)
                    box_dist = vector_euclidian_distance(
                        (tracked_box[0], tracked_box[1]),
                        (tracked_box[2], tracked_box[3]))
                    if euclid_dist > box_dist:
                        weight = 0
                    G.add_edge(('b', i), ('t', j), weight=weight)

            # max-match using Blossom algorithm
            max_match = nx.max_weight_matching(G)
            for match in max_match:
                if not G[('b', match[0][1])][('t',
                                              match[1][1])]['weight'] == 0:
                    self.tracked_objects[match[1][1]].box = boxes[match[0][1]]
                    redetected_boxes[match[0][1]] = 1
                    redetected_objects[match[1][1]] = 1

        # delete dropped objects
        self.tracked_objects = [
            self.tracked_objects[i] for i in range(len(redetected_objects))
            if redetected_objects[i]
        ]

        # add new detections
        for i in range(len(redetected_boxes)):
            if redetected_boxes[i] == 0:
                self.tracked_objects.append(
                    TrackedObject(self.id, boxes[i], rospy.Time.now()))
                self.id += 1
Пример #53
0
def experiment(length, ones_range_min, ones_range_max, reps, numStrings):
    strings = []
    ones = []
    maxmatch_avg = []
    maxmatch_std_dev = []
    greedymatch_avg = []
    greedymatch_std_dev = []

    for numOnes in range(ones_range_min, ones_range_max + 1):
        ones.append(numOnes)
        freed_pages_maxmatching = []
        freed_pages_greedymatching = []
        for iterations in range(reps):
            for i in range(numStrings):
                strings.append(createRandomString(length, numOnes))

            graph = makeGraph(strings)
            frdpgs_maxmatching = len(nx.max_weight_matching(graph)) / 2
            perc = (frdpgs_maxmatching / numStrings) * 100
            freed_pages_maxmatching.append(perc)

            #            graph_c = nx.complement(graph)
            #            frdpgs_greedymatching = numStrings - color_counter(graph_c)
            #            perc = (frdpgs_greedymatching/numStrings)*100
            #            freed_pages_greedymatching.append(perc)

            b, unmatched = greedyMesher(strings)
            frdpgs_greedymatching = (numStrings - len(unmatched)) / 2
            perc = (frdpgs_greedymatching / numStrings) * 100
            freed_pages_greedymatching.append(perc)

            strings = []
        m = np.asarray(freed_pages_maxmatching)
        m_a = np.mean(m)
        maxmatch_avg.append(m_a)
        m_s = np.std(m)
        maxmatch_std_dev.append(m_s)

        c = np.asarray(freed_pages_greedymatching)
        c_a = np.mean(c)
        greedymatch_avg.append(c_a)
        c_s = np.std(c)
        greedymatch_std_dev.append(c_s)

    return ones, maxmatch_avg, maxmatch_std_dev, greedymatch_avg, greedymatch_std_dev
    def get_benchmark_set(self):
        # return bm_list: List[Tuple[int, int]]   list of tuples  [(node1, node2)]

        # convert multigraph to simplified graph with weighted edges
        node_degree_dict = dict(nx.degree(self.graph))
        tmp_graph = nx.Graph()
        tmp_graph.add_nodes_from(self.graph.nodes)
        edges_list = []
        for e in self.graph.edges:
            edges_list.append(e[0:2])

        edges_set = set(edges_list)
        edges_to_add = []

        # calculate weight based on degree of each node (n1.degree * n2.degree)
        for e in edges_set:
            c = 1 / (node_degree_dict[e[0]] * node_degree_dict[e[1]])
            t = (e[0], e[1], c)
            edges_to_add.append(t)

        tmp_graph.add_weighted_edges_from(edges_to_add)
        print("NODES:")
        print(tmp_graph.nodes)
        print("EDGES:")
        print(tmp_graph.edges)
        for e in tmp_graph.edges:
            print(tmp_graph.edges[e])

        node_list = self.graph.nodes

        # for i in node_list:
        #   node_list[i]['evenlevel'] = math.inf
        #   node_list[i]['oddlevel'] = math.inf
        #   node_list[i]['blossom'] = None
        #   node_list[i]['predecessors'] = []
        #   node_list[i]['anomalies'] = []
        #   node_list[i]['visited'] = False

        # for e in self.graph.edges:
        #   self.graph.edges[e]['visited'] = False
        #   self.graph.edges[e]['used'] = False

        return nx.max_weight_matching(tmp_graph,
                                      maxcardinality=True,
                                      weight='weight')
Пример #55
0
def max_weight_matching(Mrkt, Agents, verbose=False, maxcardinality=True):
    """
    Computes max-weight matching of graph of inputted agents
        based on the “blossom” method for finding augmenting paths
        and the “primal-dual” method for finding a matching of maximum weight,
        both methods invented by Jack Edmonds
    Implemented by NetworkX
    Runtime: O(n^3) for n nodes
    Arguments
    ---------
    Mrkt: mm.Market object
        The market in which the matches are made
    Agents: list
        list of agents initiating matches
    maxcardinality: bool
        if True, compute the maximum-cardinality matching
        with maximum weight among all maximum-cardinality matchings.
    verbose: bool
        Whether algorithm prints information on action
    Returns
    -------
    dict { agent.name : agent.name } of matches

    Reference:
        “Efficient Algorithms for Finding Maximum Matching in Graphs”,
        Zvi Galil, ACM Computing Surveys, 1986.
    """
    if verbose:
        print("\nMax Weight Match Algorithm\n")
        print("Agents to match ", [a.name for a in Agents], "\n")

    # If Agents not whole market, get subgraph
    if len(Mrkt.Graph.nodes()) != len(Agents):
        to_match = deepcopy(Mrkt.Graph.subgraph(Agents))
    else:
        to_match = Mrkt.Graph
    # Workaround of assertionerror in Nx verifyOptimum() function
    # Breaks around integer weights
    for u, v, d in to_match.edges(data=True):
        d['weight'] = float(d['weight'])

    mate = nx.max_weight_matching(to_match, maxcardinality=maxcardinality)

    result = {a.name: mate[a].name for a in mate}
    return result
Пример #56
0
 def test_gnp_random_against_networkx_with_weight(self):
     for i in range(1024):
         # TODO: add back subTest usage on new testtools release
         random.seed(i)
         rx_graph = retworkx.undirected_gnp_random_graph(10,
                                                         .75,
                                                         seed=42 + i)
         for edge in rx_graph.edge_list():
             rx_graph.update_edge(*edge, random.randint(0, 5000))
         nx_graph = networkx.Graph([(x[0], x[1], {
             'weight': x[2]
         }) for x in rx_graph.weighted_edge_list()])
         nx_matches = networkx.max_weight_matching(nx_graph)
         rx_matches = retworkx.max_weight_matching(rx_graph,
                                                   weight_fn=lambda x: x,
                                                   verify_optimum=True)
         self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 42 + i,
                                 nx_graph)
Пример #57
0
def single_chinese_postman_path(graph):
    """
    Given a graph, return a list of node id's forming the shortest chinese postman path.
    If we assume V' (number of nodes with odd degree) is at least some constant fraction of V (total number of nodes),
    say 10%, the overall complexity is O(V^3).
    """

    # Build a fully-connected graph containing only the odd edges.  Complexity: O(V'*(E + V log(V)) )
    odd = odd_graph(graph)

    # Find the best matching of pairs of odd nodes. Complexity: O(V'^3)
    matching = nx.max_weight_matching(odd, True)

    # Complexity of the remainder is less approximately O(E)
    eulerian_graph = build_eulerian_graph(graph, odd, matching)
    nodes = eulerian_circuit(eulerian_graph)

    return eulerian_graph, nodes
Пример #58
0
def getMaxWeightMatching(G):
    """Returns the maximum weighted matching of G as dict"""    
    
    # initialize matching as dict
    matching = {}
    
    # iterate over each connected component C of G (for better runtime performance)
    for C in nx.connected_component_subgraphs(G) :
        
        # TODO get maximum cardinality!!!
        
        # compute maximum weight matching for connected component C
        m = nx.max_weight_matching(C, maxcardinality=True) 
        
        # append it to the matching of the entire graph G
        matching.update(m)
    
    return matching
Пример #59
0
def _min_weight_matching(graph):
    """
    Finds a perfect matching with minimum weight
    """
    for v1, v2 in graph.edges_iter():
        graph[v1][v2]["weight"] = -graph[v1][v2]["weight"] #want minimum weght

    MIN_LOG_SIZE = 20
    if len(graph) > MIN_LOG_SIZE:
        logger.debug("Finding perfect matching for a component of "
                     "size {0}".format(len(graph)))
    edges = nx.max_weight_matching(graph, maxcardinality=True)
    unique_edges = set()
    for v1, v2 in edges.items():
        if not (v2, v1) in unique_edges:
            unique_edges.add((v1, v2))

    return list(unique_edges)
Пример #60
0
    def getMergedRides(self, combinedRideWithDist):
        mergeableTripGraph = nx.Graph()
        mergeableTripGraph.add_weighted_edges_from(combinedRideWithDist)
        matching_dictionary = nx.max_weight_matching(mergeableTripGraph,
                                                     maxcardinality=True)
        #print(matching_dictionary)
        return matching_dictionary


#g = GraphMatching::Graph::WeightedGraph[
#  [1, 2, 10],
#  [1, 3, 11]
#]
#m = g.maximum_weighted_matching
#print(m.edges)
##=> [[3, 1]]
#print(m.weight(g))
##=> 11