iT邦幫忙

0

python 畫圖

  • 分享至 

  • xImage
import pandas as pd
import numpy as np
import random
import socket
from enum import Enum
import matplotlib.pyplot as plt
HOST = '127.0.0.1'
PORT = 8888

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   
s.connect((HOST, PORT))                                

class CrossoverType(Enum):
    single = 1
    double = 2
    more = 3
    
class MutationType(Enum):
    Inversion = 1
    Insertion = 2
    Displacement = 3
    ReciprocalExchange = 4
    
class SelectionType(Enum):
    Deterministic = 1
    Stochastic= 2
    
class GeneticAlgorithm:
    def __init__(self,pop_size,number_of_genes,selection_type,
                 crossover_type,crossover_rate,mutation_type,mutation_rate,
                 ):
        
        self.pop_size = pop_size                               
        self.selection_type = selection_type
        self.crossover_size = int(pop_size*crossover_rate)
        if(self.crossover_size%2==1):                           
            self.crossover_size -= 1;                           
        self.mutation_size =  int(pop_size*mutation_rate)
        self.total_size = self.pop_size+self.mutation_size+self.crossover_size  
        self.number_of_genes = number_of_genes                  
        self.crossover_type = crossover_type
        self.crossover_rate = crossover_rate
        self.mutation_type = mutation_type
        self.mutation_rate = mutation_rate
        
        
    def initialize(self):
        self.selected_chromosomes = np.zeros((self.pop_size,self.number_of_genes))              
        self.indexs = np.arange(self.total_size)                                                #如果np.arrange(5),輸出為array([0,1,2,3,4])
        self.chromosomes = np.zeros((self.total_size,self.number_of_genes),dtype=int)           
        for i in range(self.pop_size):
            rtv = [random.randint(0,1) for _ in range(self.number_of_genes)]
            for j in range(self.number_of_genes):  
                self.chromosomes[i][j] = rtv[j]                  
        self.fitness = np.zeros(self.total_size)            
        self.objective_values = np.zeros(self.total_size)
        self.best_chromosome = np.zeros(self.number_of_genes,dtype=int)
        self.best_fitness = 0
        
    def evaluate_fitness(self):
        for i,chromosome in enumerate(self.chromosomes[:self.pop_size]):      
            self.objective_values[i] = self.countbyflexsim(chromosome) 
            
    def update_best_solution(self):
        best_index = np.argmin(self.objective_values)        
        if(self.best_fitness < self.objective_values[best_index]):
            self.best_fitness = self.objective_values[best_index]    
            for i,gene in enumerate(self.chromosomes[best_index]):
                self.best_chromosome[i] = gene

    def countbyflexsim(self,scenario):
        list = scenario.tolist()
        scenario_str = str(list)[1:-1] 
        s.send(scenario_str.encode())
        indata = s.recv(1024)
        indata = indata.decode()
        indata = indata.strip()                              
        indata = indata.strip(',')                           
        indata = float(indata)
        return indata   
    
    def shuffle_index(self,length):
        for i in range(length):
            self.indexs[i] = i
        np.random.shuffle(self.indexs[:length]) 
            
    def perform_crossover_operation(self):
        self.shuffle_index(self.pop_size) 
        
        child1_index = self.pop_size
        child2_index = self.pop_size+1      
        count_of_crossover = int(self.crossover_size/2) 
        for i in range(count_of_crossover):
            parent1_index = self.indexs[i]      
            parent2_index  = self.indexs[i+1]   
            
            if(self.crossover_type == CrossoverType.single):
                self.single_point_crossover(parent1_index,parent2_index,child1_index,child2_index)
                self.objective_values[child1_index] = self.countbyflexsim(self.chromosomes[child1_index])
                self.objective_values[child2_index] = self.countbyflexsim(self.chromosomes[child2_index])
            elif(self.crossover_type == CrossoverType.double):
                self.double_point_crossover(parent1_index,parent2_index,child1_index,child2_index)
                self.objective_values[child1_index] = self.countbyflexsim(self.chromosomes[child1_index])
                self.objective_values[child2_index] = self.countbyflexsim(self.chromosomes[child2_index])
            else:
                self.more_point_crossover(parent1_index,parent2_index,child1_index,child2_index)
                self.objective_values[child1_index] = self.countbyflexsim(self.chromosomes[child1_index])
                self.objective_values[child2_index] = self.countbyflexsim(self.chromosomes[child2_index])
        
            child1_index +=2
            child2_index +=2
    def single_point_crossover(self,p1,p2,c1,c2):
        self.chromosomes[c1] = self.chromosomes[p1]
        self.chromosomes[c2] = self.chromosomes[p2]
        cross_point = np.random.randint(1,self.number_of_genes) 
        self.chromosomes[c1][cross_point:] = self.chromosomes[p2][cross_point:] 
        self.chromosomes[c2][cross_point:] = self.chromosomes[p1][cross_point:]
    
    def double_point_crossover(self,p1,p2,c1,c2):
        self.chromosomes[c1] = self.chromosomes[p1]
        self.chromosomes[c2] = self.chromosomes[p2]
        index = []
        ran = random.sample(range(0,self.number_of_genes),2)
        for i in ran:
            index.append(i)
        index.sort()
        self.chromosomes[c1][index[0]:index[1]] = self.chromosomes[p2][index[0]:index[1]]
        self.chromosomes[c2][index[0]:index[1]] = self.chromosomes[p1][index[0]:index[1]]

    def more_point_crossover(self,p1,p2,c1,c2):
        self.chromosomes[c1] = self.chromosomes[p1]
        self.chromosomes[c2] = self.chromosomes[p2]
        index = []
        ran = random.sample(range(0,self.number_of_genes),3)
        for i in ran:
            index.append(i)
        index.sort()
        self.chromosomes[c1][index[0]:index[1]] = self.chromosomes[p2][index[0]:index[1]]
        self.chromosomes[c1][index[2]:self.number_of_genes] = self.chromosomes[p2][index[2]:self.number_of_genes]
        self.chromosomes[c2][index[0]:index[1]] = self.chromosomes[p1][index[0]:index[1]]
        self.chromosomes[c2][index[2]:self.number_of_genes] = self.chromosomes[p1][index[2]:self.number_of_genes]


        
    def do_roulette_wheel_selection(self,fitness_list):
        sum_fitness = sum(fitness_list)
        transition_probability = [fitness/sum_fitness for fitness in fitness_list]
        
        rand = random.random() #輸出為0-1範圍的實數
        sum_prob = 0
        for i,prob in enumerate(transition_probability):
            sum_prob += prob
            if(sum_prob>=rand): #當第一個位置的機率條件符合 回傳遞第一個位置
               return i
        
    def perform_selection(self):
        if self.selection_type == SelectionType.Deterministic:
            index = np.argsort(self.objective_values)[::1]     
        
        elif self.selection_type == SelectionType.Stochastic:
            index = [self.do_roulette_wheel_selection(self.objective_values) for i in range(self.pop_size)] 
        
        else:
            index = self.shuffle_index(self.total_size)
        
        for i in range(self.pop_size):
            for j in range(self.number_of_genes):
                self.selected_chromosomes[i][j] =  self.chromosomes[index[i]][j]
        
        for i in range(self.pop_size):
            for j in range(self.number_of_genes):
                self.chromosomes[i][j] = self.selected_chromosomes[i][j]
                
    def perform_mutation_operation(self):
        self.shuffle_index(self.pop_size+self.crossover_size)
        child1_index = self.pop_size+self.crossover_size
        for i in range(self.mutation_size):
            if(self.mutation_type==MutationType.Inversion):
                parent1_index = self.indexs[i]
                self.shuffle_mutation(parent1_index,child1_index)
                self.objective_values[child1_index] = self.countbyflexsim(self.chromosomes[child1_index])
                child1_index += 1
            
    def shuffle_mutation(self,p1,c1):
        for i in range(self.number_of_genes):
            self.chromosomes[c1][i] = self.chromosomes[p1][i]
        ran = random.sample(range(0,self.number_of_genes),12)
        for i in ran: #隨機選擇12個基因進行突變
            if(self.chromosomes[c1][i]==0):
                self.chromosomes[c1][i] = 1
            else:
                self.chromosomes[c1][i] = 0

pop_size = 2
selection_type = SelectionType.Stochastic
crossover_type = CrossoverType.more #single double more
crossover_rate = 1         
mutation_type = MutationType.Inversion
mutation_rate = 0.5
number_of_genes =60 
solver = GeneticAlgorithm(pop_size,number_of_genes,selection_type,
                          crossover_type,crossover_rate,
                          mutation_type,mutation_rate,
                          )
solver.initialize()
solver.evaluate_fitness()
for i in range(100):
    solver.perform_crossover_operation()
    solver.perform_mutation_operation()
    solver.update_best_solution()
    solver.perform_selection()

    if(i %10 ==0):
         print(F"iteration {i} :")
         print(f"{solver.best_chromosome}: {solver.countbyflexsim(solver.best_chromosome)}")
outdata = "exit"
s.send(outdata.encode())

以上是我基因演算法的程式碼
我想請問如何調整程式碼能夠畫出類似以下的圖
https://ithelp.ithome.com.tw/upload/images/20230330/20156408rjlCoNwtFg.png
X軸為iteration
Y軸為當次iteration最佳適應值也就是best_fitness

froce iT邦大師 1 級 ‧ 2023-03-31 11:05:45 檢舉
https://ithelp.ithome.com.tw/articles/10196239
你都引入matplotlib 了,怎麼會不知道怎麼畫...
先整理出你要的數據,然後參考官網的範例去改就行了。
https://matplotlib.org/stable/gallery/index

另外我看不懂你用socket只送個exit是要幹嘛。
s9816358 iT邦新手 5 級 ‧ 2023-03-31 15:41:14 檢舉
已解決 謝謝您!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答