File size: 6,356 Bytes
9eb3fa3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e422956
9eb3fa3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1dd991e
31e2242
e444364
9eb3fa3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import numpy as np
import random
from deap import base, creator, tools, algorithms
import plotly.graph_objs as go
import streamlit as st

# Define the objective function
class Objective:
    def Evaluate(self, p):
        return -25.7743 * np.exp(-0.5 * ((p[0] + 25.7743)**2 / 0.1 + (p[1] - 80.1937)**2 / 0.1)) + \
               80.1937 * np.exp(-0.5 * ((p[0] - 25.7743)**2 / 0.2 + (p[1] + 80.1937)**2 / 0.2)),
    
# Define the bounds
BOUND_LOW, BOUND_UP = -100.0, 100.0 
NDIM = 2

# Create the fitness and individual classes
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin)

# Initialize the toolbox
toolbox = base.Toolbox()

# Attribute generator
toolbox.register("attr_float", random.uniform, BOUND_LOW, BOUND_UP)

# Structure initialization
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, NDIM)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

# Define the evaluation function
def evaluate(individual):
    return Objective().Evaluate(individual)

toolbox.register("evaluate", evaluate)

# Define the genetic operators
toolbox.register("mate", tools.cxBlend, alpha=0.5)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)

# Define the main function to run the genetic algorithm
def main():
    random.seed(42)
    
    # Create an initial population of 300 individuals
    pop = toolbox.population(n=300)
    
    # Define the hall of fame to keep track of the best individuals
    hof = tools.HallOfFame(1)
    
    # Define the statistics to collect
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("avg", np.mean)
    stats.register("std", np.std)
    stats.register("min", np.min)
    stats.register("max", np.max)
    
    # Define the parameters for the genetic algorithm
    ngen = 500
    cxpb = 0.7
    mutpb = 0.2
    
    # Run the genetic algorithm
    pop, log = algorithms.eaSimple(pop, toolbox, cxpb, mutpb=mutpb, ngen=ngen, stats=stats, halloffame=hof, verbose=True)
    
    # Print the best individual
    st.write("Best individual is: %s, %s" % (hof[0], hof[0].fitness.values))
    st.image('Objective Function 3.jpeg', caption='Objective Function 2 Target Pattern 2')
    
    # Visualization
    x = np.linspace(-100, 100, 400)
    y = np.linspace(-100, 100, 400)
    X, Y = np.meshgrid(x, y)
    Z = np.zeros_like(X)
    
    for i in range(X.shape[0]):
        for j in range(X.shape[1]):
            Z[i, j] = Objective().Evaluate([X[i, j], Y[i, j]])[0]
            
    # Custom colorscale with specified colors
    custom_colorscale = [
        [0, '#ffffff'], # White
        [1, '#0000ff']  # Blue
    ]
    
    trace = go.Surface(x=X, y=Y, z=Z, colorscale=custom_colorscale)
    data = [trace]
    
    # Add convergence path 
    convergence_path = np.array([ind for ind in hof])
    trace_convergence = go.Scatter3d(
        x=convergence_path[:, 0],
        y=convergence_path[:, 1],
        z=[Objective().Evaluate(ind)[0] for ind in convergence_path],
        mode='lines+markers',
        marker=dict(size=4, color='#0000ff', showscale=True), # Blue markers
        line=dict(color='#ffffff', width=2)  # White line 
    )
    data.append(trace_convergence)
    
    # Add target pattern coordinates
    target_pattern = np.array([
        [-25.7743, 80.1937]
    ])
    trace_target = go.Scatter3d(
        x=target_pattern[:, 0],
        y=target_pattern[:, 1],
        z=[Objective().Evaluate(ind)[0] for ind in target_pattern],
        mode='markers',
        marker=dict(size=10, color='#0000ff', symbol='x'), # Blue markers
        name='Target Pattern'
    )
    data.append(trace_target)
    
    # Add best individual
    trace_best = go.Scatter3d(
        x=[hof[0][0]],
        y=[hof[0][1]],
        z=[hof[0].fitness.values[0]],
        mode='markers',
        marker=dict(size=10, color='#ff0000', symbol='circle'), # Red marker
        name='Best Individual'
    )
    data.append(trace_best)
    
    layout = go.Layout(
        title='Objective Function Visualization with Convergence Path',
        scene=dict(
            xaxis=dict(title='X'),
            yaxis=dict(title='Y'),
            zaxis=dict(title='Z')
        )
    )
    
    fig = go.Figure(data=data, layout=layout)
    st.plotly_chart(fig)
    
    # Convergence Plot
    min_fitness_values = log.select("min")
    avg_fitness_values = log.select("avg")
    
    convergence_trace = go.Scatter(
        x=list(range(len(min_fitness_values))),
        y=min_fitness_values,
        mode='lines+markers',
        name='Min Fitness'
    )
    
    avg_trace = go.Scatter(
        x=list(range(len(avg_fitness_values))),
        y=avg_fitness_values,
        mode='lines+markers',
        name='Avg Fitness'
    )
    
    convergence_layout = go.Layout(
        title='Convergence Plot',
        xaxis=dict(title='Generation'),
        yaxis=dict(title='Fitness')
    )
    
    convergence_fig = go.Figure(data=[convergence_trace, avg_trace], layout=convergence_layout)
    st.plotly_chart(convergence_fig)
    
    # Population Distribution Over Generations
    def plot_population_distribution(pop, generation):
        pop_trace = go.Scatter3d(
            x=[ind[0] for ind in pop],
            y=[ind[1] for ind in pop],
            z=[ind.fitness.values[0] for ind in pop],
            mode='markers',
            marker=dict(size=4, color='#ff0000', showscale=True), # Red markers
            name=f'Generation {generation}'
        )
        return pop_trace
    
    # Interactive Controls for Population Distribution
    generation = st.slider("Select Generation", min_value=0, max_value=ngen, value=150)
    pop_trace = plot_population_distribution(pop, generation)
    pop_fig = go.Figure(data=[trace, pop_trace], layout=layout)
    st.plotly_chart(pop_fig)
    
if __name__ == "__main__":
    st.title("Genetic Algorithm Objective Function 2 Pair of Gaussians Visualization -1*[-25.7743, 80.1937]")
    st.image('Objective Function 2.jpeg', caption='UAV Objective Function 2 Target Pattern')
    st.image('Objective Function 2.png', caption='UAV Objective Function 2')
    st.write('一。NICO MAULEN | Techengue Vol 5 - Tech & Latin House (Live Set)')
    main()