def find_matching(self):
        u"""Finds a matching in the bipartite graph.

        This is done using the Hopcroft-Karp algorithm with an implementation from the
        `hopcroftkarp` package.

        Returns:
            A dictionary where each edge of the matching is represented by a key-value pair
            with the key being from the left part of the graph and the value from te right part.
        """
        # The directed graph is represented as a dictionary of edges
        # The key is the tail of all edges which are represented by the value
        # The value is a set of heads for the all edges originating from the tail (key)
        # In addition, the graph stores which part of the bipartite graph a node originated from
        # to avoid problems when a value exists in both halfs.
        # Only one direction of the undirected edge is needed for the HopcroftKarp class
        directed_graph = {}  # type: Dict[Tuple[int, TLeft], Set[Tuple[int, TRight]]]

        for (left, right) in self._edges:
            tail = (LEFT, left)
            head = (RIGHT, right)
            if tail not in directed_graph:
                directed_graph[tail] = set([head])
            else:
                directed_graph[tail].add(head)

        matching = HopcroftKarp(directed_graph).maximum_matching()

        # Filter out the partitions (LEFT and RIGHT) and only return the matching edges
        # that go from LEFT to RIGHT
        return dict((tail[1], head[1]) for tail, head in matching.items() if tail[0] == LEFT)
示例#2
0
def compute_maximum_matching():

    class_size = int(input("Enter Class Size: "))

    associate_dict = example_creator.associate_preferences(class_size)

    manager_dict = example_creator.manager_preferences(class_size)

    amicable_preference_dict = create_amicable_preference(
        associate_dict, manager_dict)

    # converted_amicable_dict = amicable_dict_converter(amicable_preference_dict)
    """
    print_dictionary(associate_dict)

    print_dictionary(manager_dict)

    print_dictionary(amicable_preference_dict)

    print_dictionary(converted_amicable_dict)
    """

    duplicate_dict = copy.deepcopy(amicable_preference_dict)
    amicable_match = HopcroftKarp(amicable_preference_dict).maximum_matching()

    print(amicable_match)
    print(
        "Total number of managers and associates matched where both listed each other is: "
        + str(len(amicable_match)))

    return class_size, associate_dict, manager_dict, amicable_match
示例#3
0
def solver(file):
    graph = {}
    allLefts = set()
    allRights = set()
    total = 0

    numlines = int(file.readline())
    total = numlines
    for x in range(numlines):
        words = file.readline().lower().strip().split()
        num = words[1] + "XXX"

        if words[0] in graph:
            graph[words[0]].add(num)
        else:
            graph[words[0]] = {num}

        allLefts.add(words[0])
        allRights.add(num)



    hk = HopcroftKarp(graph)
    max_matching = hk.maximum_matching()

    caught = 0
    caught += len(max_matching.keys()) // 2
    caught += len([x for x in allLefts if x not in max_matching])
    caught += len([x for x in allRights if x not in max_matching])

    print(caught)
    print(max_matching)
    return(total - caught)
示例#4
0
def run(data):

    c1 = []
    c2 = []
    for t in data:
        if t[1] == 1:
            c1.append(t[0])
        else:
            c2.append(t[0])

    c1.sort()
    c2.sort()
    c1 += [float('inf')] * max(len(c2) - len(c1), 0)
    c2 += [float('inf')] * max(len(c1) - len(c2), 0)
    n = len(c1)

    # print(c1, c2)
    graph = dict()
    c1h = list()
    for i, c in enumerate(c1):
        graph[(1, i, c)] = {(2, j, d) for j, d in enumerate(c2) if c != d}
        c1h.append((1, i, c))

    mm = HopcroftKarp(graph).maximum_matching()
    # print(mm)
    # print(c1h)
    diff = [c[2] for c in c1h if c not in mm]

    cars = diff.count(1)
    prom = len(diff) - cars

    return str(n + cars) + ' ' + str(prom)
def hopkroft(graph, structure):
    transformed_graph = {}

    supervisors = graph.getEdges()
    students = graph.getStuEdges()
    correspondence = {}
    sup_name = 0
    list_supervisors = [supervisor for supervisor in supervisors]
    list_students = [student for student in students]
    random.shuffle(list_supervisors)
    random.shuffle(list_students)
    a_to_b = {}
    for i in range(len(list_students)):
        a_to_b[list_students[i]] = 'stu' + str(i)

    for supervisor in list_supervisors:
        cardinality = structure[supervisor]
        for i in range(cardinality):
            for stu in supervisors[supervisor]:
                transformed_graph.setdefault(sup_name, set()).add(a_to_b[stu])
            correspondence[sup_name] = supervisor
            sup_name = sup_name + 1
    m = HopcroftKarp(transformed_graph).maximum_matching()

    result = BipartiteGraph()
    for student in students:
        sup_code = m[a_to_b[student]]
        result.addEdge(correspondence[sup_code], student)
    return result
示例#6
0
def gluten_morgen(filename="data/day21.dat"):
    food = []
    total_food = []
    allergens = {}
    with open(filename) as fdata:
        for i, line in enumerate(fdata):
            f, a = line.strip().split(" (contains ")
            total_food.extend(f.split(" "))
            food.append(f.split(" "))
            allgs = a[:-1].split(", ")
            for a in allgs:
                if a in allergens:
                    allergens[a].append(i)
                else:
                    allergens[a] = [i]

    def intersection(*food_chains):
        master_set = set(food[food_chains[0]])
        for f in food_chains:
            master_set &= set(food[f])

        return master_set

    ing = set()
    final_dict = {}
    for a in allergens:
        inter = intersection(*allergens[a])
        final_dict[a] = list(inter)
        ing = ing.union(inter)
    print(final_dict)
    matching = HopcroftKarp(final_dict).maximum_matching(keys_only=True)
    alph = ",".join(matching[a] for a in sorted(matching))
    return len([f for f in total_food if f not in ing]), alph
示例#7
0
        def FindBipartitePerfectMatching(matrix):
            ''' Leveraged Hopcroft-Karp to find the 
                maximal matching in a bipartite graph. '''

            # Input: Bipartite Matrix
            # Output: Perfect Matching of Bipartite Matrix

            from hopcroftkarp import HopcroftKarp
            import string

            bipartiteGraph = {}

            for rowNum in xrange(0, len(matrix)):
                key = string.lowercase
                bipartiteGraph[key[rowNum]] = set(
                    np.where(matrix[rowNum] == 1)[0])

            perfectMatching = HopcroftKarp(bipartiteGraph).maximum_matching()

            matrix[:] = 0

            for key in perfectMatching:
                val = perfectMatching[key]
                if type(val) == type('a'):
                    matrix[string.lowercase.index(val), key] = 1

            return matrix
示例#8
0
def run(data):

    graph = dict()

    # build graph for bipartite maximum-matching
    for a, b in data:
        a = 'A_' + a
        b = 'B_' + b

        if a not in graph:
            graph[a] = set([b])
        else:
            graph[a] |= set([b])

        # if b not in graph:
        #     graph[b] = set([a])
        # else:
        #     graph[b] |= set([a])

    # number of edges in left / right half of graph
    left = set()
    right = set()
    for a, b in data:
        left |= set([a])
        right |= set([b])

    x = HopcroftKarp(graph).maximum_matching()
    num_optimal = round(len(x) / 2)
    num_real_topics = num_optimal + (len(left) - num_optimal) + (len(right) -
                                                                 num_optimal)

    return len(data) - num_real_topics
 def test_keys_only(self):
     graph = {'a': {1, 3}, 'c': {1, 3}, 'd': {3, 6}, 'h': {8}}
     hk = HopcroftKarp(graph)
     max_matching = hk.maximum_matching(keys_only=True)
     self.assertTrue(
         max_matching == {
             'a': 1,
             'c': 3,
             'd': 6,
             'h': 8
         } or max_matching == {
             'a': 3,
             'c': 1,
             'd': 6,
             'h': 8
         }, 'maximum matching is incorrect')
示例#10
0
def getBottleneckDist(S, T):
    """
    Perform the Bottleneck distance matching between persistence diagrams.
    Assumes first two columns of S and T are the coordinates of the persistence
    points, but allows for other coordinate columns (which are ignored in
    diagonal matching)
    :param S: Mx(>=2) array of birth/death pairs for PD 1
    :param T: Nx(>=2) array of birth/death paris for PD 2
    :returns (tuples of matched indices, total cost, (N+M)x(N+M) cross-similarity)
    """
    from bisect import bisect_left
    from hopcroftkarp import HopcroftKarp

    N = S.shape[0]
    M = T.shape[0]
    # Step 1: Compute CSM between S and T, including points on diagonal
    # L Infinity distance
    Sb, Sd = S[:, 0], S[:, 1]
    Tb, Td = T[:, 0], T[:, 1]
    D1 = np.abs(Sb[:, None] - Tb[None, :])
    D2 = np.abs(Sd[:, None] - Td[None, :])
    DUL = np.maximum(D1, D2)
    # Put diagonal elements into the matrix, being mindful that Linfinity
    # balls meet the diagonal line at a diamond vertex
    D = np.zeros((N + M, N + M))
    D[0:N, 0:M] = DUL
    UR = np.max(D) * np.ones((N, N))
    np.fill_diagonal(UR, 0.5 * (S[:, 1] - S[:, 0]))
    D[0:N, M::] = UR
    UL = np.max(D) * np.ones((M, M))
    np.fill_diagonal(UL, 0.5 * (T[:, 1] - T[:, 0]))
    D[N::, 0:M] = UL

    # Step 2: Perform a binary search + Hopcroft Karp to find the
    # bottleneck distance
    N = D.shape[0]
    ds = np.unique(D.flatten())
    ds = ds[ds > 0]
    ds = np.sort(ds)
    bdist = ds[-1]
    matching = {}
    while len(ds) >= 1:
        idx = 0
        if len(ds) > 1:
            idx = bisect_left(range(ds.size), int(ds.size / 2))
        d = ds[idx]
        graph = {}
        for i in range(N):
            graph['%s' % i] = {j for j in range(N) if D[i, j] <= d}
        res = HopcroftKarp(graph).maximum_matching()
        if len(res) == 2 * N and d < bdist:
            bdist = d
            matching = res
            ds = ds[0:idx]
        else:
            ds = ds[idx + 1::]
    matchidx = [(i, matching['%i' % i]) for i in range(N)]
    return (matchidx, bdist, D)
示例#11
0
def main(args):
    """
    """
    with open(args.input, 'r') as fh:
        data = fh.read().split('\n')
        allergens_map = defaultdict(list)
        all_ingred = list()

        for d in data:
            res = re.match('(.+)\(contains(.+)\)', d)

            if res:
                ingredients = res.group(1).rstrip().lstrip().split(' ')
                allergens = res.group(2).rstrip().lstrip().split(', ')

                for a in allergens:
                    allergens_map[a].append(set(ingredients))
                all_ingred.append(ingredients)

        poison = list()
        graph = {}
        for a in allergens_map:
            i = set.intersection(*allergens_map[a])
            graph[a] = i
            for entry in i:
                if entry not in poison:
                    poison.append(entry)

        # print(all_ingred)
        c = 0
        for a in all_ingred:
            for i in a:
                if i not in poison:
                    c += 1
        print(c)

        # https://en.wikipedia.org/wiki/Hopcroft%E2%80%93Karp_algorithm
        matcb = HopcroftKarp(graph).maximum_matching(keys_only=True)
        l = sorted(matcb.keys())

        part2 = []
        for key in l:
            part2.append(matcb[key])

        print(",".join(part2))
示例#12
0
def get_departure_keys_product(rules=RULES,
                               tickets=TICKETS,
                               my_ticket=MY_TICKET):
    tickets_to_remove = set(i for i, ticket in enumerate(tickets)
                            if invalid(ticket, rules))

    n = len(tickets[0])
    rule_columns = {r: set(range(n)) for r in rules}
    for i, ticket in enumerate(tickets):
        if i in set(tickets_to_remove):
            continue
        for rule in rules:
            for j, v in enumerate(ticket):
                if not is_valid(v, rules[rule]):
                    rule_columns[rule].discard(j)

    matching = HopcroftKarp(rule_columns).maximum_matching(keys_only=True)
    departure_keys = [i for k, i in matching.items() if "departure" in k]
    return product([my_ticket[i] for i in departure_keys])
示例#13
0
def pick(problems,solved2):
    chosen=[]
    if len(problems) == 0:
        return chosen
    graph = {}
    co=0
    for typ,l,r in problems:
        allp = getall(typ,l,r,solved2)
        if len(allp) == 0:
            continue
        random.shuffle(allp)
        graph[co] = allp
        co=co+1
    if len(graph) == 0:
        return []
    hk = HopcroftKarp(graph)
    max_matching = hk.maximum_matching()
    for i in range(0,co):
        chosen.append(max_matching[i])
    random.shuffle(chosen)
    return chosen
示例#14
0
def solve(topics):
    n = len(topics)
    graph = {}
    for t in topics:
        if t[0] not in graph.keys():
            graph[t[0]] = set()
        graph[t[0]].add(t[1])
    # print(graph)
    n_matched = len(HopcroftKarp(graph).maximum_matching()) // 2
    # print(HopcroftKarp(graph).maximum_matching())
    points = len(set(t[0] for t in topics)) + len(set(t[1] for t in topics))
    print(n - (points - n_matched))
示例#15
0
def solve(L):
    n = len(L)
    graph = defaultdict(set)
    left = set()
    right = set()
    for u, v in L:
        left.add(u)
        right.add(v)
        graph['l' + u].add('r' + v)
    sol = HopcroftKarp(graph).maximum_matching()
    orig = len(left) + len(right) - len(sol) / 2
    return n - orig
    def __init__(self, graph):

        self.graph = graph

        self.left = set(graph.keys())
        self.right = set()

        for value in graph.values():
            self.right.update(value)
        for vertex in self.left:
            for neighbour in graph[vertex]:
                if neighbour not in graph:
                    graph[neighbour] = set()
                    graph[neighbour].add(vertex)
                else:
                    graph[neighbour].add(vertex)

        hk = HopcroftKarp(graph)
        self.matching = hk.maximum_matching()
        self.E_w = set()
        self.E_0 = set()
        self.E_1 = set()
示例#17
0
def main():

    class_size, associate_dict, manager_dict, amicable_match_dict = maximum_matching.compute_maximum_matching(
    )

    if len(amicable_match_dict) != 2 * class_size:

        leftover_associate_dictionary = unmatched_dictionaries(
            associate_dict, amicable_match_dict)

        leftover_manager_dictionary = unmatched_dictionaries(
            manager_dict, amicable_match_dict)

        associate_graph = create_leftover_graph(leftover_associate_dictionary,
                                                leftover_manager_dictionary)

        leftover_matches_formed = HopcroftKarp(
            associate_graph).maximum_matching()

        print(leftover_matches_formed)
        print(
            "Total number of managers and associates matched where atleast one of them listed other is: "
            + str(len(leftover_matches_formed)))

        if len(amicable_match_dict) + len(
                leftover_matches_formed) != 2 * class_size:
            unmatched_associates, unmatched_managers = cannot_be_matched(
                amicable_match_dict, leftover_matches_formed, associate_dict,
                manager_dict)

            print(unmatched_associates, unmatched_managers)

    profit_matrix = matching_with_preference.matching_preference(
        class_size, associate_dict, manager_dict)

    maximum_matching.print_dictionary(associate_dict)
    maximum_matching.print_dictionary(manager_dict)

    print(kuhn_munkers.maxWeightMatching(profit_matrix))

    pause()

    program_choices_test_data = pd.read_csv('managerchoice.csv')
    candidate_choices_test_data = pd.read_csv('associatechoice.csv')

    test_match = MatchController(program_choices_test_data,
                                 candidate_choices_test_data)
    test_match.start_match()
    results = test_match.results_dict()

    maximum_matching.print_dictionary(results)
 def test_mainExample(self):
     graph = {'a': {1, 3}, 'c': {1, 3}, 'd': {3, 6}, 'h': {8}}
     hk = HopcroftKarp(graph)
     max_matching = hk.maximum_matching()
     self.assertTrue(
         max_matching == {
             1: 'a',
             'a': 1,
             3: 'c',
             'c': 3,
             6: 'd',
             'd': 6,
             8: 'h',
             'h': 8
         } or max_matching == {
             3: 'a',
             'a': 3,
             1: 'c',
             'c': 1,
             6: 'd',
             'd': 6,
             8: 'h',
             'h': 8
         }, 'maximum matching is incorrect')
示例#19
0
def solve(case_index):
    graph = collections.defaultdict(set)
    n = read_int()
    next_line()

    words = []

    for i in xrange(n):
        first, second = read_word(), read_word()
        words.append((first, second))
        next_line()
        graph[first + "1"].add(second + "2")

    graph = dict(graph)
    num_firsts = len(set(i[0] for i in words))
    num_seconds = len(set(i[1] for i in words))
    num_match = len(HopcroftKarp(graph).maximum_matching()) / 2
    return str(len(words) - (num_firsts + num_seconds - num_match))
def conf_mat(correct_class, pred_class, ts, match_func, win_len):
    """
    - description: return confusion matrix as dictionary. Match pred_class to
    correct_class maximizing number of true positives. One change point can be
    matched only once. By now solved with maximum matching in bipartite graph:
    nodes of the left represents change points of correct_class and the nodes
    of the right represents change points of pred_class. Two nodes are
    connected if the distance between than is less or equal than win_len. In
    case of more than one solution with maximum matching is possible to select
    the solution with minimum distance between matched change points, but for
    that, the problem must be solved with dynamic programming or
    min-cost-max-flow.
    - arguments:
        - correct_class: list with ids indicating change points of correct
        classification
        - pred_class : list with ids indicating change points of predicted
        classification
        - win_len: correct_class[i] can be matched with pred_class[j] if
        abs(correct_class[i] - pred_class[j]) <= win_len
    """

    graph = {}
    for l in xrange(len(correct_class)):
        neigh = set()
        for r in xrange(len(pred_class)):
            if match_func(correct_class[l], pred_class[r], win_len):
                neigh.add("r{}".format(r))
        graph["l{}".format(l)] = neigh
    max_match = HopcroftKarp(graph).maximum_matching()

    conf = {}
    conf["tp"] = len(max_match) / 2
    conf["fp"] = len(pred_class) - conf["tp"]
    conf["fn"] = len(correct_class) - conf["tp"]
    # tn = number of true not change points - number of wrong predicted change
    # points
    # tn = (number of points - number of true change points) - number of wrong
    # predicted change points
    conf["tn"] = len(ts.y) - len(correct_class) - conf["fp"]

    return conf
示例#21
0
def find_matching(graph):
    match = HopcroftKarp(graph).maximum_matching()
    #print 'Done: find matching'
    return match
示例#22
0
def TOPOWithPairs(GPSMap,
                  OSMMap,
                  GPSList,
                  OSMList,
                  step=0.00005,
                  r=0.00300,
                  threshold=0.00015,
                  region=None,
                  outputfile="tmp.txt",
                  one2oneMatching=True,
                  metaData=None):

    i = 0
    precesion_sum = 0
    recall_sum = 0

    print(len(OSMList), len(GPSList.keys()))

    rrr = float(len(GPSList.keys())) / float(len(OSMList))

    print("Overall Coverage", rrr)

    returnResult = []

    for k, itemGPS in GPSList.iteritems():

        itemOSM = OSMList[k]

        gpsn1, gpsn2, gpsd1, gpsd2 = itemGPS[1], itemGPS[2], itemGPS[
            3], itemGPS[4]
        osmn1, osmn2, osmd1, osmd2 = itemOSM[2], itemOSM[3], itemOSM[
            4], itemOSM[5]

        osm_start_lat, osm_start_lon = itemOSM[0], itemOSM[1]
        gps_start_lat, gps_start_lon = itemGPS[5], itemGPS[6]

        # nid = pairs[min_node]

        # lat = GPSMap.nodes[nid][0]
        # lon = GPSMap.nodes[nid][1]

        lat = itemOSM[0]
        lon = itemOSM[1]

        ts1 = time()
        marbles = GPSMap.TOPOWalk(1,
                                  step=step,
                                  r=r,
                                  direction=False,
                                  newstyle=True,
                                  nid1=gpsn1,
                                  nid2=gpsn2,
                                  dist1=gpsd1,
                                  dist2=gpsd2)

        # for recall
        holes = OSMMap.TOPOWalk(1,
                                step=step,
                                r=r,
                                direction=False,
                                newstyle=True,
                                nid1=osmn1,
                                nid2=osmn2,
                                dist1=osmd1,
                                dist2=osmd2,
                                metaData=metaData)  # remove holes in tunnel

        # for precision
        holes_bidirection = OSMMap.TOPOWalk(
            1,
            step=step,
            r=r,
            direction=False,
            newstyle=True,
            nid1=osmn1,
            nid2=osmn2,
            dist1=osmd1,
            dist2=osmd2,
            bidirection=True,
            metaData=None)  # don't remove holes in tunnel
        ts2 = time()

        idx_marbles = index.Index()
        idx_holes = index.Index()
        idx_holes_bidirection = index.Index()

        for j in range(len(marbles)):
            idx_marbles.insert(
                j, (marbles[j][0] - 0.00001, marbles[j][1] - 0.00001,
                    marbles[j][0] + 0.00001, marbles[j][1] + 0.00001))

        for j in range(len(holes)):
            idx_holes.insert(j, (holes[j][0] - 0.00001, holes[j][1] - 0.00001,
                                 holes[j][0] + 0.00001, holes[j][1] + 0.00001))

        for j in range(len(holes_bidirection)):
            idx_holes_bidirection.insert(
                j,
                (holes_bidirection[j][0] - 0.00001, holes_bidirection[j][1] -
                 0.00001, holes_bidirection[j][0] + 0.00001,
                 holes_bidirection[j][1] + 0.00001))

        # holes_bidirection  = holes
        # idx_holes_bidirection = idx_holes

        matchedNum = 0
        bigraph = {}
        matched_marbles = []
        bipartite_graph = []

        cost_map = {}

        for marble in marbles:
            rr = threshold * 1.8
            possible_holes = list(
                idx_holes_bidirection.intersection(
                    (marble[0] - rr, marble[1] - rr, marble[0] + rr,
                     marble[1] + rr)))
            for hole_id in possible_holes:
                hole = holes_bidirection[hole_id]
                ddd = distance(marble, hole)

                n1 = latlonNorm((marble[2], marble[3]))
                n2 = latlonNorm((hole[2], hole[3]))

                #ddd += (1.0 - abs(n1[0] * n2[0] + n1[1] * n2[1])) * threshold * 5
                #ddd -= threshold / 2
                #ddd = max(ddd, 0)

                if marble[2] != marble[3] and hole[2] != hole[3]:
                    angle_d = 1.0 - abs(n1[0] * n2[0] + n1[1] * n2[1])
                else:
                    angle_d = 0.0

                #angle_d = 0.0

                if ddd < threshold and angle_d < 0.29:  # 0.03 --> 15 degrees  0.13 --> 30 degrees 0.29 --> 45 degrees
                    #cost_map[(marble, hole_id)] = ddd

                    if marble in bigraph.keys():
                        bigraph[marble].add(hole_id)
                    else:
                        bigraph[marble] = Set([hole_id])

                    bipartite_graph.append((marble, hole_id, ddd))

                    matchedNum += 1
                    matched_marbles.append(marble)
                    #break

        soft_matchedNum = 0

        if one2oneMatching == True:
            matches = HopcroftKarp(bigraph).maximum_matching()

            matchedNum = len(matches.keys()) / 2

            # for k,v in matches.iteritems():
            # 	if (k,v) in cost_map.keys():
            # 		soft_matchedNum += max(min(((threshold - cost_map[(k,v)]) / threshold),1.0),0.0)

        #matched_marbles, matched_holes, _ = BipartiteGraphMatching(bipartite_graph)
        #matched_holes = [(holes_bidirection[item][0], holes_bidirection[item][1]) for item in matched_holes]

        #matched_marbles = [(marbles[item][0], marbles[item][1]) for item in matched_marbles]

        # for item in HopcroftKarp(bigraph).maximum_matching().keys():
        # 	if type(item) is not int :
        # 		matched_marbles.append(item)

        print(i, len(marbles), len(holes))
        if len(marbles) == 0 or len(holes) == 0:
            continue

        #precesion = float(soft_matchedNum) / len(marbles)
        precesion = float(matchedNum) / len(marbles)

        # TOPO Debug
        #showTOPO.RenderSVG(marbles, holes, matched_marbles,matched_holes,  lat, lon, 0.00300, "svg/nn"+outputfile.split('/')[-1]+"_%.6f_"%precesion+str(i)+"_"+str(lat)+"_"+str(lon)+".svg", OSMMap= OSMMap, starts=(osm_start_lat,osm_start_lon,gps_start_lat,gps_start_lon))

        matchedNum = 0
        bigraph = {}

        cost_map = {}

        for hole in holes:
            rr = threshold * 1.8
            possible_marbles = list(
                idx_marbles.intersection(
                    (hole[0] - rr, hole[1] - rr, hole[0] + rr, hole[1] + rr)))
            for marble_id in possible_marbles:
                marble = marbles[marble_id]

                ddd = distance(marble, hole)

                n1 = latlonNorm((marble[2], marble[3]))
                n2 = latlonNorm((hole[2], hole[3]))

                #ddd += (1.0 - abs(n1[0] * n2[0] + n1[1] * n2[1])) * threshold * 5
                #ddd -= threshold / 2
                #ddd = max(ddd, 0)

                if marble[2] != marble[3] and hole[2] != hole[3]:
                    angle_d = 1.0 - abs(n1[0] * n2[0] + n1[1] * n2[1])
                else:
                    angle_d = 0.0

                #angle_d = 0.0

                if ddd < threshold and angle_d < 0.29:
                    #cost_map[(hole, marble_id)] = ddd

                    if hole in bigraph.keys():
                        bigraph[hole].add(marble_id)
                    else:
                        bigraph[hole] = Set([marble_id])
                    matchedNum += 1
                    #break

        soft_matchedNum = 0

        if one2oneMatching == True:
            #matchedNum = len(HopcroftKarp(bigraph).maximum_matching().keys()) / 2

            matches = HopcroftKarp(bigraph).maximum_matching()

            matchedNum = len(matches.keys()) / 2

            # for k,v in matches.iteritems():
            # 	if (k,v) in cost_map.keys():
            # 		soft_matchedNum += max(min(((threshold - cost_map[(k,v)]) / threshold),1.0),0.0)

        #recall = float(soft_matchedNum) / len(holes)
        recall = float(matchedNum) / len(holes)

        precesion_sum += precesion
        recall_sum += recall

        ts3 = time()

        with open(outputfile, "a") as fout:
            fout.write(
                str(i) + " " + str(lat) + " " + str(lon) + " " + str(gpsn1) +
                " " + str(gpsn2) + " Precesion " + str(precesion) +
                " Recall " + str(recall) + " Avg Precesion " +
                str(precesion_sum / (i + 1)) + " Avg Recall " +
                str(recall_sum / (i + 1)) + " \n")

        print(i, "Precesion", precesion, "Recall", recall, "Avg Precesion",
              precesion_sum / (i + 1), "Avg Recall", recall_sum / (i + 1), rrr,
              ts2 - ts1, ts3 - ts2)

        returnResult.append(
            (lat, lon, precesion, recall, gpsn1, gpsn2, gpsd1, gpsd2))

        i = i + 1
        #if i > 100:
        #	break

    # try:
    # 	with open(outputfile, "a") as fout:
    # 		fout.write(str(precesion_sum/i)+" "+str(recall_sum/i)+" "+str(rrr)+ " "+ str(rrr * recall_sum/i) +"\n")
    # except:
    # 	 with open(outputfile, "a") as fout:
    #                     fout.write(str(0)+" "+str(0)+" "+str(0)+ " "+ "0.0" +"\n")

    #with open("TOPOResultSummary.txt","a") as fout:
    #	fout.write(str(precesion_sum/i)+" "+str(recall_sum/i)+" "+str(rrr)+ " "+ str(rrr * recall_sum/i) +"\n")

    new_topoResult = TOPO121(returnResult, GPSMap)

    # Debug svg
    # for rr in returnResult:
    # 	if rr not in new_topoResult:
    # 		print("remove rr")
    # 		Popen("rm svg/*%s*.svg" % (str(rr[0])+"_"+str(rr[1])),shell=True).wait()

    #print(topoAvg(returnResult), len(returnResult)/float(len(OSMList)))
    print(topoAvg(new_topoResult), len(new_topoResult) / float(len(OSMList)))
    p, r = topoAvg(new_topoResult)

    # with open(outputfile, "a") as fout:
    # 	fout.write(str(p)+" "+str(r)+" "+str(len(new_topoResult)/float(len(OSMList)))+"\n")

    print("precision=" + str(p) + " overall-recall=" +
          str(r * len(new_topoResult) / float(len(OSMList))))

    try:
        with open(outputfile, "a") as fout:
            fout.write(
                str(p) + " " + str(r) + " " +
                str(len(new_topoResult) / float(len(OSMList))) + " " +
                str(r * len(new_topoResult) / float(len(OSMList))) + "\n")
            fout.write("precision=" + str(p) + " overall-recall=" +
                       str(r * len(new_topoResult) / float(len(OSMList))))
    except:
        with open(outputfile, "a") as fout:
            fout.write(
                str(0) + " " + str(0) + " " + str(0) + " " + str(0) + "\n")

    return new_topoResult
示例#23
0
def bottleneck(dgm1, dgm2, matching=False):
    """
    Perform the Bottleneck distance matching between persistence diagrams.
    Assumes first two columns of S and T are the coordinates of the persistence
    points, but allows for other coordinate columns (which are ignored in
    diagonal matching).

    See the `distances` notebook for an example of how to use this.

    Parameters
    -----------
    dgm1: Mx(>=2) 
        array of birth/death pairs for PD 1
    dgm2: Nx(>=2) 
        array of birth/death paris for PD 2
    matching: bool, default False
        if True, return matching infromation and cross-similarity matrix

    Returns
    --------

    d: float
        bottleneck distance between dgm1 and dgm2
    matching: ndarray(Mx+Nx, 3), Only returns if `matching=True`
        A list of correspondences in an optimal matching, as well as their distance, where:
        * First column is index of point in first persistence diagram, or -1 if diagonal
        * Second column is index of point in second persistence diagram, or -1 if diagonal
        * Third column is the distance of each matching
    """

    return_matching = matching

    S = np.array(dgm1)
    M = min(S.shape[0], S.size)
    if S.size > 0:
        S = S[np.isfinite(S[:, 1]), :]
        if S.shape[0] < M:
            warnings.warn("dgm1 has points with non-finite death times;" +
                          "ignoring those points")
            M = S.shape[0]
    T = np.array(dgm2)
    N = min(T.shape[0], T.size)
    if T.size > 0:
        T = T[np.isfinite(T[:, 1]), :]
        if T.shape[0] < N:
            warnings.warn("dgm2 has points with non-finite death times;" +
                          "ignoring those points")
            N = T.shape[0]

    if M == 0:
        S = np.array([[0, 0]])
        M = 1
    if N == 0:
        T = np.array([[0, 0]])
        N = 1

    # Step 1: Compute CSM between S and T, including points on diagonal
    # L Infinity distance
    Sb, Sd = S[:, 0], S[:, 1]
    Tb, Td = T[:, 0], T[:, 1]
    D1 = np.abs(Sb[:, None] - Tb[None, :])
    D2 = np.abs(Sd[:, None] - Td[None, :])
    DUL = np.maximum(D1, D2)

    # Put diagonal elements into the matrix, being mindful that Linfinity
    # balls meet the diagonal line at a diamond vertex
    D = np.zeros((M + N, M + N))
    # Upper left is Linfinity cross-similarity between two diagrams
    D[0:M, 0:N] = DUL
    # Upper right is diagonal matching of points from S
    UR = np.inf * np.ones((M, M))
    np.fill_diagonal(UR, 0.5 * (S[:, 1] - S[:, 0]))
    D[0:M, N::] = UR
    # Lower left is diagonal matching of points from T
    UL = np.inf * np.ones((N, N))
    np.fill_diagonal(UL, 0.5 * (T[:, 1] - T[:, 0]))
    D[M::, 0:N] = UL
    # Lower right is all 0s by default (remaining diagonals match to diagonals)

    # Step 2: Perform a binary search + Hopcroft Karp to find the
    # bottleneck distance
    ds = np.sort(np.unique(D.flatten()))[0:-1]  # Everything but np.inf
    bdist = ds[-1]
    matching = {}
    while len(ds) >= 1:
        idx = 0
        if len(ds) > 1:
            idx = bisect_left(range(ds.size), int(ds.size / 2))
        d = ds[idx]
        graph = {}
        for i in range(D.shape[0]):
            graph["{}".format(i)] = {
                j
                for j in range(D.shape[1]) if D[i, j] <= d
            }
        res = HopcroftKarp(graph).maximum_matching()
        if len(res) == 2 * D.shape[0] and d <= bdist:
            bdist = d
            matching = res
            ds = ds[0:idx]
        else:
            ds = ds[idx + 1::]

    if return_matching:
        matchidx = []
        for i in range(M + N):
            j = matching["{}".format(i)]
            d = D[i, j]
            if i < M:
                if j >= N:
                    j = -1  # Diagonal match from first persistence diagram
            else:
                if j >= N:  # Diagonal to diagonal, so don't include this
                    continue
                i = -1
            matchidx.append([i, j, d])
        return bdist, np.array(matchidx)
    else:
        return bdist
示例#24
0
def bottleneck(dgm1, dgm2, matching=False):
    """
    Perform the Bottleneck distance matching between persistence diagrams.
    Assumes first two columns of S and T are the coordinates of the persistence
    points, but allows for other coordinate columns (which are ignored in
    diagonal matching).

    See the `distances` notebook for an example of how to use this.

    Parameters
    -----------
    dgm1: Mx(>=2) 
        array of birth/death pairs for PD 1
    dgm2: Nx(>=2) 
        array of birth/death paris for PD 2
    matching: bool, default False
        if True, return matching infromation and cross-similarity matrix

    Returns
    --------

    d: float
        bottleneck distance between dgm1 and dgm2
    (matching, D): Only returns if `matching=True`
        (tuples of matched indices, (N+M)x(N+M) cross-similarity matrix)
    """

    return_matching = matching

    S = np.array(dgm1)
    S = S[np.isfinite(S[:, 1]), :]
    T = np.array(dgm2)
    T = T[np.isfinite(T[:, 1]), :]

    N = S.shape[0]
    M = T.shape[0]

    # Step 1: Compute CSM between S and T, including points on diagonal
    # L Infinity distance
    Sb, Sd = S[:, 0], S[:, 1]
    Tb, Td = T[:, 0], T[:, 1]
    D1 = np.abs(Sb[:, None] - Tb[None, :])
    D2 = np.abs(Sd[:, None] - Td[None, :])
    DUL = np.maximum(D1, D2)

    # Put diagonal elements into the matrix, being mindful that Linfinity
    # balls meet the diagonal line at a diamond vertex
    D = np.zeros((N + M, N + M))
    D[0:N, 0:M] = DUL
    UR = np.max(D) * np.ones((N, N))
    np.fill_diagonal(UR, 0.5 * (S[:, 1] - S[:, 0]))
    D[0:N, M::] = UR
    UL = np.max(D) * np.ones((M, M))
    np.fill_diagonal(UL, 0.5 * (T[:, 1] - T[:, 0]))
    D[N::, 0:M] = UL

    # Step 2: Perform a binary search + Hopcroft Karp to find the
    # bottleneck distance
    N = D.shape[0]
    ds = np.sort(np.unique(D.flatten()))
    bdist = ds[-1]
    matching = {}
    while len(ds) >= 1:
        idx = 0
        if len(ds) > 1:
            idx = bisect_left(range(ds.size), int(ds.size / 2))
        d = ds[idx]
        graph = {}
        for i in range(N):
            graph["%s" % i] = {j for j in range(N) if D[i, j] <= d}
        res = HopcroftKarp(graph).maximum_matching()
        if len(res) == 2 * N and d < bdist:
            bdist = d
            matching = res
            ds = ds[0:idx]
        else:
            ds = ds[idx + 1::]

    if return_matching:
        matchidx = [(i, matching["%i" % i]) for i in range(N)]
        return bdist, (matchidx, D)
    else:
        return bdist
示例#25
0
# add identifiers to the labels to use when matching them
ground_truth['id'] = 'g' + ground_truth.index.astype(str)
turker_labels['id'] = 't' + turker_labels.index.astype(str)

# each graph is a dictionary with the key being the id of label in ground truth, and the value being
# a list of ids for labels in the turker label set that could be matched to it.
binary_graph = dict(zip(ground_truth.id, [[] for i in range(len(ground_truth))]))
multi_graph = dict(zip(ground_truth.id, [[] for i in range(len(ground_truth))]))

# binary: for every ground truth label, find which turker labels are less than 0.5 meters away
for row in ground_truth.iterrows():
	match = turker_labels.apply(lambda x: haversine(x.coords, row[1].coords) < 0.0025, axis=1)
	binary_graph[row[1].id].extend(turker_labels.id[match].values)

# compute maximum matching
binary_matching = HopcroftKarp(binary_graph).maximum_matching()

def precision(true_pos, false_pos):
	if true_pos > 0 or false_pos > 0:
		return true_pos / (1.0 * true_pos + false_pos)
	else:
		return float('NaN')

def recall(true_pos, false_neg):
	if true_pos > 0 or false_neg > 0:
		return true_pos / (1.0 * true_pos + false_neg)
	else:
		return float('NaN')

def f_measure(true_pos, false_pos, false_neg):
	P = precision(true_pos, false_pos)
示例#26
0
文件: 0.py 项目: qifanyyy/CLCDSA
from hopcroftkarp import HopcroftKarp

T = int(raw_input())

for t in range(T):
  N = int(raw_input())
  graph = {}
  aset = set()
  bs = set()
  for i in range(N):
    a, b = raw_input().split()
    b += '_'
    aset.add(a)
    bs.add(b)
    if a not in graph:
        graph[a] = set()
    graph[a].add(b)

  match = HopcroftKarp(graph).maximum_matching()
  r = len(match)/2
  print 'Case #%d: %d' % (t+1, N+r-len(aset)-len(bs))
示例#27
0
    fst = {}
    sec = {}
    words = []
    count1 = {}
    count2 = {}
    G = {}
    for _ in range(N):
        u, v = tuple(input().strip().split())
        u = '1' + u
        v = '2' + v
        if u not in count1:
            count1[u] = 1
        else:
            count1[u] += 1

        if v not in count2:
            count2[v] = 1
        else:
            count2[v] += 1

        if u in G:
            G[u].add(v)
        else:
            G[u] = {v}

    H = HopcroftKarp(G).maximum_matching()
    answer = N - (len(count1) + len(count2) - len(H) / 2)

    #print()
    print("Case #%d: %s" % (t + 1, answer))
                for neighbour in self.graph[vertex]:
                    if (vertex in left_star and neighbour in right_star) or \
                            (vertex in left_plus and neighbour in right_plus):
                        self.E_w.add((vertex, neighbour))

            graph_prime = {}
            for vertex in left_unlabelled:
                graph_prime[vertex] = set([neighbour for neighbour in self.graph[vertex] if neighbour in right_unlabelled])
            for vertex in right_unlabelled:
                graph_prime[vertex] = set([neighbour for neighbour in self.graph[vertex] if neighbour in left_unlabelled])
            self.edge_part_perfect(graph_prime, left_unlabelled, right_unlabelled)

        return self.E_1, self.E_w, self.E_0

# g = {'a': {1, 3}, 'b': {1, 2, 4}, 'c': {1, 3}, 'd': {3, 5, 6}, 'e': {5}, 'f': {4, 7},
#          'g': {5}, 1: {'a', 'b', 'c'}, 2: {'b'}, 3: {'a', 'b', 'c'}, 4: {'b', 'f', 'e'},
#          5: {'d', 'e', 'g'}, 6: {'d'}, 7: {'f'}}
# l = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}
# r = set(range(1, 8))

g = {'S1': {'a', 'b', 'c'}, 'S2': {'a', 'b', 'c'}, 'S3': {'a', 'b', 'c'}}
C = CostaImproved(g)
m = HopcroftKarp(g)
maximum_matching = m.maximum_matching()
E1, Ew, E0 = C.edge_partitioning()
#print('Bipartite graph: ' + str(m))
print('Maximum Matching:' + str(maximum_matching))
print('one-persistent edges: ' + str(E1))
print('weakly-persistent edges: ' + str(Ew))
print('zero-persistent edges: ' + str(E0))
示例#29
0
文件: 3.py 项目: qifanyyy/CLCDSA
def solve_large(board):
	N = len(board)
	row = [True] * N
	col = [True] * N
	diag = [True] * (2 * N - 1)
	rdiag = [True] * (2 * N - 1)
	for i in xrange(N):	#init flag arrays
		for j in xrange(N):
			if board[i][j] in ['x', 'o']:
				row[i] = False
				col[j] = False
			if board[i][j] in ['+', 'o']:
				diag[i + j] = False
				rdiag[i - j + N - 1] = False
	#construct bipartite graph
	graph = {}
	mid = N - 1
	for i in xrange(2 * N - 1):
		upper_bound = mid - abs(i - mid)
		edges = set()
		for j in xrange(i % 2, upper_bound + 1, 2):
			edges.add('b' + str(mid - j))
			edges.add('b' + str(mid + j))
		graph[i] = edges
	#black out already used places for '+' (or 'o')
	for i in xrange(2 * N - 1):
		if not diag[i]:
			del graph[i]
		if not rdiag[i]:
			for node in graph:
				graph[node].discard('b' + str(i))
	#get maximum matching
	max_matching = HopcroftKarp(graph).maximum_matching()
	for x in max_matching:
		if type(x) == int:
			continue
		rdiag_no = int(x[1:])
		diag_no = max_matching[x]
		i = (diag_no + rdiag_no + 1 - N) / 2
		j = diag_no - i
		if board[i][j] == '.':
			board[i][j] = '+'
		elif board[i][j] == 'x':
			board[i][j] = 'o'
		else:
			print 'maximum matching put + to an already o or + place, exitting...'
			exit()
		diag[diag_no] = rdiag[rdiag_no] = False
	#now put x to the board
	for i in xrange(N):
		if row[i]:
			for j in xrange(N):
				if col[j]:
					if board[i][j] == '.':
						board[i][j] = 'x'
					elif board[i][j] == '+':
						board[i][j] = 'o'
					else:
						print 'try to put x to an already o or x place, exitting...'
						exit()
					row[i] = col[j] = False
					break
	return
示例#30
0
# https://code.google.com/codejam/contest/11254486/dashboard#s=p2
from hopcroftkarp import HopcroftKarp
from collections import defaultdict
filein = open('20161BC.in', 'r')
fileout = open('20161BC.out', 'w')

T = int(filein.readline())

for t in range(T):
    N = int(filein.readline())

    graph = defaultdict(set)
    X, Y = set(), set()
    for i in range(N):
        x, y = filein.readline().split(' ')
        X.add(x)
        Y.add(y)
        graph[x].add(y)
    mm = HopcroftKarp(dict(graph)).maximum_matching()
    ans = N - (len(X) + len(Y) - len(mm)) - len(mm) / 2

    fileout.write('Case #%d: %s \n' % (t + 1, str(ans)))

filein.close()
fileout.close()