I'm trying to solve the multiple knapsacks problem (MKP), in which I want to fit n
items into m
containers (knapsacks). Items have their weights and knapsacks capacity that they can hold.
I decided to solve it with genetic algorithm in Python using PyGAD. For that I expressed the problem with binary representation, but despite initial_population
being m
xn
, the solution it's looking for has only one knapsack (1xn
), so I get an error.
How to configure PyGAD to look for a m
-dimensional solution?
This is my code right now:
import numpy as np
import pygad
import random
knapsacks = np.array([7, 8])
items = np.array([3, 4, 5])
initial_population = np.array([
[1, 0, 0], # first knapsack
[0, 1, 0] # second knapsack
])
def fitness_func(solution, solution_idx):
# if sum of items in any knapsack exceeds capacity -> fail
if np.sum(np.sum(solution*items, axis=1) > knapsacks) != 0:
fitness = 10e4 # penalty
# if two items in one column -> fail (an item can't be in two knapsacks)
elif np.sum(np.argwhere(np.sum(initial_population, axis=0) > 1)):
fitness = 10e4 # penalty
else:
fitness = np.sum(solution*items)
# the higher fitness (sum of items) the better
return fitness
ga_instance = pygad.GA(
num_generations=30,
num_parents_mating=2,
fitness_func=fitness_func,
sol_per_pop=10,
num_genes=initial_population.size,
gene_space=[0, 1], # binary representation
mutation_by_replacement=True,
gene_type=int,
parent_selection_type="sss", # steady_state_selection()
keep_parents=1,
crossover_type="single_point",
mutation_type="random",
mutation_num_genes=1, # mutation_percent_genes=10,
initial_population=initial_population
)
ga_instance.run()
solution, solution_fitness, solution_idx = ga_instance.best_solution()