This project is an attempt at constructing an algorithm of personal interest from pure maths and logic. High-level and specialized libraries could be utilized to expedite this process. However, I must sharpen my raw programming skills which aren’t exactly honed in an ecosystem saturated with curated tools and boilerplate code.
Dyson swarm algorithm inspired by the Dyson sphere megastructure model. This swarm model will be created via satellite-like and particle swarm optimization behaviors.
The base model is inspired by Particle Swarm Optimization as an algorithmic foundation. The following is the result of that animated base model.
Particularly, the value detection system of PSO will be utilized for future simulation. While a custom satellite-like path finding procedure will take place among several satellite-like agents.
The main inspiration for model constraints will be based on satellite-like constellation procedures. Specifically, LEO (low Earth orbit) satellite procedures.
A spherical mesh grid structure will act as the base of the entire simulation environment. This base will express a range of values with the max values being the detection target.
PSO algorithm base finds the global minimum, but this algorithm will utilize a similar application with locating the global maximum.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def f(x, y):
"Objective Function"
return (x-3.14)**2 + (y-2.72)**2 + np.sin(3*x+1.41) + np.sin(4*y-1.73)
# Cpmpute and plot the function in 3 dimensions within [0,5][0,5]
x, y = np.array(np.meshgrid(np.linspace(0,5,100), np.linspace(0,5,100)))
z = f(x, y)
# Find the global minimum
x_min = x.ravel()[z.argmin()]
y_min = y.ravel()[z.argmin()]
# Hyper-parameter of the algorithm
c1 = c2 = 0.1
w = 0.8
# Create particles
n_particles = 20
np.random.seed(100)
X = np.random.rand(2, n_particles) * 5
V = np.random.randn(2, n_particles) * 0.1
# Initialize data
pbest = X
pbest_obj = f(X[0], X[1])
gbest = pbest[:, pbest_obj.argmin()]
gbest_obj = pbest_obj.min()
def update():
"Function to do one iteration of particle swarm optimization"
global V, X, pbest, pbest_obj, gbest, gbest_obj
# Update parameters
r1, r2 = np.random.rand(2)
V = w * V + c1*r1*(pbest - X) + c2*r2*(gbest.reshape(-1,1)-X)
X = X + V
obj = f(X[0], X[1])
pbest[:, (pbest_obj >= obj)] = X[:, (pbest_obj >= obj)]
pbest_obj = np.array([pbest_obj, obj]).min(axis=0)
gbest = pbest[:, pbest_obj.argmin()]
gbest_obj = pbest_obj.min()
# Set up base figure: The contour map
fig, ax = plt.subplots(figsize=(8,6))
fig.set_tight_layout(True)
img = ax.imshow(z, extent=[0, 5, 0, 5], origin='lower', cmap='viridis', alpha=0.5)
fig.colorbar(img, ax=ax)
ax.plot([x_min], [y_min], marker='x', markersize=5, color="white")
contours = ax.contour(x, y, z, 10, colors='black', alpha=0.4)
ax.clabel(contours, inline=True, fontsize=8, fmt="%.0f")
pbest_plot = ax.scatter(pbest[0], pbest[1], marker='o', color='black', alpha=0.5)
p_plot = ax.scatter(X[0], X[1], marker='o', color='blue', alpha=0.5)
p_arrow = ax.quiver(X[0], X[1], V[0], V[1], color='blue', width=0.005, angles='xy', scale_units='xy', scale=1)
gbest_plot = plt.scatter([gbest[0]], [gbest[1]], marker='*', s=100, color='black', alpha=0.4)
ax.set_xlim([0,5])
ax.set_ylim([0,5])
def animate(i):
"Steps of PSO: algorithm update and show in plot"
title = 'Iteration {:02d}'.format(i)
# Update parameters
update()
# Set picture
ax.set_title(title)
pbest_plot.set_offsets(pbest.T)
p_plot.set_offsets(X.T)
p_arrow.set_offsets(X.T)
p_arrow.set_UVC(V[0], V[1])
gbest_plot.set_offsets(gbest.reshape(1,-1))
return ax, pbest_plot, p_plot, p_arrow, gbest_plot
anim = FuncAnimation(fig, animate, frames=list(range(1,50)), interval=500, blit=False, repeat=True)
anim.save("PSO.gif", dpi=120, writer="pillow")
print("PSO found best solution at f({})={}".format(gbest, gbest_obj))
print("Global optimal at f({})={}".format([x_min,y_min], f(x_min,y_min)))