Код: Выделить всё
# Set parameters
num_demand_points = 2130
num_stations = 46
p = 10
weights = [1 for _ in range(num_demand_points)]
# Helper function to repair an individual
def repair(individual):
while sum(individual) < p:
idx = random.choice([i for i, x in enumerate(individual) if x == 0])
individual[idx] = 1
while sum(individual) > p:
idx = random.choice([i for i, x in enumerate(individual) if x == 1])
individual[idx] = 0
return individual
# Generate initial population with p stations
def generate_initial_population(size):
population = set()
while len(population) < size:
individual = [0] * num_stations
indices = list(range(num_stations))
random.shuffle(indices)
selected_indices = indices[:p]
for idx in selected_indices:
individual[idx] = 1
population.add(tuple(individual))
return [list(ind) for ind in population]
# Fitness Function
def fitness(individual, distance_matrix):
total_distance = 0
for demand_point_index in range(num_demand_points):
min_distance = float('inf')
for station_index in range(num_stations):
if individual[station_index] ==1:
min_distance = min(min_distance, distance_matrix[demand_point_index][station_index])
total_distance += weights[demand_point_index] * min_distance
return total_distance
# Sort fitness
def sort_fitness(population, fitnesses):
sorted_index = np.argsort(fitnesses)
sorted_population = [population[i] for i in sorted_index]
sorted_fitness = [fitnesses[i] for i in sorted_index]
print (f"Fitness: {sorted_fitness[:5]}")
return sorted_population, sorted_fitness
# Evaluation function
def evaluation(population):
#Calculate fitness value for each chromosome
pop_fitness = [fitness(individual, distance_matrix) for individual in population]
#Sort population by fitness
population_sorted, fitness_sorted = sort_fitness(population, pop_fitness)
return population_sorted, fitness_sorted
# Roulette Wheel Selection
def roulette_wheel_select(population, fitnesses, selection_percentage):
num_parents = int(len(population) * selection_percentage)
num_parents = max(num_parents, 2)
# Transform fitness values for minimization
inverted_fitness = [1 / f for f in fitnesses]
# Calculate total fitness
total_fitness = sum(inverted_fitness)
# Calculate selection probabilities
selection_probs = [f / total_fitness for f in inverted_fitness]
# Perform roulette wheel selection
cumulative_probs = [sum(selection_probs[:i+1]) for i in range(len(selection_probs))]
new_population = []
for _ in range(num_parents):
r = random.random()
for i, individual in enumerate(population):
if r population_size:
population_sort = population_sort[:population_size]
fitness_sort = fitness_sort[:population_size]
best_individual, best_fitness = population_sort[0], fitness_sort[0]
print(f"Generation {generation} - Min: {best_fitness} - CS: {population_sort[:5]} - FS : {fitness_sort[:5]} - PL:{len(children)}")
# Record improvement in best fitness
new_best = fitness_sort[0]
if best == new_best:
no_improvement_count+=1
else:
no_improvement_count = 0
generation +=1
print(f"Best individual: {best_individual}, Best fitness: {best_fitness}")
введите здесь описание изображения
Кроме того, поскольку для анализа у меня будут разные операторы частоты мутаций и выбора, на данный момент они исправлены и не должны меняться. Спасибо.
Подробнее здесь: https://stackoverflow.com/questions/787 ... p-and-down