0

I am currently dealing with the above code.

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import sympy 
import numpy as np
import random

Q = [None, None]
K = [None, None, None]
f = np.zeros((201, 201))
K[2] = f
X = []

d = 2
global_best_position = []
global_best_error = 10000
vec=np.random.rand(d)
R1=np.diag(vec)
vec=np.random.rand(d)
R2=np.diag(vec)

def akley(x, dim, a=20, b=0.2, c=2*np.pi):
    sum1 = 0
    sum2 = 0
    for i in range(2):
        sum1 += x[i]**2
        sum2 += np.cos(c*x[i])
    sum_sq_term = -a * np.exp(-b * np.sqrt(sum1) / 2)
    cos_term = -np.exp((sum2) / 2)
    Z = a + np.exp(1) + sum_sq_term + cos_term
    return Z

def plot_akley_2d():
    global d
    ymin, ymax, xmin, xmax = -16, 16, -16, 16

    for i in range(d):
        Q[i] = np.linspace(xmin, xmax, 201)

    for i in range(d):
        K[0], K[1]= np.meshgrid(Q[0], Q[1])

    for i in range(201):
        for h in range(201):
            u = [K[0][i][h], K[1][i][h]]
            u = np.array(u)
            K[2][i][h] = akley(u, 2)
    d = plt.contourf(K[0], K[1], K[2], 20, cmap=cm.rainbow)
    plt.ylim((ymin, ymax)), plt.xlim((ymin, ymax)), plt.colorbar(d);

class Particle():
    def __init__(self):
        global d
        self.position = []
        self.velocity = []
        self.best_position  = []
        self.best_error = 0
        self.error = 0

        for i in range(2):
            self.position.append(random.uniform(-16, 16))
            self.velocity.append(random.uniform(-1, 1))

        self.best_position = self.position
        self.error = akley(self.position, d)
        self.best_error = self.error
        self.evaluate_position()


    def evaluate_position(self):
        global d, global_best_position, global_best_error
        self.error = akley(self.position, d)
        if self.error < self.best_error:
            self.best_error = self.error
            self.best_position = self.position
            if self.best_error < global_best_error:
                global_best_position = self.best_position
                global_best_error = self.best_error

    def update_particle(self, w=0.5, c1=2, c2=2):
        global R1, R2, global_best_position
        self.velocity = self.velocity + c1*(self.best_position-self.position)*R1 + c2*(global_best_position - self.position)*R2
        self.position = self.position + self.velocity
        self.evaluate_position()

class PSO():
    def __init__(self, iterations, num_particles):
        self.particle_list = []
        self.iterations = iterations

        for i in range(num_particles):
            self.particle_list.append(Particle())

    def optimize(self):
        for i in range(self.iterations):
            for j in range(len(self.particle_list)):
                self.particle_list[j].update_particle()

PSO1 = PSO(100, 10)
PSO1.optimize()

print(global_best_error)
print(global_best_position)

When executing it I receive the following error:

File "<ipython-input-47-e1f278f8304b>", line 84, in update_particle
self.velocity = self.velocity + c1*(self.best_position-self.position)*R1 + c2*(global_best_position - self.position)*R2

TypeError: unsupported operand type(s) for -: 'list' and 'list'

I did some searching already and it seems to me that I am not able to substract two lists from each other. I tried to convert all of them to numpy arrays, but unfortunately it just raises even more errors within my code. I checked the dimensions of all lists and it should work, I am just very unsure about how to approach matrix/list operations here.

1
  • 2
    Numpy arrays would be the best way to go here, so if you want maybe post the errors you get with them too? If you want to stick with lists you could always perform the substraction element by element, on each self.velocity[n]. Commented Dec 7, 2018 at 9:53

1 Answer 1

1

Ideally, converting to numpy arrays would be the best course of action. Then you can subtract directly or use np.subtract().

If you want a work-around to prevent the other errors in your code you can use list comprehensions, though they will not be as quick as numpy operations:

e.g.

... c2*[global_best_position[i] - self.position[i] for i in range(len(global_best_position))]...
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer! When I would like to approach the problem using numpy arrays, I have troubles seeing where I would have to change my lists into np arrays. Is that done best right after initialisation within the class or just best before I am doing the calculations in update_particle() ?
Lists are useful for appending items in a for loop. Once your list is complete and not going to be extended any further you can cast it to a numpy array. There are also several ways you can append to numpy arrays too, but appending to lists is faster.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.