示例#1
0
def fitness(p, x_train, y_train, x_test, y_test):
    # Init fitness
    fitness_indi = 0
    N = Individual()
    p = N.individual_decode(p)
    N = N.individual_model(p,
                           num_class=2,
                           x_train=x_train,
                           y_train=y_train,
                           x_test=x_test,
                           y_test=y_test)

    fitness_indi = N.evaluate(x=x_test, y=y_test, verbose=0)[1]
    return fitness_indi
    def crossover(self, parent_1: Individual,
                  parent_2: Individual) -> Individual:
        """Crossover two parents using the Periodic crossover with Intersections (PIX) algorithm,
        as defined in Vidal et al. (2011)."""
        # logger.debug("Beginning crossover")
        # logger.debug(f"Par 1 chrom: {parent_1.giant_tour_chromosome}")
        # logger.debug(f"Par 2 chrom: {parent_2.giant_tour_chromosome}")
        child_vehicle_type_chromosome: Union[None, Dict[int, List[int]]] = {}
        child_giant_tour_chromosome: Dict[int, List[Location]] = {}
        for vehicle_type in self.possible_vehicle_types:
            child_giant_tour_chromosome[vehicle_type.data_index] = []

        num_vehicle_types = len(self.possible_vehicle_types)

        # Step 0: Inheritance Rule
        # Figure out which tours are inherited from P1, which from P2 and which others are mixed
        # In Vidal's paper, the tours are per-period and per-depot, so each pairing needs to be accounted for.
        # In my implementation, there are only the vehicle_index types to account for.
        if num_vehicle_types > 1:
            cuts = sample(range(num_vehicle_types), 2)
            if cuts[0] < cuts[1]:
                n_1 = cuts[0]
                n_2 = cuts[1]
            else:
                n_1 = cuts[1]
                n_2 = cuts[0]

            # Put the vehicle_index types into a randomly ordered list
            vehicle_type_list = list(self.possible_vehicle_types)
            shuffle(vehicle_type_list)

            # Divide up the vehicle_index types into the sets to be inherited
            set_1 = vehicle_type_list[0:n_1]
            set_2 = vehicle_type_list[n_1:n_2]
            set_mix = vehicle_type_list[n_2:num_vehicle_types]
        else:
            # If there is only one vehicle type, it goes into the mixed set
            set_1 = []
            set_2 = []
            set_mix = list(self.possible_vehicle_types)
        # logger.debug(f"Crossover sets: {set_1},\t{set_2},\t{set_mix}")

        # Step 1: Inherit data from P1
        # Set 1 inherits the whole tours
        for vehicle_type in set_1:
            if parent_1.giant_tour_chromosome.get(
                    vehicle_type.data_index) is None:
                continue

            child_giant_tour_chromosome[vehicle_type.data_index] = \
                [copy(stop) for stop in parent_1.giant_tour_chromosome[vehicle_type.data_index]]
            for child in child_giant_tour_chromosome[vehicle_type.data_index]:
                append_to_chromosome(child_vehicle_type_chromosome,
                                     child.data_index, vehicle_type, False)
        # Mixed set inherits pieces of the tours
        for vehicle_type in set_mix:
            if parent_1.giant_tour_chromosome.get(
                    vehicle_type.data_index) is None:
                continue

            tour_length = len(
                parent_1.giant_tour_chromosome[vehicle_type.data_index])

            cut_a = randint(0, tour_length)
            cut_b = cut_a
            if tour_length > 1:
                while cut_b == cut_a:
                    # logger.debug(f"{tour_length}: {cut_a}, {cut_b}")
                    cut_b = randint(0, tour_length)

            if cut_a < cut_b:
                child_tour = [
                    copy(stop) for stop in parent_1.giant_tour_chromosome[
                        vehicle_type.data_index][cut_a:cut_b]
                ]
            else:
                child_tour = [
                    copy(stop) for stop in [
                        *parent_1.giant_tour_chromosome[
                            vehicle_type.data_index][0:cut_b],
                        *parent_1.giant_tour_chromosome[
                            vehicle_type.data_index][cut_a:tour_length]
                    ]
                ]

            child_giant_tour_chromosome[vehicle_type.data_index] = child_tour

            for child in child_giant_tour_chromosome[vehicle_type.data_index]:
                append_to_chromosome(child_vehicle_type_chromosome,
                                     child.data_index, vehicle_type, False)

        # logger.debug(f"Data inherited from P1")
        # all_stops = [stop_t for vehicle_type_t in [*set_1, *set_mix] for stop_t in
        #              parent_1.giant_tour_chromosome.get(vehicle_type_t.data_index)]
        # if len(child_giant_tour_chromosome.keys()) == 0 and len(all_stops) > 0:
        #     raise ValueError(f"No keys in child chromosome. All stops {all_stops}")

        # Step 2: Inherit data from P2
        # For all vehicle_index types in set 2 and mix, loop through the customers in parent 2.
        # If the customer either has a matching vehicle_index type or none in the child's vehicle_index chromosome,
        # add it to this type's tour. Recall that the vehicle_index types are in a random order in the sets.
        # This allows customers to be reassigned between vehicle_index types, while vaguely keeping the parent's order.
        for vehicle_type in [*set_2, *set_mix]:
            if parent_2.giant_tour_chromosome.get(vehicle_type.data_index):
                for stop in parent_2.giant_tour_chromosome[
                        vehicle_type.data_index]:
                    customer_vehicles = child_vehicle_type_chromosome.get(
                        stop.data_index)
                    if customer_vehicles is None or vehicle_type in customer_vehicles:
                        append_to_chromosome(child_giant_tour_chromosome,
                                             vehicle_type.data_index, stop)
                        append_to_chromosome(child_vehicle_type_chromosome,
                                             stop.data_index, vehicle_type,
                                             False)

        # logger.debug(f"Data inherited from P2")

        # logger.debug(f"Child chrom: {child_giant_tour_chromosome}")

        # Step 3: Complete customer services
        child = Individual(
            child_giant_tour_chromosome,
            vehicle_type_chromosome=child_vehicle_type_chromosome,
            possible_locations=self.possible_locations)
        # child.update_all_routes_location_indices()
        # child.complete_customer_services(self.allow_split_deliveries)

        # if len(child_giant_tour_chromosome.keys()) == 0:
        #     raise ValueError(f"No keys in child chromosome.")

        # child.complete_customer_services_slow()
        child.evaluate()

        # logger.debug(f"Completed customer services")

        # Create and return the child
        return child