157 lines
3.8 KiB
Python
157 lines
3.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Tue May 24 13:13:28 2016
|
|
|
|
@author: Hossam Faris
|
|
"""
|
|
import math
|
|
import numpy
|
|
import random
|
|
import time
|
|
from .solution import solution
|
|
|
|
|
|
def get_cuckoos(nest, best, lb, ub, n, dim):
|
|
|
|
# perform Levy flights
|
|
tempnest = numpy.zeros((n, dim))
|
|
tempnest = numpy.array(nest)
|
|
beta = 3 / 2
|
|
sigma = (
|
|
math.gamma(1 + beta)
|
|
* math.sin(math.pi * beta / 2)
|
|
/ (math.gamma((1 + beta) / 2) * beta * 2 ** ((beta - 1) / 2))
|
|
) ** (1 / beta)
|
|
|
|
s = numpy.zeros(dim)
|
|
for j in range(0, n):
|
|
s = nest[j, :]
|
|
u = numpy.random.randn(len(s)) * sigma
|
|
v = numpy.random.randn(len(s))
|
|
step = u / abs(v) ** (1 / beta)
|
|
|
|
stepsize = 0.01 * (step * (s - best))
|
|
|
|
s = s + stepsize * numpy.random.randn(len(s))
|
|
|
|
for k in range(dim):
|
|
tempnest[j, k] = numpy.clip(s[k], lb[k], ub[k])
|
|
|
|
return tempnest
|
|
|
|
|
|
def get_best_nest(nest, newnest, fitness, n, dim, objf):
|
|
# Evaluating all new solutions
|
|
tempnest = numpy.zeros((n, dim))
|
|
tempnest = numpy.copy(nest)
|
|
|
|
for j in range(0, n):
|
|
# for j=1:size(nest,1),
|
|
fnew = objf(newnest[j, :])
|
|
if fnew <= fitness[j]:
|
|
fitness[j] = fnew
|
|
tempnest[j, :] = newnest[j, :]
|
|
|
|
# Find the current best
|
|
|
|
fmin = min(fitness)
|
|
K = numpy.argmin(fitness)
|
|
bestlocal = tempnest[K, :]
|
|
|
|
return fmin, bestlocal, tempnest, fitness
|
|
|
|
|
|
# Replace some nests by constructing new solutions/nests
|
|
def empty_nests(nest, pa, n, dim):
|
|
|
|
# Discovered or not
|
|
tempnest = numpy.zeros((n, dim))
|
|
|
|
K = numpy.random.uniform(0, 1, (n, dim)) > pa
|
|
|
|
stepsize = random.random() * (
|
|
nest[numpy.random.permutation(n), :] - nest[numpy.random.permutation(n), :]
|
|
)
|
|
|
|
tempnest = nest + stepsize * K
|
|
|
|
return tempnest
|
|
|
|
|
|
##########################################################################
|
|
|
|
|
|
def CS(objf, lb, ub, dim, n, N_IterTotal):
|
|
|
|
# lb=-1
|
|
# ub=1
|
|
# n=50
|
|
# N_IterTotal=1000
|
|
# dim=30
|
|
|
|
# Discovery rate of alien eggs/solutions
|
|
pa = 0.25
|
|
|
|
nd = dim
|
|
|
|
# Lb=[lb]*nd
|
|
# Ub=[ub]*nd
|
|
convergence = []
|
|
if not isinstance(lb, list):
|
|
lb = [lb] * dim
|
|
if not isinstance(ub, list):
|
|
ub = [ub] * dim
|
|
|
|
# RInitialize nests randomely
|
|
nest = numpy.zeros((n, dim))
|
|
for i in range(dim):
|
|
nest[:, i] = numpy.random.uniform(0, 1, n) * (ub[i] - lb[i]) + lb[i]
|
|
|
|
new_nest = numpy.zeros((n, dim))
|
|
new_nest = numpy.copy(nest)
|
|
|
|
bestnest = [0] * dim
|
|
|
|
fitness = numpy.zeros(n)
|
|
fitness.fill(float("inf"))
|
|
|
|
s = solution()
|
|
|
|
print('CS is optimizing "' + objf.__name__ + '"')
|
|
|
|
timerStart = time.time()
|
|
s.startTime = time.strftime("%Y-%m-%d-%H-%M-%S")
|
|
|
|
fmin, bestnest, nest, fitness = get_best_nest(nest, new_nest, fitness, n, dim, objf)
|
|
convergence = []
|
|
# Main loop counter
|
|
for iter in range(0, N_IterTotal):
|
|
# Generate new solutions (but keep the current best)
|
|
|
|
new_nest = get_cuckoos(nest, bestnest, lb, ub, n, dim)
|
|
|
|
# Evaluate new solutions and find best
|
|
fnew, best, nest, fitness = get_best_nest(nest, new_nest, fitness, n, dim, objf)
|
|
|
|
new_nest = empty_nests(new_nest, pa, n, dim)
|
|
|
|
# Evaluate new solutions and find best
|
|
fnew, best, nest, fitness = get_best_nest(nest, new_nest, fitness, n, dim, objf)
|
|
|
|
if fnew < fmin:
|
|
fmin = fnew
|
|
bestnest = best
|
|
|
|
if iter % 10 == 0:
|
|
print(["At iteration " + str(iter) + " the best fitness is " + str(fmin)])
|
|
convergence.append(fmin)
|
|
|
|
timerEnd = time.time()
|
|
s.endTime = time.strftime("%Y-%m-%d-%H-%M-%S")
|
|
s.executionTime = timerEnd - timerStart
|
|
s.convergence = convergence
|
|
s.optimizer = "CS"
|
|
s.bestIndividual = bestnest
|
|
s.objfname = objf.__name__
|
|
|
|
return s
|