Ejemplo n.º 1
0
    def run(self, graph, demands):
        start_timer = time.time()
        self.logger.info("run an algorithm")

        self.current_graph = graph.copy()                  # context for current solution
        self.next_graph = graph.copy()                     # context for next solution
        self.allocator = SpectrumAllocator(self.current_graph)

        self.current_solution = self.create_first_solution(demands)
        self.allocate_solution(self.current_solution, self.current_graph)
        self.current_energy = calculate_graph_cost(self.current_graph)

        self.best_solution = copy_demands(self.current_solution)
        self.best_energy = self.current_energy

        while self.is_not_cold():
            self.logger.debug("temperature = %s", self.temperature)
            self.next_solution = self.create_new_solution(self.current_solution)
            self.allocate_solution(self.next_solution, self.next_graph)
            self.next_energy = calculate_graph_cost(self.next_graph)

            if self.next_energy < self.current_energy:
                self.logger.debug("better solution than current one founded with cost: %s", self.next_energy)
                self.accept_next()
                self.check_if_next_is_better_than_best()
            elif self.is_worse_solution_acceptable():
                self.logger.debug("worse solution than current accepted with cost: %s", self.next_energy)
                self.accept_next()
            self.cool_temperature()

        stop_timer = time.time()
        self.final_time = stop_timer - start_timer
Ejemplo n.º 2
0
 def setUp(self):
     parser = Parser("../test_data", "euro16_k2.txt")
     scenario = parser.get_scenario(2)
     graph = graph_factory(scenario.networkTopology)
     candidatePathFetcher = CandidatePathsFetcher(scenario.candidatePaths, len(graph.nodes), scenario.pathsLengths)
     # get path
     list_of_paths1 = candidatePathFetcher.fetch_candidates(0, 1)
     # 1, 6, 10
     self.path = list_of_paths1[1]
     self.edges = graph.edges
     self.sa = SpectrumAllocator(graph)
Ejemplo n.º 3
0
class SimulatedAnnealing:
    def __init__(self, temperature=1000, cooling_rate=0.1, minimal_temperature=1):
        self.logger = logging.getLogger(str(self.__class__))
        self.temperature = temperature
        self.cooling_rate = cooling_rate
        self.minimal_temperature = minimal_temperature
        self.best_solution = None
        self.best_energy = None
        self.current_solution = None
        self.next_solution = None
        self.current_energy = None
        self.next_energy = None
        self.allocator = None
        self.final_time = None
        self.logger.info("initialize algorithm")

        self.current_graph = None
        self.next_graph = None

    def run(self, graph, demands):
        start_timer = time.time()
        self.logger.info("run an algorithm")

        self.current_graph = graph.copy()                  # context for current solution
        self.next_graph = graph.copy()                     # context for next solution
        self.allocator = SpectrumAllocator(self.current_graph)

        self.current_solution = self.create_first_solution(demands)
        self.allocate_solution(self.current_solution, self.current_graph)
        self.current_energy = calculate_graph_cost(self.current_graph)

        self.best_solution = copy_demands(self.current_solution)
        self.best_energy = self.current_energy

        while self.is_not_cold():
            self.logger.debug("temperature = %s", self.temperature)
            self.next_solution = self.create_new_solution(self.current_solution)
            self.allocate_solution(self.next_solution, self.next_graph)
            self.next_energy = calculate_graph_cost(self.next_graph)

            if self.next_energy < self.current_energy:
                self.logger.debug("better solution than current one founded with cost: %s", self.next_energy)
                self.accept_next()
                self.check_if_next_is_better_than_best()
            elif self.is_worse_solution_acceptable():
                self.logger.debug("worse solution than current accepted with cost: %s", self.next_energy)
                self.accept_next()
            self.cool_temperature()

        stop_timer = time.time()
        self.final_time = stop_timer - start_timer

    def create_new_solution(self, demands):
        solution = copy_demands(demands)
        index = random.randint(0, len(demands) - 2)
        solution[index], solution[index+1] = solution[index+1], solution[index]
        demand = solution[index]
        if isinstance(demand, UnicastDemand):
            path_index = random.randint(0, demand.nr_of_paths - 1)
            demand.select_path(path_index)
        elif isinstance(demand, AnycastDemand):
            data_center_index = random.randint(0, demand.nr_of_data_centers - 1)
            path_up_index = random.randint(0, demand.nr_of_paths - 1)
            path_down_index = random.randint(0, demand.nr_of_paths - 1)
            demand.select_data_center_by_index(data_center_index)
            demand.select_path_up(path_up_index)
            demand.select_path_down(path_down_index)
        return solution

    def create_first_solution(self, demands):
        solution = []
        size_of_demands = len(demands)
        # todo: think how to remove redundancy
        demands = copy_demands(demands)
        while size_of_demands > 0:
            selected_demand_index = random.randint(0, size_of_demands - 1)
            demand = demands.pop(selected_demand_index)
            if isinstance(demand, UnicastDemand):
                path_index = random.randint(0, demand.nr_of_paths - 1)
                demand.select_path(path_index)
                solution.append(demand)
            elif isinstance(demand, AnycastDemand):
                data_center_index = random.randint(0, demand.nr_of_data_centers - 1)
                path_up_index = random.randint(0, demand.nr_of_paths - 1)
                path_down_index = random.randint(0, demand.nr_of_paths - 1)
                demand.select_data_center_by_index(data_center_index)
                demand.select_path_up(path_up_index)
                demand.select_path_down(path_down_index)
                solution.append(demand)
            size_of_demands -= 1
        return solution

    def allocate_solution(self, list_of_demands, context):
        """
        It allocates list of demands on graf provided by context
        :param list_of_demands:
        :param context:
        :return:
        """
        self.allocator.set_context(context)
        self.allocator.clear()
        for demand in list_of_demands:
            if isinstance(demand, UnicastDemand):
                path = demand.get_selected_path()
                self.allocator.allocate_first_free_spectrum_on_path(path)
            elif isinstance(demand, AnycastDemand):
                path_up = demand.get_selected_path_up()
                path_down = demand.get_selected_path_down()
                self.allocator.allocate_first_free_spectrum_on_path(path_up)
                self.allocator.allocate_first_free_spectrum_on_path(path_down)

    def accept_next(self):
        self.current_energy = self.next_energy
        self.current_solution = copy_demands(self.next_solution)      # copy

    def check_if_next_is_better_than_best(self):
        if self.next_energy < self.best_energy:
            self.logger.debug("new best solution found with cost: %s", self.next_energy)
            self.best_energy = self.next_energy
            self.best_solution = copy_demands(self.next_solution)       # copy

    def is_worse_solution_acceptable(self):
        probability = math.exp(-(self.next_energy - self.current_energy) * 1.0 / self.temperature)
        if probability > random.random():
            return True
        return False

    def cool_temperature(self):
        self.temperature *= 1 - self.cooling_rate

    def is_not_cold(self):
        return self.temperature > self.minimal_temperature
Ejemplo n.º 4
0
class SpectrumTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        logging.basicConfig(level=logging.DEBUG)

    def setUp(self):
        parser = Parser("../test_data", "euro16_k2.txt")
        scenario = parser.get_scenario(2)
        graph = graph_factory(scenario.networkTopology)
        candidatePathFetcher = CandidatePathsFetcher(scenario.candidatePaths, len(graph.nodes), scenario.pathsLengths)
        # get path
        list_of_paths1 = candidatePathFetcher.fetch_candidates(0, 1)
        # 1, 6, 10
        self.path = list_of_paths1[1]
        self.edges = graph.edges
        self.sa = SpectrumAllocator(graph)

    def test_normal_allocation(self):
        """
        following scenario: alloc 4
        edge 1 free
        edge 6 alloc 0, 1, 7
        edge 10 alloc 2, 7, 8
        :return: 3 to 7
        """
        spectrum_size = 4
        expected = [[0, 0, 0, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1, 1, 1], [0, 0, 1, 1, 1, 1, 1, 1, 1]]

        edge6 = self.edges[6]
        edge6.spectrum.allocate(0, 2)
        edge6.spectrum.allocate(7, 8)
        edge10 = self.edges[10]
        edge10.spectrum.allocate(2, 3)
        edge10.spectrum.allocate(7, 9)

        self.sa.allocate_first_free_spectrum_on_path(self.path, spectrum_size)
        self.print_edges()

        for value, edge_id in zip(expected, self.path.edges):
            self.assertListEqual(value, self.edges[edge_id].spectrum.spectrum)

    def test_moved_allocation(self):
        """
        following scenario: alloc 4
        edge 1 free
        edge 6 alloc 0, 1, 6, 7
        edge 10 alloc 2, 7, 8
        :return: 9, 13
        """

        spectrum_size = 4
        expected = [
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
            [1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1],
            [0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
        ]

        edge6 = self.edges[6]
        edge6.spectrum.allocate(0, 2)
        edge6.spectrum.allocate(6, 8)
        edge10 = self.edges[10]
        edge10.spectrum.allocate(2, 3)
        edge10.spectrum.allocate(7, 9)

        self.sa.allocate_first_free_spectrum_on_path(self.path, spectrum_size)
        self.print_edges()

        for value, edge_id in zip(expected, self.path.edges):
            self.assertListEqual(value, self.edges[edge_id].spectrum.spectrum)

    def print_edges(self):
        for edge_index in self.path.edges:
            print self.edges[edge_index]