# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import copy
import random
import os
from mpl_toolkits.mplot3d.axes3d import get_test_data
# This import registers the 3D projection, but is otherwise unused.
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 unused import
class SPEA2:
class solution:
def __init__(self, var_bounds, objective_functions):
self.variables = [random.uniform(bounds[0], bounds[1]) for bounds in var_bounds]
self.objectives = [function(self.variables) for function in objective_functions]
def dominated_by(self, sol_1, sol_2):
for i in range(self.objective_functions_dimensions):
if sol_2.objectives[i] > sol_1.objectives[i]:
return False
return True
def calculate_raw_fitness(self, population):
strength = np.zeros(self.length)
raw_fitness = np.zeros(self.length)
dominations = {}
for i in range(self.length):
dominations[i] = []
for j in range(self.length):
if i != j:
if not self.dominated_by(population[i], population[j]):
strength[i] = strength[i] + 1
else:
dominations[i].append(j)
for i in range(self.length):
for j in dominations[i]:
raw_fitness[i] = raw_fitness[i] + strength[j]
return raw_fitness
def calculate_fitness_and_distances(self, population, raw_fitness):
k_n = int(self.length**0.5) - 1
fitness = np.zeros(self.length)
all_distances = []
for i in range(self.length):
distances = []
for j in range(self.length):
if i != j:
sol_1 = population[i]
sol_2 = population[j]
distance = sum([(sol_1.objectives[i] - sol_2.objectives[i])**2 for i in range(self.objective_functions_dimensions)])**0.5
distances.append(distance)
distances.sort()
all_distances.append(distances)
fitness[i] = raw_fitness[i] + 1/(distances[k_n] + 2)
return fitness
def trim_archive(self, archive, fitness):
while len(archive) > self.archive_size:
all_distances = []
for i in range(len(archive)):
distances = []
for j in range(len(archive)):
if i != j:
sol_1 = archive[i]
sol_2 = archive[j]
distance = sum([(sol_1.objectives[i] - sol_2.objectives[i])**2 for i in range(self.objective_functions_dimensions)])
distances.append(distance)
distances.sort()
all_distances.append(distances)
k_n = 1
while True:
closest_n = min(all_distances[i][k_n] for i in range(len(all_distances)))
most_crowded = [i for i in range(len(all_distances)) if all_distances[i][k_n] == closest_n]
if len(most_crowded) == 1:
archive.pop(most_crowded[0])
fitness.pop(most_crowded[0])
break
else:
k_n = k_n + 1
return archive, fitness
def sort_population(self, population, fitness):
sorted_ids = np.argsort(fitness)
new_fitness = [fitness[sorted_ids[i]] for i in range(self.length)]
new_population = [population[sorted_ids[i]] for i in range(self.length)]
return new_population, new_fitness
class roulette_wheel:
def __init__(self, fitness, length):
self.length = length
SPEA2代码
最新推荐文章于 2024-03-05 20:33:32 发布