Untitled
unknown
python
2 years ago
8.5 kB
4
Indexable
# 8) Для размещения магазинов в торговом центре выделено 200 млн руб. и площадь 2 км2. На территории торгового # центра необходимо разместить магазины. Сгенерировать множество из 400 магазинов со следующими параметрами: # стоимость размещения магазина в интервале [10;20] млн руб.; посещаемость магазина [1;10] тыс. человек; # занимаемая магазином площадь в интервале [50;150] м2. Требуется найти комбинацию магазинов, обеспечивающих # максимальную посещаемость торгового центра. import random as rnd import matplotlib.pyplot as plt from random import randint, random # Ограниченное количество ресурсов BUDGET = 200 MALL_SQUARE = 2000000 # Параметры работы генетического алгоритма CHROMOSOME_SIZE = 400 POPULATION_SIZE = 400 P_CROSSOVER = 0.9 P_MUTATION = 0.01 MAX_GENERATIONS = 3000 # Параметры генератора случайных чисел RANDOM_SEED = 5 rnd.seed(RANDOM_SEED) class Furniture: def __init__(self): self.cost_placement = randint(10, 20) self.attendance = randint(1, 10) self.square = randint(50, 150) class FitnessMax(): def __init__(self): self.value = 0 class Individual(list): def __init__(self, *args): super().__init__(*args) self.fitness = FitnessMax() def one_max_fitness(individual): budget_expenses, square_expenses = get_budget_square_expenses(individual) attendance = get_attendance(individual) kb = 0 if budget_expenses < BUDGET else attendance ks = 0 if square_expenses < MALL_SQUARE else attendance fitness = attendance - kb * (budget_expenses - BUDGET) - ks * (square_expenses - MALL_SQUARE) return fitness def get_attendance(individual): attendance = 0 for gene in individual: if gene: attendance = attendance + gene.attendance return attendance def get_budget_square_expenses(individual): budget_expenses = 0 square_expenses = 0 for gene in individual: if gene: budget_expenses = budget_expenses + gene.cost_placement square_expenses = square_expenses + gene.square return budget_expenses, square_expenses def create_basic_set(): genes = [] for i in range(CHROMOSOME_SIZE): genes.append(Furniture()) return Individual(genes) def individual_creator(basic_set): genes = [] for i in range(CHROMOSOME_SIZE): if random() >= 0.5: genes.append(basic_set[i]) else: genes.append(None) return Individual(genes) def population_creator(basic_set, n=POPULATION_SIZE): return list([individual_creator(basic_set) for i in range(n)]) def clone(value): ind = Individual(value[:]) ind.fitness.value = value.fitness.value return ind def selection(population, basic_set): population.sort(key=lambda x: x.fitness.value, reverse=True) elite = population[:50] population = population_creator(basic_set) population[:50] = elite[:50] return population def crossover_two_point(child1, child2): point_1 = 0 point_2 = 0 while point_1 >= point_2: point_1 = randint(2, len(child1) - 3) point_2 = randint(2, len(child1) - 3) child1[point_1:point_2], child2[point_1:point_2] = child2[point_1:point_2], child1[point_1:point_2] def genetic_mutation(mutant, basic_set): for index in range(len(mutant)): if random() < P_MUTATION: mutant[index] = None if mutant[index] else basic_set[index] if __name__ == '__main__': best_individuals = [] basic_set = create_basic_set() population = population_creator(basic_set) generation_counter = 0 fitness_values = list(map(one_max_fitness, population)) for individual, fitness_value in zip(population, fitness_values): individual.fitness.value = fitness_value max_fitness_values = [] mean_fitness_values = [] min_budget_square_expenses_values = [] while generation_counter < MAX_GENERATIONS: generation_counter += 1 offspring = selection(population, basic_set) offspring = list(map(clone, offspring)) for child1, child2 in zip(offspring[::2], offspring[1::2]): if random() < P_CROSSOVER: crossover_two_point(child1, child2) fresh_fitness_values = list(map(one_max_fitness, offspring)) for individual, fitness_value in zip(offspring, fresh_fitness_values): individual.fitness.value = fitness_value population[:] = offspring fitness_values = [ind.fitness.value for ind in population] max_fitness = max(fitness_values) max_fitness_index = fitness_values.index(max_fitness) min_budget_square_expenses = get_budget_square_expenses(population[max_fitness_index]) mean_fitness = sum(fitness_values) / len(population) max_fitness_values.append(max_fitness) mean_fitness_values.append(mean_fitness) min_budget_square_expenses_values.append(min_budget_square_expenses) print( f"Поколение {generation_counter}: Макс приспособленность = {max_fitness}, Средняя приспособленность = {mean_fitness}") best_index = fitness_values.index(max(fitness_values)) best_individual = population[best_index] best_individuals.append(best_individual) print("Лучший индивидуум = ", *best_individual) budget_square_expenses = get_budget_square_expenses(best_individual) print(f"Потрачено: {budget_square_expenses[0]} млн руб, {budget_square_expenses[1]} м2") print(f"Посещения: {get_attendance(best_individual)} тыс человек") print() budget_expenses_values = [i[0] for i in min_budget_square_expenses_values] square_expenses_values = [i[1] for i in min_budget_square_expenses_values] plt.plot(max_fitness_values, color='red') plt.plot(mean_fitness_values, color='green') plt.legend(["Максимальная приспособленность, кол-во тыс", "Средняя приспособленность, кол-во тыс"]) plt.xlabel('Поколение, число') plt.ylabel('Макс/средняя приспособленность, кол-во тыс') plt.title('Зависимость максимальной и средней приспособленности от поколения') plt.grid() plt.show() plt.plot(budget_expenses_values, color='red') plt.plot(square_expenses_values, color='green') plt.legend(["Расход бюджета, млн руб", "Расход площади, м2"]) plt.xlabel('Поколение, число') plt.ylabel('Расход бюджета/площади, млн руб/м2') plt.title('Расход бюджета и площади от поколения') plt.grid() plt.show() best_individuals_chromosome_sum = [ sum(x is not None for x in chromosomes) for chromosomes in best_individuals] plt.plot(best_individuals_chromosome_sum) plt.xlabel('Поколение, число') plt.ylabel('Число единиц в хромосоме лучшего индивидуума, число') plt.title('Число ед-ц в хромосоме лучшего индивидуума в зав-ти от поколения') plt.grid() plt.show() best_individuals.sort(key=lambda x: x.fitness.value, reverse=True) best_individual = best_individuals[0] print("Лучший индивидуум за всё время = ", best_individual) budget_square_expenses = get_budget_square_expenses(best_individual) print(f"Потрачено: {budget_square_expenses[0]} млн руб, {budget_square_expenses[1]} м2") print(f"Посещения: {get_attendance(best_individual)} тыс человек") print()
Editor is loading...