Ejemplo n.º 1
0
    def _calculate_objectives(self):
        assert not (self.order and self.times),\
            "Pass order or times, but not both!"
        self.makespan = None
        self.min_sum = None
        self.local_min_sum = None
        if self.times:
            warning_printed = False
            self.order = calculate_order_from_times(self.times, self.graph)
            times, self.local_sum = calculate_times(self.order, self.graph, return_angle_sum=True)
            for key in times:
                try:
                    assert math.isclose(times[key], self.times[key], abs_tol=10**-5)
                except AssertionError as e:
                    if not warning_printed:
                        warning_printed = True
                        if self.solution_type == "min_sum":
                            if hasattr(self, "obj_val") and \
                               not math.isclose(sum(self.local_sum), self.obj_val):
                                print("Warning: Solution type is min_sum but minsum is mismatched: ",
                                      sum(self.local_sum), "vs:", self.obj_val)
                        print("Warning: Times are not matching:", times[key], self.times[key])
                        max_times = max([times[i] for i in times])
                        max_self_times = max([self.times[i] for i in self.times])
                        
                        if not math.isclose(max_times, max_self_times, abs_tol=10**-5):
                            print("And max times are also mismatched. Calculated:", max_times, " passed:", max_self_times)

        elif self.order:
            self.times, self.local_sum = calculate_times(self.order, self.graph, return_angle_sum=True)
        else:
            return
        self.makespan = max([self.times[key] for key in self.times])
        self.min_sum = sum(self.local_sum)
        self.local_min_sum = max(self.local_sum)
    def _calculate_order(self, solutions, graph):
        order = []
        had_duplicates = False
        if not self.greedy_glue:
            for sol in solutions:
                for edge in sol.order:
                    # ToDo: DELETE THIS DEBUG LINES
                    duplicate_edge = edge in order
                    had_duplicates = had_duplicates or duplicate_edge
                    # END DEBUG LINES
                order.extend([edge for edge in sol.order if edge not in order])
            times = calculate_times(order, graph)
        else:
            best_order = None
            best_angles = None
            best_times = None
            for sol in solutions:
                order = [edge for edge in sol.order]
                times = calculate_times(order, graph)
                angles = [0 for i in range(graph.vert_amount)]
                remaining_solutions = {
                    sol2
                    for sol2 in solutions if sol2 != sol
                }
                while remaining_solutions:
                    next_times = None
                    next_angles = None
                    next_sol = None

                    for sol2 in remaining_solutions:
                        second_order = [
                            edge for edge in sol2.order if edge not in order
                        ]
                        orders = [
                            second_order, [i for i in reversed(second_order)]
                        ]
                        for new_order in orders:
                            curr_times, angles = calculate_times(
                                new_order,
                                graph,
                                times=times.copy(),
                                return_angle_sum=True)
                            if next_times is None or sum(angles) < sum(
                                    next_angles):
                                next_times = curr_times
                                next_angles = angles
                                next_sol = sol2
                                next_order = new_order

                    angles = next_angles

                    times = next_times
                    order = order + next_order
                    remaining_solutions.remove(next_sol)
                if best_order is None or sum(angles) < sum(best_angles):
                    best_angles = angles
                    best_order = order
                    best_times = times
                return best_times
        return times
Ejemplo n.º 3
0
 def __call__(self, gen_algo: GeneticAlgorithm):
     data = []
     for genome in gen_algo.genomes:
         arg_sorted = np.argsort(genome.order_numbers)
         order = self.graph.edges[arg_sorted].tolist()
         times, head_sum = calculate_times(self.graph.edges[arg_sorted], angles=self.graph.costs, return_angle_sum=True)
         min_sum = sum(head_sum)
         local_min_sum = max(head_sum)
         sol = AngularGraphSolution(
             self.graph,
             0,
             gen_algo.solver,
             gen_algo.solution_type,
             is_optimal=False,
             order=order,
             error_message=None
         )            
         data.append({
             "Graph": self.graph.name,
             "Generation": gen_algo.generation,
             "solution_type": sol.solution_type,
             "solver": sol.solver,
             "min_sum": sol.min_sum,
             "local_min_sum": sol.local_min_sum,
             "makespan": sol.makespan
         })
         assert math.isclose(genome.solution, -sol.local_min_sum) or math.isclose(genome.solution, -sol.min_sum)
     self.dataFrame = self.dataFrame.append(DataFrame(data), ignore_index=True)
     update_callback(gen_algo)
Ejemplo n.º 4
0
def _inner_fitness_makespan(angles, edges, orders):
    results = np.zeros(len(orders), dtype=float)
    for i, order in enumerate(orders):
        arg_sort = np.argsort(order)
        times = calculate_times(edges[arg_sort], angles=angles)
        results[i] = -max([times[key] for key in times])
    return results
Ejemplo n.º 5
0
    def _get_candidate(self, order, remaining_edges, headings, angles):
        candidate_edge = None
        candidate_cost = None

        times = calculate_times(order, angles=angles)

        for edge in remaining_edges:
            new_order = order.copy()
            new_order.append(edge)
            max_time = 0
            vertex_set = set(edge)
            for index in vertex_set:
                other_index = vertex_set.difference([index]).pop()
                curr_prev = headings[index][-1] if headings[index] else None
                if curr_prev is not None:
                    angle = angles[index][(curr_prev, other_index)]
                    sorted_key = tuple(sorted([index, curr_prev]))
                    max_time = max([max_time, times[sorted_key] + angle])

            if ((candidate_cost is None) or
                (max_time < candidate_cost)) or ((candidate_cost == 0) and
                                                 (max_time > 0)):
                candidate_edge = edge
                candidate_cost = max_time
        return candidate_edge, candidate_cost
Ejemplo n.º 6
0
 def _get_cost(self,
               solution: Union[AngularGraphSolution, List],
               angles: Optional = None):
     if isinstance(solution, AngularGraphSolution):
         return solution.makespan
     times = calculate_times(solution, angles=angles)
     return sum([times[key] for key in times])
Ejemplo n.º 7
0
 def _get_cost(self,
               solution: Union[AngularGraphSolution, List],
               angles: Optional = None):
     if isinstance(solution, AngularGraphSolution):
         return solution.order, solution.min_sum
     times, heads = calculate_times(solution,
                                    return_angle_sum=True,
                                    angles=angles)
     return solution, sum(heads)
Ejemplo n.º 8
0
 def _get_cost(self,
               solution: Union[AngularGraphSolution, List],
               angles: Optional = None):
     if isinstance(solution, AngularGraphSolution):
         return solution.order, solution.makespan
     times, heads = calculate_times(solution,
                                    return_angle_sum=True,
                                    angles=angles)
     return solution, max([times[key] for key in times])
Ejemplo n.º 9
0
def _inner_fitness_local_min_sum(angles, edges, orders):
    results = np.zeros(len(orders), dtype=float)
    for i, order in enumerate(orders):
        arg_sort = np.argsort(order)
        times, head_sum = calculate_times(edges[arg_sort],
                                          angles=angles,
                                          return_angle_sum=True)
        results[i] = -max(head_sum)
    return results
Ejemplo n.º 10
0
 def _add_pre_solution(self, times, graph,
                       start_solution: Union[AngularGraphSolution,
                                             List[Tuple[int, int]]]):
     if start_solution:
         if not isinstance(start_solution, AngularGraphSolution):
             start_times = calculate_times(start_solution, graph)
         else:
             start_times = start_solution.times
         for key in times:
             times[key].Start = start_times[key]
 def _add_pre_solution(self, graph: Graph,
                       start_solution: Union[AngularGraphSolution,
                                             List[Tuple[int, int]]]):
     if start_solution is None:
         return
     if not isinstance(start_solution, AngularGraphSolution):
         times = calculate_times(start_solution, graph)
     else:
         times = start_solution.times
     for key in times:
         self.times[key].Start = times[key]
Ejemplo n.º 12
0
def _calculate_cost(solver, graph, new_order):
    times, heads = calculate_times(graph.edges[np.argsort(new_order)],
                                   graph,
                                   return_angle_sum=True)
    if solver.solution_type == "makespan":
        cost = max(times.values())
    elif solver.solution_type == "min_sum":
        cost = sum(heads)
    else:
        cost = max(heads)
    return cost
Ejemplo n.º 13
0
    def _calc_solution(self, graph, orientations, n, k, start_time):
        dep_graph = self._calculate_dependecy_graph(graph, orientations)
        order = self._calculate_order(dep_graph)
        times = calculate_times(order, graph)

        obj_val = (n - 2) * 180 + (360 / n) * k
        sol = AngularGraphSolution(graph,
                                   time.time() - start_time,
                                   self.__class__.__name__,
                                   "min_sum",
                                   times=times,
                                   obj_val=obj_val,
                                   sweep_order=order)
        return sol
Ejemplo n.º 14
0
    def _get_candidate(self, order, remaining_edges, headings, angles):
        candidate_edge = None
        candidate_cost = None

        for edge in remaining_edges:
            new_order = order.copy()
            new_order.append(edge)
            new_times = calculate_times(new_order, angles=angles)
            cost = max(new_times.values())
            if ((candidate_cost is None) or
                (cost < candidate_cost)) or ((candidate_cost == 0) and
                                             (cost > 0)):
                candidate_edge = edge
                candidate_cost = cost
        return candidate_edge, candidate_cost
Ejemplo n.º 15
0
 def _reconstruct_order(self):
     self.order = pickle.loads(self._sol)
     # This is just for older versions, where the solution was saved as multidict
     if isinstance(self.order, Multidict):
         self.times = self.order
         self.order = calculate_order_from_times(self.times, self.graph)
     else:
         self.times, self.local_sum = calculate_times(self.order, self.graph, return_angle_sum=True)
     self.makespan = None
     self.min_sum = None
     self.local_min_sum = None
     try:
         self.makespan = max(self.times.values())
         self.min_sum = sum(self.local_sum)
         self.local_min_sum = max(self.local_sum)
     except (TypeError, AttributeError):
         pass # can happen if a solution has an error
Ejemplo n.º 16
0
def _greedy_order(orders, graph: Graph, solver: Solver):
    results = []
    for orig_order in orders:
        arg_ordered = np.argsort(orig_order)
        ordered = orig_order[arg_ordered]
        inner_graph = Graph(graph.vertices, graph.edges[arg_ordered])
        order, cost = solver.solve(inner_graph, no_sol_return=True)
        edge_dict = {(o[0], o[1]): i for i, o in enumerate(graph.edges)}
        order_translate = {
            edge_dict[(e1, e2)]: i
            for i, (e1, e2) in enumerate(order)
        }
        new_order = np.array(
            [ordered[order_translate[key]] for key in range(len(orig_order))])
        times, heads = calculate_times(graph.edges[np.argsort(new_order)],
                                       graph,
                                       return_angle_sum=True)
        try:
            assert (graph.edges[np.argsort(new_order)] == order
                    ).all(), "Not all edges are sorted the same"
        except AssertionError as ar:
            print(ar)
        results.append((new_order, -cost))
    return results