Untitled
unknown
plain_text
3 years ago
8.5 kB
11
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...