def get_variable_length_route(self) -> Route:
        # Generates a route between random stations, but keeps track of sations inbetween, so that we attempt
        #   to avoid duplicated stations. On avg gives wtt=1000, but the length of the route varies - no idea
        #   how to work with that
        r = Route(self)
        unused_stations = set(list(range(1, len(self.stations) + 1)))

        def _take_one_from_unused(remove=True) -> int:
            elem = random.choice(tuple(unused_stations))
            if remove:
                unused_stations.remove(elem)

            return elem

        stops = [self.stations[_take_one_from_unused() - 1]]

        while len(unused_stations) != 0:
            st_from = stops[-1]
            st_to = self.stations[_take_one_from_unused(False) - 1]

            info = get_path_info(self.graph, self.stations, st_from, st_to)
            for s in info["stations"]:
                unused_stations.discard(s.id)
                stops.append(s)

        r.route_stops = stops
        r.build_spf()

        return r
    def inversion_mutation(offspring: list) -> list: # aka IVM
        mutated_offspring = []

        for o in offspring:
            route_len = len(o.route_stops)

            cutoff_1 = random.randrange(route_len + 1)
            cutoff_2 = random.randrange(route_len + 1)

            cut_start = min(cutoff_1, cutoff_2)
            cut_end = max(cutoff_1, cutoff_2)

            cut_route = list(reversed(o.route_stops[cut_start:cut_end]))

            leftovers = o.route_stops[:cut_start] + o.route_stops[cut_end:]
            try:
                insert_at = random.randrange(len(leftovers))
            except:
                insert_at = 0

            mutated_o = Route(RouteManager.INSTANCE)
            mutated_o.route_stops = leftovers[:insert_at] + cut_route + leftovers[insert_at:]

            mutated_o.build_spf()

            mutated_offspring.append(mutated_o)

        return mutated_offspring
    def get_fixed_length_route(self) -> Route:
        # Always gets a route of fixed length of #total stations, but definitely has a lot of duplicate
        #   stations en-route. On avg gives wtt=3000, but it is the best option for crossover methods
        r = Route(self)

        mixed_stops = list(range(1, len(self.stations) + 1))
        random.shuffle(mixed_stops)

        r.route_stops = [self.stations[x - 1] for x in mixed_stops]
        r.build_spf()

        return r
    def swap_mutation(offspring: list) -> list: # aka EM
        mutated_offspring = []

        for o in offspring:
            route_len = len(o.route_stops)

            swap_pos_1 = random.randrange(route_len)
            swap_pos_2 = random.randrange(route_len)

            mutated_o = Route(RouteManager.INSTANCE)
            mutated_o.route_stops = [ s for s in o.route_stops]

            temp = mutated_o.route_stops[swap_pos_1]
            mutated_o.route_stops[swap_pos_1] = mutated_o.route_stops[swap_pos_2]
            mutated_o.route_stops[swap_pos_2] = temp 

            mutated_offspring.append(mutated_o)

        return mutated_offspring
Beispiel #5
0
    return f"{hour}:{str(minute).rjust(2,'0')}"


if __name__ == "__main__":
    stations = load_stations_from_file()
    rm = RouteManager(stations)

    # The best route with wtt=522, tournament selection, ordered crossover, simple_inversion mutation
    #   ADJUSTED NOTES: put 10 right after 14, to have less transfers and walking around
    best_route = Route(rm)
    best_route.route_stops = [
        stations[id - 1] for id in [
            20, 21, 22, 23, 24, 25, 26, 27, 29, 60, 59, 57, 58, 61, 62, 63, 49,
            28, 41, 38, 39, 40, 42, 47, 48, 46, 45, 44, 43, 52, 55, 56, 54, 53,
            51, 50, 11, 12, 70, 71, 69, 68, 67, 66, 65, 64, 13, 31, 33, 34, 37,
            36, 35, 32, 30, 16, 19, 18, 17, 15, 14, 10, 9, 8, 7, 6, 5, 4, 3, 2,
            1
        ]
    ]
    best_route.build_spf()

    print(
        f"Route's wtt={best_route.get_wtt()}, fitness={best_route.get_fitness()}"
    )

    time_offset = 420  # We want to start the route at 7:00am <=> 420 minutes into the day
    t = 0

    for s in range(len(best_route.route_stops)):
Beispiel #6
0
    def cycle_crossover(mating_pool : list, offspring_len=1000) -> list: # aka (CX)
        offspring = []

        for i in range(0, offspring_len, 2):
            parent_1 = random.choice(mating_pool)
            parent_2 = random.choice(mating_pool)

            #print("\nParents:")
            #print([s.id for s in parent_1.route_stops])
            #print([s.id for s in parent_2.route_stops])

            offspring_1 = Route(RouteManager.INSTANCE)
            offspring_2 = Route(RouteManager.INSTANCE)

            offspring_1.route_stops = [ None for s in parent_1.route_stops ]
            offspring_2.route_stops = [ None for s in parent_1.route_stops ]

            i_1 = 0
            while True:
                offspring_1.route_stops[i_1] = parent_1.route_stops[i_1]
                lookup = parent_2.route_stops[i_1]

                for i in range(len(parent_1.route_stops)):
                    if parent_1.route_stops[i].id == lookup.id:
                        i_1 = i
                        break

                if i_1 == 0:
                    break

            i_2 = 0
            while True:
                offspring_2.route_stops[i_2] = parent_2.route_stops[i_2]
                lookup = parent_1.route_stops[i_2]

                for i in range(len(parent_2.route_stops)):
                    if parent_2.route_stops[i].id == lookup.id:
                        i_2 = i
                        break

                if i_2 == 0:
                    break

            for i in range(len(parent_1.route_stops)):
                if offspring_1.route_stops[i] == None:
                    offspring_1.route_stops[i] = parent_2.route_stops[i]

                if offspring_2.route_stops[i] == None:
                    offspring_2.route_stops[i] = parent_1.route_stops[i]

            offspring_1.build_spf()
            offspring_2.build_spf()

            #print("Offspring:")
            #print([s.id if s != None else None for s in offspring_1.route_stops])
            #print([s.id if s != None else None for s in offspring_2.route_stops])

            offspring.append(offspring_1)
            offspring.append(offspring_2)

        return offspring
Beispiel #7
0
    def ordered_crossover(mating_pool : list, offspring_len=1000) -> list: # aka (OX)
        offspring = []

        for i in range(0, offspring_len, 2):
            parent_1 = random.choice(mating_pool)
            parent_2 = random.choice(mating_pool)

            #print("\nParents:")
            #print([s.id for s in parent_1.route_stops])
            #print([s.id for s in parent_2.route_stops])

            route_len = len(parent_1.route_stops)

            offspring_1 = Route(RouteManager.INSTANCE)
            offspring_2 = Route(RouteManager.INSTANCE)

            offspring_1.route_stops = [ None for s in parent_1.route_stops ]
            offspring_2.route_stops = [ None for s in parent_1.route_stops ]

            cutoff_1 = random.randrange(route_len + 1)
            cutoff_2 = random.randrange(route_len + 1)

            cut_start = min(cutoff_1, cutoff_2)
            cut_end = max(cutoff_1, cutoff_2)

            #print("Cuts:")
            #print(cut_start, cut_end)

            # Exchange the cutodd point
            for i in range(cut_start, cut_end):
                offspring_1.route_stops[i] = parent_1.route_stops[i]
                offspring_2.route_stops[i] = parent_2.route_stops[i]

            j_1 = cut_end % route_len
            j_2 = cut_end % route_len

            for i in range(route_len):
                i_conv = (cut_end + i) % route_len

                route_stop_1 = parent_1.route_stops[i_conv]
                route_stop_2 = parent_2.route_stops[i_conv]

                if not offspring_2.has_station(route_stop_1):
                    offspring_2.route_stops[j_2] = route_stop_1
                    j_2 = (j_2 + 1) % route_len

                if not offspring_1.has_station(route_stop_2):
                    offspring_1.route_stops[j_1] = route_stop_2
                    j_1 = (j_1 + 1) % route_len

            offspring_1.build_spf()
            offspring_2.build_spf()

            #print("Offspring:")
            #print([s.id for s in offspring_1.route_stops])
            #print([s.id for s in offspring_2.route_stops])

            offspring.append(offspring_1)
            offspring.append(offspring_2)

        return offspring