SPEA2代码

# -*- 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值