print("HellSSo!")

# Why are we here?

I'm hoping it's to read about Swarm Intelligence! I'm also hoping you're interested to read about the interactive dashboard side of things too so we can play with it at the end.

If that sounds like too much and you just want to play with it now, you can use it on PyViz examples here: https://particle-swarms.pyviz.demo.anaconda.com

We're going to build the dashboard using some of Anacondas's HoloViz tools (Holoviews, Panel and Bokeh) to get the result from the tweet below.

## Finding the "just right" Goldilocks Zone using Swarm Intelligence

Say you're building a house and you want to maximise the number of rooms you can fit in your plot of land, maybe saying that all rooms have to be a certain size or bigger. That's the kind of thing that optimisation algorithms are useful for.

Optimisation methods like Particle Swarm Optimisation are used when you want to find the best/optimum for some system / problem. You could just try every possible input but that might take a while so smarter people than me have invented better ways.

## No death

This is going to be pretty similar to my Genetic Algorithm blog post except this time there will be a lot less death. You won’t necessarily need to have read that blog post but I will be referring back to it once or twice so you may want to go back and read that first.

## Make it interactive because

Let's build a dashboard in which you can control parameters of Particle Swarm Optimisation, click a target and see the little dots flock towards it. Like an interactive, 2D version of this plot on Wikipedia.

# Swarm Intelligence

## Wait, why no death?

Genetic algorithm is based on genetic evolution where for each generation there is survival-of-the-fittest-style well... death. In the case of Particle Swarm Optimisation, there is the same population throughout because we want them to remember where they were when they were at their fittest. Like looking back at yourself on your wedding day or after a health kick. Each particles position is a potential solution to your problem so they're all trying to find the best position together.

## Adding velocity to the mix

In the case of Genetic Algorithm each member of the population was just a few numbers (their X and Y position), the parameters that you’re trying to optimise. In this case each particle will not just have a X and Y position, they also have a velocity. We also need a way to know how to improve the particles in our swarm...

### Closer (smaller distance) is better

The same as with Genetic Algorithm, we'll need to find the fittest member of the population using euclidean distance / mean squared error (which particle is closest to the target).

#collapse-hide
def mean_squared_error(y_true, y_pred):
return ((y_true - y_pred)**2).mean(axis=0)

target_x, target_y = 0,0
def problem(soln):
global target_x #using globals so we can link this to the click event later
global target_y
return mean_squared_error(soln, [target_x, target_y])

def assess_fitness(individual, problem):
"Determines the fitness of an individual using the given problem"
return problem(individual)


## Nostalgic by design

Each member is going to keep track of their fittest position, this can help them if they explore a worse direction, or want to tell other particles (but we'll get to that later). They also keep an ID so that we can colour them across iterations.

## A portrait of a particle

The big red blob is one particle which has an X and Y position, a velocity and is constantly reminiscing about it's fittest position.

Here's that in code (before we add any of the update logic).

#collapse-hide
import numpy as np
import pandas as pd
import random
from holoviews import opts, dim
import holoviews as hv
import panel as pn
from holoviews.streams import Stream
hv.extension('bokeh', logo=False)