Sunday, March 12, 2023

A simple OOP example of 3D-FOA by Python

 """

A simple OOP example of 3D-FOA by Python to find the min value of QF 

Author: Wei-Yuan Lin

Soochow University, Taipei

Taiwan

Ver.3

In this version, there are two classes - Fly and FOA.

The Fly class represents each individual fly in the swarm

This code implements the Fruitfly  Optimization Algorithm (FOA) to optimize a function called "smell". FOA is a nature-inspired algorithm that mimics the behavior of fruit fly to find the optimal solution. The "smell" function is defined in the Fly class, and it is calculated based on the distance of the fly from the origin. The optimization process involves moving the flies randomly and calculating the new value of the "smell" function. The best fly is chosen based on the minimum value of the "smell" function. The FOA is run for a certain number of generations, and the results are plotted in 2D and 3D.


The code defines two classes: Fly and FOA. The Fly class represents a fruit fly, and it has the following attributes:

* x: the x-coordinate of the fruit fly

* y: the y-coordinate of the fruit fly

* z: the z-coordinate of the fruit fly

* smell: the value of the "smell" function for the fruit fly

The class also has three methods:

* calculate_smell(): calculates the value of the "smell" function for the fruit fly based on its coordinates.

* move(): moves the fruit fly randomly in 3D space.

* lt(): a comparison operator that is used to compare two flies based on their "smell" value. This is used to determine the best fly.


The FOA class represents the optimization process, and it has the following attributes:


* population: the number of flies in the population

* generations: the number of generations to run the optimization

* fly_list: a list of Fly objects representing the population of flies

* best_fly: the Fly object with the minimum "smell" value

* xlist, ylist, zlist, value: lists that store the x, y, z coordinates and "smell" values of the best fly at each generation


The class also has four methods:

* initialize_population(): creates the initial population of flies and calculates their "smell" values.

* optimize(): runs the optimization process for a certain number of generations.

* plot_results(): plots the results in 2D and 3D.

The main function creates an instance of the FOA class with a population of 100 flies and 100 generations. It then initializes the population and runs the optimization process. Finally, it plots the results using the plot_results() method.

"""

# Step 1 import required libraries

import numpy as np

import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3D


# Step 2 define the class- Fly

class Fly:

    def __init__(self, x, y, z):

        self.x = x

        self.y = y

        self.z = z

        self.smell = None


    def calculate_smell(self):

        S = 1 / np.sqrt(self.x ** 2 + self.y ** 2 + self.z ** 2)

        self.smell = -7 + S ** 2


    def move(self):

        self.x += 2 * np.random.rand() - 1

        self.y += 2 * np.random.rand() - 1

        self.z += 2 * np.random.rand() - 1


    def __lt__(self, other):

        return self.smell < other.smell


# Step 3 define the class- FOA.

class FOA:

    def __init__(self, population, generations):

        self.population = population

        self.generations = generations

        self.fly_list = []

        self.best_fly = None

        self.xlist, self.ylist, self.zlist, self.smell_list = [][][][]


    def initialize_population(self):

        for _ in range(self.population):

            fly = Fly(10 * np.random.rand(), 10 * np.random.rand(), 10 * np.random.rand())

            fly.calculate_smell()

            self.fly_list.append(fly)

        self.best_fly = min(self.fly_list)


    def optimize(self):

        for i in range(self.generations):

            for fly in self.fly_list:

                fly.move()

                fly.calculate_smell()

                if fly < self.best_fly:

                    self.best_fly = fly

                    self.xlist.append(fly.x)

                    self.ylist.append(fly.y)

                    self.zlist.append(fly.z)

                    self.smell_list.append(fly.smell)


    # Step 4 plot the graphs

    def plot_results(self):

        fig, ax = plt.subplots(1, 3, figsize=(12, 4))


        plt.subplot(1, 3, 1)

        plt.plot(range(1, len(self.smell_list) + 1), self.smell_list, '*', color='blue')

        plt.xlabel('Gen')

        plt.title('Min f(S)=-7+S**2', fontsize=14)

        plt.ylabel('Best Value', fontsize=10)

        plt.grid(linestyle='--')


        plt.subplot(1, 3, 2)

        plt.plot(self.xlist, self.ylist, '*', color='black')

        plt.title('2D-Route of Best Fly', fontsize=14)

        plt.xlabel('X Axis', fontsize=12)

        plt.ylabel('Y Axis', fontsize=12)

        plt.grid(linestyle='--')


        plt.subplot(1, 3, 3, projection='3d')

        plt.plot(self.xlist, self.ylist, self.zlist, '*', color='green')

        plt.title("3D-Route of Best Fly", fontsize=14)

        plt.xlabel('X Axis', fontsize=12)

        plt.ylabel('Y Axis', fontsize=12)

        plt.gca().set_zlabel("Z Axis")

        plt.grid(linestyle='--')


        plt.show()

        fig.savefig("3dFOA.png")

        print("best value for gen : ", self.best_fly.smell)



# Main program

if __name__ == '__main__':

    foa = FOA(population=500, generations=100)

    foa.initialize_population()

    foa.optimize()  # added the optimize method call

    foa.plot_results()



The main changes in the code include adding self.smell_list to store the smell of the best fly in each generation and calling the optimize() method in the main program. Additionally, the plot() method was corrected to plot self.smell_list instead of self.smell, which was not defined in the FOA class.


未知.png

best value for gen :  -6.9989065313201735




0 comments:

Post a Comment