Esempio n. 1
0
 def test_minimum_weight_full_matching_requires_complete_input(self):
     G = nx.Graph()
     G.add_nodes_from([1, 2, 3, 4], bipartite=0)
     G.add_nodes_from(['a', 'b', 'c'], bipartite=1)
     G.add_edges_from([(1, 'a'), (1, 'b'), (2, 'b'), (2, 'c'), (3, 'c'),
                       (4, 'a')])
     minimum_weight_full_matching(G)
Esempio n. 2
0
 def test_minimum_weight_full_matching_with_no_full_matching(self):
     B = nx.Graph()
     B.add_nodes_from([1, 2, 3], bipartite=0)
     B.add_nodes_from([4, 5, 6], bipartite=1)
     B.add_edge(1, 4, weight=100)
     B.add_edge(2, 4, weight=100)
     B.add_edge(3, 4, weight=50)
     B.add_edge(3, 5, weight=50)
     B.add_edge(3, 6, weight=50)
     with pytest.raises(ValueError):
         minimum_weight_full_matching(B)
Esempio n. 3
0
    def dispatch(self, dispatch_observ):
        """ Compute the assignment between drivers and passengers at each time step
    :param dispatch_observ: a list of dict, the key in the dict includes:
        order_id, int
        driver_id, int
        order_driver_distance, float
        order_start_location, a list as [lng, lat], float
        order_finish_location, a list as [lng, lat], float
        driver_location, a list as [lng, lat], float
        timestamp, int
        order_finish_timestamp, int
        day_of_week, int
        reward_units, float
        pick_up_eta, float

    :return: a list of dict, the key in the dict includes:
        order_id and driver_id, the pair indicating the assignment
    """
        """
    dispatch_observ.sort(key=lambda od_info: od_info['reward_units'], reverse=True)
    assigned_order = set()
    assigned_driver = set()
    dispatch_action = []
    for od in dispatch_observ:
      # make sure each order is assigned to one driver, and each driver is assigned with one order
      if (od["order_id"] in assigned_order) or (od["driver_id"] in assigned_driver):
        continue
      assigned_order.add(od["order_id"])
      assigned_driver.add(od["driver_id"])
      dispatch_action.append(dict(order_id=od["order_id"], driver_id=od["driver_id"]))
    return dispatch_action
    """

        id_order = list({}.fromkeys(od['order_id']
                                    for od in dispatch_observ).keys())
        id_driver = list({}.fromkeys(od['driver_id']
                                     for od in dispatch_observ).keys())
        order_id = dict((order, idx) for idx, order in enumerate(id_order))
        driver_id = dict((driver, idx) for idx, driver in enumerate(id_driver))
        N = len(order_id)
        M = len(driver_id)

        import networkx as nx
        G = nx.complete_bipartite_graph(N, M)
        for od in dispatch_observ:
            order = order_id[od['order_id']]
            driver = N + driver_id[od['driver_id']]
            G.edges[order, driver]['weight'] = -od['reward_units']

        from networkx.algorithms.bipartite.matching import minimum_weight_full_matching
        match = minimum_weight_full_matching(G)

        dispatch_action = []
        for idx, order in enumerate(id_order):
            dispatch_action.append({
                'driver_id': id_driver[match[idx] - N],
                'order_id': order
            })
        return dispatch_action
Esempio n. 4
0
 def test_minimum_weight_full_matching_different_weight_key(self):
     G = nx.complete_bipartite_graph(2, 2)
     G.add_edge(0, 2, mass=2)
     G.add_edge(0, 3, mass=0.2)
     G.add_edge(1, 2, mass=1)
     G.add_edge(1, 3, mass=2)
     matching = minimum_weight_full_matching(G, weight="mass")
     assert matching == {0: 3, 1: 2, 2: 1, 3: 0}
Esempio n. 5
0
 def test_minimum_weight_full_matching_negative_weights(self):
     G = nx.complete_bipartite_graph(2, 2)
     G.add_edge(0, 2, weight=-2)
     G.add_edge(0, 3, weight=0.2)
     G.add_edge(1, 2, weight=-2)
     G.add_edge(1, 3, weight=0.3)
     matching = minimum_weight_full_matching(G)
     assert matching == {0: 3, 1: 2, 2: 1, 3: 0}
Esempio n. 6
0
 def test_minimum_weight_full_matching_incomplete_graph(self):
     B = nx.Graph()
     B.add_nodes_from([1, 2], bipartite=0)
     B.add_nodes_from([3, 4], bipartite=1)
     B.add_edge(1, 4, weight=100)
     B.add_edge(2, 3, weight=100)
     B.add_edge(2, 4, weight=50)
     matching = minimum_weight_full_matching(B)
     assert matching == {1: 4, 2: 3, 4: 1, 3: 2}
Esempio n. 7
0
    def score(self, prediction, metric='f1', average='macro'):
        """
        :param prediction: The prediction of your model. Dict of dict like {tag: {lemma: word}}.
        :param metric: Metric for calculating per-slot-pair score.
        :param average: Type of average.
        :returns: The overall score.
        """
        self._check_dict_dict(prediction, lambda s: isinstance(s, str),
                              'prediction')
        if metric not in ['f1', 'precision', 'recall']:
            raise ValueError(
                "'metric' must be 'precision', 'recall' or 'f1', got '{}'.".
                format(metric))
        if average not in ['micro', 'macro']:
            raise ValueError(
                "'average' must be 'micro' or 'macro', got '{}'.".format(
                    average))

        graph = nx.Graph()
        prd_nodes = frozenset('prd_' + tag for tag in prediction.keys())
        ref_nodes = frozenset('ref_' + tag for tag in self.reference.keys())
        graph.add_nodes_from(prd_nodes)
        graph.add_nodes_from(ref_nodes)

        for prd_tag, prd_dict in prediction.items():
            for ref_tag, ref_dict in self.reference.items():
                true_pos = 0
                for lemma, prd_word in prd_dict.items():
                    ref_set = ref_dict.get(lemma)
                    if ref_set is not None and prd_word in ref_set:
                        true_pos += 1
                if average == 'micro':
                    tag_score = true_pos
                else:
                    tag_score = self._get_metric(true_pos, len(prd_dict),
                                                 len(ref_dict), metric)
                graph.add_edge('prd_' + prd_tag,
                               'ref_' + ref_tag,
                               weight=-tag_score)

        matches = minimum_weight_full_matching(graph, prd_nodes)
        match_score = 0
        for prd_node, ref_node in matches.items():
            if prd_node in prd_nodes:
                match_score -= graph[prd_node][ref_node]['weight']
        if average == 'micro':
            total_prd = sum(len(prd_dict) for prd_dict in prediction.values())
            total_ref = sum(len(ref_dict) for ref_dict in reference.values())
            final_score = self._get_metric(match_score, total_prd, total_ref,
                                           metric)
            return final_score * len(self.reference) / max(
                len(self.reference), len(prediction))
        else:
            return match_score / max(len(self.reference), len(prediction))
Esempio n. 8
0
 def test_minimum_weight_full_matching_square(self):
     G = nx.complete_bipartite_graph(3, 3)
     G.add_edge(0, 3, weight=400)
     G.add_edge(0, 4, weight=150)
     G.add_edge(0, 5, weight=400)
     G.add_edge(1, 3, weight=400)
     G.add_edge(1, 4, weight=450)
     G.add_edge(1, 5, weight=600)
     G.add_edge(2, 3, weight=300)
     G.add_edge(2, 4, weight=225)
     G.add_edge(2, 5, weight=300)
     matching = minimum_weight_full_matching(G)
     assert matching == {0: 4, 1: 3, 2: 5, 4: 0, 3: 1, 5: 2}
Esempio n. 9
0
 def test_minimum_weight_full_matching_smaller_right(self):
     G = nx.complete_bipartite_graph(4, 3)
     G.add_edge(0, 4, weight=400)
     G.add_edge(0, 5, weight=400)
     G.add_edge(0, 6, weight=300)
     G.add_edge(1, 4, weight=150)
     G.add_edge(1, 5, weight=450)
     G.add_edge(1, 6, weight=225)
     G.add_edge(2, 4, weight=400)
     G.add_edge(2, 5, weight=600)
     G.add_edge(2, 6, weight=290)
     G.add_edge(3, 4, weight=1)
     G.add_edge(3, 5, weight=2)
     G.add_edge(3, 6, weight=3)
     matching = minimum_weight_full_matching(G)
     assert matching == {1: 4, 2: 6, 3: 5, 4: 1, 5: 3, 6: 2}
Esempio n. 10
0
 def test_minimum_weight_full_matching_smaller_top_nodes_right(self):
     G = nx.complete_bipartite_graph(3, 4)
     G.add_edge(0, 3, weight=400)
     G.add_edge(0, 4, weight=150)
     G.add_edge(0, 5, weight=400)
     G.add_edge(0, 6, weight=1)
     G.add_edge(1, 3, weight=400)
     G.add_edge(1, 4, weight=450)
     G.add_edge(1, 5, weight=600)
     G.add_edge(1, 6, weight=2)
     G.add_edge(2, 3, weight=300)
     G.add_edge(2, 4, weight=225)
     G.add_edge(2, 5, weight=290)
     G.add_edge(2, 6, weight=3)
     matching = minimum_weight_full_matching(G, top_nodes=[3, 4, 5, 6])
     assert matching == {0: 4, 1: 6, 2: 5, 4: 0, 5: 2, 6: 1}
Esempio n. 11
0
 def test_minimum_weight_full_matching_smaller_left(self):
     G = nx.complete_bipartite_graph(3, 4)
     G.add_edge(0, 3, weight=400)
     G.add_edge(0, 4, weight=150)
     G.add_edge(0, 5, weight=400)
     G.add_edge(0, 6, weight=1)
     G.add_edge(1, 3, weight=400)
     G.add_edge(1, 4, weight=450)
     G.add_edge(1, 5, weight=600)
     G.add_edge(1, 6, weight=2)
     G.add_edge(2, 3, weight=300)
     G.add_edge(2, 4, weight=225)
     G.add_edge(2, 5, weight=290)
     G.add_edge(2, 6, weight=3)
     matching = minimum_weight_full_matching(G)
     assert_equal(matching, {0: 4, 1: 6, 2: 5, 4: 0, 5: 2, 6: 1})
Esempio n. 12
0
 print("Assigning edge weights...")
 if args.normalize_weight:
   weight_param_name = 'norm_'+args.weight_param
 else:
   weight_param_name = args.weight_param
 set1_vs_set2_weights = df_to_dict(set1_vs_set2_weights, weight_param_name)
 set2_vs_set1_weights = df_to_dict(set2_vs_set1_weights, weight_param_name)
 for edge in bg.edges:
   q = set1_proteins[edge[0]]
   s = set2_proteins[edge[1]]
   bidirectional_weight = calculate_biderectional_weight(set1_vs_set2_weights, set2_vs_set1_weights, q, s)
   bg.edges[edge]['weight'] = bidirectional_weight
 
 # find max weight matching
 print("Finding max weight matching...")
 mw = minimum_weight_full_matching(bg)
 
 # print out matches
 print("Writing out results...")
 with open(args.out_tsv, 'w') as fo:
   print("%s\t%s\t%s weight" %(args.set1_name, args.set2_name, args.weight_param), file=fo)
   for match in mw:
     source, target = match, mw[match]
     if target < source:
       # each match appears in both directions in the output dict
       continue
     match_weight = -1 * bg[source][target]['weight']
     if match_weight > 0:
       q_name = set1_proteins[source]
       s_name = set2_proteins[target]
       print("%s\t%s\t%s" %(q_name, s_name, match_weight), file=fo)