From 04d5f7f9a86101fcfda120ad15b1d5b7907ded6b Mon Sep 17 00:00:00 2001 From: Jose Miguel Garcia Date: Mon, 2 Mar 2020 20:23:50 +0100 Subject: [PATCH] Add pre local search algorithm --- graph_utils.py | 10 ++++++++++ solution_grasp.py | 37 ++++++++++++++++++++++++++++++++++++ test/solution_grasp_tests.py | 9 +++++++++ 3 files changed, 56 insertions(+) diff --git a/graph_utils.py b/graph_utils.py index 310dcf9..1a103ee 100644 --- a/graph_utils.py +++ b/graph_utils.py @@ -42,6 +42,16 @@ def is_clique(graph): return False return clique + @staticmethod + def is_clique_solution(graph, clique): + is_clique = True + for node in clique: + for node_to_compare in clique: + if graph.nodes[node].node_id != graph.nodes[node_to_compare].node_id: + if not GraphUtils.are_adjacent(graph.nodes[node_to_compare], graph.nodes[node]): + return False + return is_clique + @staticmethod def become_clique(graph, clique, node): is_clique = True diff --git a/solution_grasp.py b/solution_grasp.py index 850f571..6f46e68 100644 --- a/solution_grasp.py +++ b/solution_grasp.py @@ -5,6 +5,7 @@ import logging import random +from graph_utils import GraphUtils from solution_greedy_adjacent import SolutionGreedyNeighbors from solution_greedy_ratio import SolutionGreedyRatio @@ -63,3 +64,39 @@ def get_rcl(mu, gc): else: remaining_candidates = gc[:position].copy() return remaining_candidates + + # TODO complete and refactor + def apply_ls(self, graph, solution, name): + sol_copy = solution.copy() + ratio_neighbors = set() + for node in solution: + ratio_neighbors.update(graph.nodes[node].neighbors_indices) + o_ratio_neighbors = sorted(ratio_neighbors, key=lambda x: graph.nodes[x].p_weight / graph.nodes[x].q_weight, + reverse=True) + better_node = o_ratio_neighbors.pop(0) + to_delete = set() + for node in sol_copy: + if better_node not in graph.nodes[node].neighbors_indices and better_node != node: + to_delete.add(node) + sol_copy = sol_copy - to_delete + sol_copy.update({better_node}) + # + cliques = dict() + greedy_constructive = SolutionGreedyRatio(graph, name) + for node in sol_copy: + current_clique = greedy_constructive.find_clique(node) + if GraphUtils.is_clique_solution(graph, current_clique): + self.LOGGER.debug("is clique") + cliques.update({node: current_clique}) + final_clique = self.complete_clique(solution, sol_copy, cliques) + # FIXME logger + if GraphUtils.is_clique_solution(graph, final_clique): + self.LOGGER.debug("good solution") + else: + self.LOGGER.fatal("isn't a solution") + + def complete_clique(self, solution, clique_ls, cliques_neighbors): + final_clique = set() + for node, clique in cliques_neighbors.items(): + final_clique = final_clique.union(clique) + return final_clique diff --git a/test/solution_grasp_tests.py b/test/solution_grasp_tests.py index bf906b8..02fc85c 100644 --- a/test/solution_grasp_tests.py +++ b/test/solution_grasp_tests.py @@ -11,6 +11,7 @@ class SolutionGraspTests(unittest.TestCase): + GRAPH_TEST = 'test_files/set-e/DIMACS2/johnson8-2-4.txt' GRAPH_SIMPLE_1_TEST_PTH = 'test_files/test-graph-type-1.txt' def test_grasp_OK(self): @@ -56,6 +57,14 @@ def test_random(self): for k, v in a: print("clave= {0}: valor= {1}".format(k, v)) + def test_apply_ls(self): + solution = {16, 18, 19, 20, 21, 23} + graph = Instance() + file = SolutionGraspTests.GRAPH_TEST + graph.read_file(file) + instace_sol = SolutionGrasp() + instace_sol.apply_ls(graph, solution) + if __name__ == '__main__': unittest.main()