Пример #1
0
def compareSolution(fileName, sol, path, dropoff_mapping, list_locs,
                    output_directory):
    input_file = utils.read_file(fileName)
    #print('outputs/'+fileName[fileName.index('/')+1:fileName.index('.')+1]+'out')
    if os.path.exists('outputs/' + fileName[fileName.index('/') +
                                            1:fileName.index('.') + 1] +
                      'out'):
        output_file = utils.read_file('outputs/' +
                                      fileName[fileName.index('/') +
                                               1:fileName.index('.') + 1] +
                                      'out')
        file_cost = output_validator.tests(input_file, output_file, [])
        file_cost, meg = file_cost[0], file_cost[1]
        print(fileName, ": ", meg)
        if file_cost > sol:
            print("better solution found by ",
                  100 * (file_cost - sol) / file_cost, "%")
            output_file = utils.input_to_output(fileName, output_directory)
            convertToFile(convert_locations_to_indices(path, list_locs),
                          dropoff_mapping, output_file, list_locs)

    else:
        print('No previous solution.')
        output_file = utils.input_to_output(fileName, output_directory)
        convertToFile(convert_locations_to_indices(path, list_locs),
                      dropoff_mapping, output_file, list_locs)
Пример #2
0
def mst_dfs_solve(list_of_locations,
                  list_of_homes,
                  starting_car_location,
                  adjacency_matrix,
                  existing_mst=None,
                  params=[]):

    if not existing_mst:
        G, _ = adjacency_matrix_to_graph(adjacency_matrix)
        mst = nx.minimum_spanning_tree(G)
    else:
        mst = existing_mst

    seen = set()
    traversal = []

    def dfs(u):
        if u not in seen:
            traversal.append(u)
            seen.add(u)
            for v in mst.neighbors(u):
                if v not in seen:
                    dfs(v)
                    traversal.append(u)

    dfs(list_of_locations.index(starting_car_location))

    dropoffs = {home: [home] for home in list_of_homes}
    dropoffs = {
        list_of_locations.index(key):
        convert_locations_to_indices(dropoffs[key], list_of_locations)
        for key in dropoffs
    }
    return traversal, dropoffs
Пример #3
0
def runSolver(inputFile):
    input_data = utils.read_file(inputFile)
    params = []
    num_of_locations, num_houses, list_locations, list_houses, starting_car_location, adjacency_matrix = data_parser(
        input_data)
    result = solve(list_locations,
                   list_houses,
                   starting_car_location,
                   adjacency_matrix,
                   params=params)
    new_keys = convert_locations_to_indices(result[1].keys(), list_locations)
    new_dict = dict()
    old_keys = list(result[1].keys())
    for i in range(len(old_keys)):
        new_dict[new_keys[i]] = convert_locations_to_indices(
            result[1][old_keys[i]], list_locations)
    compareSolution(inputFile, result[2], result[0], new_dict, list_locations,
                    'outputs')
Пример #4
0
def solve_from_file(input_file, output_directory, params=[]):
    print('Processing', input_file)

    input_data = utils.read_file(input_file)
    num_of_locations, num_houses, list_locations, list_houses, starting_car_location, adjacency_matrix = data_parser(
        input_data)
    result = solve(list_locations,
                   list_houses,
                   starting_car_location,
                   adjacency_matrix,
                   params=params)
    new_keys = convert_locations_to_indices(result[1].keys(), list_locations)
    new_dict = dict()
    old_keys = list(result[1].keys())
    for i in range(len(old_keys)):
        new_dict[new_keys[i]] = convert_locations_to_indices(
            result[1][old_keys[i]], list_locations)
    compareSolution(input_file, result[2], result[0], new_dict, list_locations,
                    output_directory)
    print("Finished processing: ", input_file)
    """basename, filename = os.path.split(input_file)
Пример #5
0
def output(G, path, dropoffs):
    if path is None or len(dropoffs) == 0:
        raise Exception("<-- CUSTOM ERROR --> Invalid solver output.")
    indexPath = su.convert_locations_to_indices(path, G.locations)
    indexDropoffs = {}
    for key in dropoffs:
        k = G.locations.index(k) if k in G.locations else None
        v = G.locations.index(
            dropoffs[k]) if dropoffs[k] in G.locations else None
        if k is None or v is None:
            raise Exception("<-- CUSTOM ERROR --> Invalid location in output.")
        indexDropoffs[k] = v
    return indexPath, indexDropoffs
Пример #6
0
 def __init__(self, data):
     # [number_of_locations, number_of_houses, list_of_locations, list_of_houses, starting_location, adjacency_matrix]
     if data is None:
         return
     self.num_locations = data[0]
     self.num_houses = data[1]
     self.locations = data[2]
     self.houses = su.convert_locations_to_indices(data[3], self.locations)
     self.start = self.index(data[4])
     self.G = data[5]
     self.edge_list = self._edgeList()
     self.adjacency_list = self._adjacencyList()
     nparray = np.matrix(data[5])
     nparray[nparray == 'x'] = 0.0
     self.nxG = nx.from_numpy_matrix(nparray.astype(float))
 def __walking_constraints(self):
     # Boolean array of whether or not a location is a home by index
     H = (np.array(
         convert_locations_to_indices(self.list_of_locations,
                                      self.list_of_houses)) !=
          None).astype(int)
     # Check that each column i of walking_matrix sums up to H[i]
     for i in range(self.walking_matrix.shape[1]):
         self.model.addConstr(
             grb.quicksum(self.walking_matrix[:, i]) == H[i])
     # Check that we matched correct homes
     for vertex in range(len(self.walking_matrix)):
         self.model.addConstr(
             grb.quicksum(self.walking_matrix[vertex, :]) == grb.quicksum(
                 self.arrangement_matrix[
                     vertex, 1:self.arrangement_matrix.shape[1] - 1]))
Пример #8
0
def solve(list_of_locations,
          list_of_homes,
          starting_car_location,
          adjacency_matrix,
          params=[]):
    """
    Write your algorithm here.
    Input:
        list_of_locations: A list of locations such that node i of the graph corresponds to name at index i of the list
        list_of_homes: A list of homes
        starting_car_location: The name of the starting location for the car
        adjacency_matrix: The adjacency matrix from the input file
    Output:
        A list of locations representing the car path
        A dictionary mapping drop-off location to a list of homes of TAs that got off at that particular location
        NOTE: both outputs should be in terms of indices not the names of the locations themselves
    """
    locations = student_utils.convert_locations_to_indices(
        list_of_locations, list_of_locations)
    homes = student_utils.convert_locations_to_indices(list_of_homes,
                                                       list_of_locations)
    start = list_of_locations.index(starting_car_location)

    start_time = time.time()

    if params[0] == 'naive':
        car_path, drop_off = naive_solver(locations, homes, start,
                                          adjacency_matrix)
        print("--- %s seconds ---" % (time.time() - start_time))
        return car_path, drop_off
    elif params[0] == 'greedy':
        car_path, drop_off = greedy_solver(locations, homes, start,
                                           adjacency_matrix)
        print("--- %s seconds ---" % (time.time() - start_time))
        return car_path, drop_off
    elif params[0] == 'three_opt':
        car_path, drop_off = three_opt_solver(locations, homes, start,
                                              adjacency_matrix)
        print("--- %s seconds ---" % (time.time() - start_time))
        return car_path, drop_off
    elif params[0] == 'ant_colony':
        car_path, drop_off = ant_colony(locations, homes, start,
                                        adjacency_matrix)
        print("--- %s seconds ---" % (time.time() - start_time))
        return car_path, drop_off
    elif params[0] == 'greedy_clustering_three_opt':
        car_path, drop_off = greedy_clustering_three_opt(
            locations, homes, start, adjacency_matrix, int(params[1]))
        print("--- %s seconds ---" % (time.time() - start_time))
        return car_path, drop_off
    elif params[0] == 'mst':
        car_path, drop_off = mst_solver(locations, homes, start,
                                        adjacency_matrix)
        print("--- %s seconds ---" % (time.time() - start_time))
        return car_path, drop_off
    elif params[0] == 'two_opt':
        car_path, drop_off = two_opt_solver(locations, homes, start,
                                            adjacency_matrix)
        print("--- %s seconds ---" % (time.time() - start_time))
        return car_path, drop_off
    elif params[0] == 'greedy_clustering_two_opt':
        car_path, drop_off = greedy_clustering_two_opt(locations, homes, start,
                                                       adjacency_matrix,
                                                       int(params[1]))
        print("--- %s seconds ---" % (time.time() - start_time))
        return car_path, drop_off
    else:
        pass
Пример #9
0
def flp_solve(list_of_locations,
                  list_of_homes,
                  starting_car_location,
                  adjacency_matrix,
                  solve,
                  params=[]):
    mapping = defaultdict(int)
    for i in range(len(list_of_locations)):
        mapping[list_of_locations[i]] = i
    G, _ = adjacency_matrix_to_graph(adjacency_matrix)
    U = list_of_homes
    facilities = list_of_locations
    start = starting_car_location
    paths, distances = nx.floyd_warshall_predecessor_and_distance(G, weight='weight')
#     print(distances)
#     print(paths)
# print("ran all pairs")
    # Builds set S in polynomial time as opposed to powerset (exponential)
    def buildS():
        res = []
        for f in facilities:
            for s in range(1, len(U)):
                sorted_dist = sorted([(target, distances[mapping[f]][mapping[target]]) for target in U], key=lambda x: x[1])
                sorted_dist = sorted_dist[:s]
                A = set([t for t, _ in sorted_dist])
                cost = sum([s[1] for s in sorted_dist]) + (2/3) * distances[mapping[start]][mapping[f]]
                elem = {'facility': f, 
                        'A': A, 
                        'count': s, 
                        'cost': cost
                       } # facility, dictionary to see which elements are present, num elements, cost
                res.append(elem)
        return res
    S = buildS()
   # print("Built S")
    uncovered = set(U)
    lst = [(s['cost']/s['count'], hash(s['facility'] + str(s['count'])), s) for s in S]
    result = set([])
    dropoff_mapping = defaultdict(list)
    while uncovered and lst:
        smallest = min(lst, key = lambda x: x[0])
        lst.remove(smallest)
        smallest = smallest[2]
        result.add(smallest['facility'])
        dropoff_mapping[smallest['facility']] = list(smallest['A'])
        uncovered = uncovered.difference(smallest['A'])
        new_lst = []
        for _, h, elem in lst:
            if solve == 1:
                if elem['facility'] in result:
                    elem['cost'] -= distances[mapping[start]][mapping[elem['facility']]]
            if solve == 2:
                if elem['facility'] not in result:
                    elem['cost'] = sum([distances[mapping[s]][mapping[elem['facility']]] for s in elem['A']]) + (1/4) * sum([distances[mapping[r]][mapping[elem['facility']]] for r in result if r != start])
            intersect = len(elem['A'].intersection(uncovered))
            new_cost = float('inf')
            if intersect > 0:
                new_cost = elem['cost']/intersect
            new_lst.append((new_cost, h, elem))
        lst = new_lst
   # print("computed dropoffs")
    #finding path between all
    traversal = [mapping[start]]
    dists = [(distances[traversal[-1]][mapping[r]], mapping[r]) for r in list(result) if r != start]
    dropoffs = [mapping[start]] if start in result else []
   # print("computing traversal")
    def reconstruct_path(source, target, predecessors):
        if source == target:
            return []
        prev = predecessors[source]
        curr = prev[target]
        path = [target, curr]
        while curr != source:
            curr = prev[curr]
            path.append(curr)
        return list(reversed(path))
        
    while dists:
        n = min(dists, key= lambda x: x[0])
        dists.remove(n)
        n = n[1]
        dropoffs.append(n)
        traversal.extend(reconstruct_path(traversal[-1], n, paths)[1:])
        dists = [(distances[traversal[-1]][r], r) for _, r in dists]
    traversal.extend(reconstruct_path(traversal[-1], mapping[start], paths)[1:]) 
   # print("done")
#     dropoffs_dict = {key: dropoff_mapping[key] for key in dropoff_mapping}
    dropoffs_dict = defaultdict(list)
    for h in convert_locations_to_indices(list_of_homes, list_of_locations):
        minValue = float('inf')
        minVertex = mapping[start]
        for i in traversal:
            if distances[h][i] < minValue:
                minValue = distances[h][i]
                minVertex = i
        dropoffs_dict[minVertex].append(h)
    dropoffs_dict = {key: dropoffs_dict[key] for key in dropoffs_dict}
    return traversal, dropoffs_dict