Python:PSO 聚集 <s> 并且代码仅在鼠标移动时有效</s>
Python: PSO clumping <s>and code working only when mouse moves</s>
我正在尝试制作一个简单的 PSO(粒子群优化)程序。
下面是我当前的代码,我一直在调整权重,结果发现 "optimization" 不起作用。
import random as ran
import math
# import threading as thr
import pygame as gm
# import pycuda as cuda
# import matplotlib.pyplot as plt
p_max = 10 # Maximum number of particles
rand_max = 100 # Maximum random vector value
# history = 10 # Number of iterations to record as history (including most current)
width = 600
height = 600
func_dict = {
"sphere" : ( lambda x, y: ( (x-(width/2))**2 + (y-(height/2))**2 ) ),
"booth" : ( lambda x, y: (((x-(width/2)) + 2*(y-(height/2)) - 7) ** 2) + ((2*(x-(width/2)) + (y-(height/2)) - 5) ** 2) ),
"matyas" : ( lambda x, y: (0.26 * ((x-(width/2))**2 + (y-(height/2))**2) - 0.48*(x-(width/2))*(y-(height/2))) )
} # (x-(width/2)) and (y-(height/2)) to shift the Zero to the display center
func = "sphere" # Choose function from func_dict
# Weights (0<w<1)
wLocal = 0.4 # Explore weight
wGlobal = 0.8 # Exploit weight
wRandom = 0.02 # Weight of random vector
global_best = [None, None, None] # Initial blank
class particle: # particles
global global_best
def __init__(self):
global global_best
global width, height
global func_dict, func
self.vel_x = 0
self.vel_y = 0
self.pos_x = ran.randint(0, width)
self.pos_y = ran.randint(0, height)
self.pos_z = func_dict[func](self.pos_x, self.pos_y)
self.local_best = [self.pos_x, self.pos_y, self.pos_z]
if (global_best[0] == None) or (global_best[1] == None) or (global_best[2] == None): # Is 1st particle
global_best = self.local_best
def update(self): # Update vectors
global width, height
global rand_max
global wGlobal, wLocal, wRandom
global global_best
self.vel_x = (wGlobal * (global_best[0] - self.pos_x)) + (wLocal * (self.local_best[0] - self.pos_x)) + (wRandom * ran.randint(-rand_max, rand_max))
self.vel_y = (wGlobal * (global_best[1] - self.pos_y)) + (wLocal * (self.local_best[1] - self.pos_y)) + (wRandom * ran.randint(-rand_max, rand_max))
# self.pos_x = (self.pos_x + self.vel_x) % width
# self.pos_y = (self.pos_y + self.vel_y) % height
self.pos_x += self.vel_x
self.pos_y += self.vel_y
if self.pos_x < 0:
self.pos_x = 0
if self.pos_y < 0:
self.pos_y = 0
if self.pos_x > width:
self.pos_x = width
if self.pos_y > height:
self.pos_y = height
self.pos_z = func_dict[func](self.pos_x, self.pos_y)
if self.pos_z < global_best[2]:
global_best = [self.pos_x, self.pos_y, self.pos_z]
particles = [None for _ in range(p_max)]
def initialize():
global_best = [None, None, None]
for foo in range(p_max):
particles[foo] = particle() # create new particles
# def dist(p1, p2): # distance
# return(math.sqrt( ( (p1.pos_x - p2.pos_y)**2) + ((p1.pos_y - p2.pos_y)**2) ) )
# def update(this): # this = particle
# this.vel_x = (wGlobal * (global_best[0] - this.pos_x)) + (wLocal * (this.local_best[0] - this.pos_x)) + (wRandom * ran.randint(0, rand_max))
# this.vel_y = (wGlobal * (global_best[1] - this.pos_y)) + (wLocal * (this.local_best[1] - this.pos_y)) + (wRandom * ran.randint(0, rand_max))
# # this.pos_x = (this.pos_x + this.vel_x) % width
# # this.pos_y = (this.pos_y + this.vel_y) % height
# this.pos_x += this.vel_x
# this.pos_y += this.vel_y
# if this.pos_x < 0:
# this.pos_x = 0
# if this.pos_y < 0:
# this.pos_y = 0
# if this.pos_x > width:
# this.pos_x = width
# if this.pos_y > height:
# this.pos_y = height
# # return this
# def update_multi(things): # things = list() of particles
# these = things
# for item in these:
# item = update(item)
# return these
gm.init()
main = gm.display.set_mode((width, height))
end_program = False
initialize()
main.fill((255, 255, 255))
while end_program == False:
# main.fill((255, 255, 255)) #Comment/Uncomment to leave trace
# plt.plot() # Plot functions
for event in gm.event.get():
if event.type == gm.QUIT:
end_program = True
for foo in range(len(particles)):
particles[foo].update()
gm.draw.circle(main, (0, 0, 0), (int(particles[foo].pos_x), int(particles[foo].pos_y)), 5, 0)
gm.display.flip()
问题一:程序只在鼠标移动时运行
我不确定为什么,但该程序仅在几次迭代中运行得相当快,但似乎只是在之后停止,但在移动鼠标时继续。
问题 2:粒子似乎停留在局部
当我四处移动鼠标时,它有点跑。出现的是第二个 # main.fill((255, 255, 255))
未注释时留下的痕迹。在没有鼠标移动的情况下程序停止之前的第一个初始痕迹似乎更加分散,我不确定这是全局变量还是随机数在起作用。
编辑:我通过取消缩进修复了程序仅在鼠标移动时运行的问题:
for foo in range(len(particles)):
particles[foo].update()
gm.draw.circle(main, (0, 0, 0), (int(particles[foo].pos_x), int(particles[foo].pos_y)), 5, 0)
然而,粒子似乎仍然几乎没有离开自己的位置,在局部振荡。
感谢 Marius 解决了问题 1。我通过简单地将 update
放在 event
循环之外来修复它。
问题 2 已通过添加我忘记的本地更新得到修复。
if self.pos_z < global_best[2]: # This was not forgotten
global_best = [self.pos_x, self.pos_y, self.pos_z]
if self.pos_z < local_best[2]: # This was forgotten
local_best = [self.pos_x, self.pos_y, self.pos_z]
我正在尝试制作一个简单的 PSO(粒子群优化)程序。
下面是我当前的代码,我一直在调整权重,结果发现 "optimization" 不起作用。
import random as ran
import math
# import threading as thr
import pygame as gm
# import pycuda as cuda
# import matplotlib.pyplot as plt
p_max = 10 # Maximum number of particles
rand_max = 100 # Maximum random vector value
# history = 10 # Number of iterations to record as history (including most current)
width = 600
height = 600
func_dict = {
"sphere" : ( lambda x, y: ( (x-(width/2))**2 + (y-(height/2))**2 ) ),
"booth" : ( lambda x, y: (((x-(width/2)) + 2*(y-(height/2)) - 7) ** 2) + ((2*(x-(width/2)) + (y-(height/2)) - 5) ** 2) ),
"matyas" : ( lambda x, y: (0.26 * ((x-(width/2))**2 + (y-(height/2))**2) - 0.48*(x-(width/2))*(y-(height/2))) )
} # (x-(width/2)) and (y-(height/2)) to shift the Zero to the display center
func = "sphere" # Choose function from func_dict
# Weights (0<w<1)
wLocal = 0.4 # Explore weight
wGlobal = 0.8 # Exploit weight
wRandom = 0.02 # Weight of random vector
global_best = [None, None, None] # Initial blank
class particle: # particles
global global_best
def __init__(self):
global global_best
global width, height
global func_dict, func
self.vel_x = 0
self.vel_y = 0
self.pos_x = ran.randint(0, width)
self.pos_y = ran.randint(0, height)
self.pos_z = func_dict[func](self.pos_x, self.pos_y)
self.local_best = [self.pos_x, self.pos_y, self.pos_z]
if (global_best[0] == None) or (global_best[1] == None) or (global_best[2] == None): # Is 1st particle
global_best = self.local_best
def update(self): # Update vectors
global width, height
global rand_max
global wGlobal, wLocal, wRandom
global global_best
self.vel_x = (wGlobal * (global_best[0] - self.pos_x)) + (wLocal * (self.local_best[0] - self.pos_x)) + (wRandom * ran.randint(-rand_max, rand_max))
self.vel_y = (wGlobal * (global_best[1] - self.pos_y)) + (wLocal * (self.local_best[1] - self.pos_y)) + (wRandom * ran.randint(-rand_max, rand_max))
# self.pos_x = (self.pos_x + self.vel_x) % width
# self.pos_y = (self.pos_y + self.vel_y) % height
self.pos_x += self.vel_x
self.pos_y += self.vel_y
if self.pos_x < 0:
self.pos_x = 0
if self.pos_y < 0:
self.pos_y = 0
if self.pos_x > width:
self.pos_x = width
if self.pos_y > height:
self.pos_y = height
self.pos_z = func_dict[func](self.pos_x, self.pos_y)
if self.pos_z < global_best[2]:
global_best = [self.pos_x, self.pos_y, self.pos_z]
particles = [None for _ in range(p_max)]
def initialize():
global_best = [None, None, None]
for foo in range(p_max):
particles[foo] = particle() # create new particles
# def dist(p1, p2): # distance
# return(math.sqrt( ( (p1.pos_x - p2.pos_y)**2) + ((p1.pos_y - p2.pos_y)**2) ) )
# def update(this): # this = particle
# this.vel_x = (wGlobal * (global_best[0] - this.pos_x)) + (wLocal * (this.local_best[0] - this.pos_x)) + (wRandom * ran.randint(0, rand_max))
# this.vel_y = (wGlobal * (global_best[1] - this.pos_y)) + (wLocal * (this.local_best[1] - this.pos_y)) + (wRandom * ran.randint(0, rand_max))
# # this.pos_x = (this.pos_x + this.vel_x) % width
# # this.pos_y = (this.pos_y + this.vel_y) % height
# this.pos_x += this.vel_x
# this.pos_y += this.vel_y
# if this.pos_x < 0:
# this.pos_x = 0
# if this.pos_y < 0:
# this.pos_y = 0
# if this.pos_x > width:
# this.pos_x = width
# if this.pos_y > height:
# this.pos_y = height
# # return this
# def update_multi(things): # things = list() of particles
# these = things
# for item in these:
# item = update(item)
# return these
gm.init()
main = gm.display.set_mode((width, height))
end_program = False
initialize()
main.fill((255, 255, 255))
while end_program == False:
# main.fill((255, 255, 255)) #Comment/Uncomment to leave trace
# plt.plot() # Plot functions
for event in gm.event.get():
if event.type == gm.QUIT:
end_program = True
for foo in range(len(particles)):
particles[foo].update()
gm.draw.circle(main, (0, 0, 0), (int(particles[foo].pos_x), int(particles[foo].pos_y)), 5, 0)
gm.display.flip()
问题一:程序只在鼠标移动时运行
我不确定为什么,但该程序仅在几次迭代中运行得相当快,但似乎只是在之后停止,但在移动鼠标时继续。
问题 2:粒子似乎停留在局部
当我四处移动鼠标时,它有点跑。出现的是第二个 # main.fill((255, 255, 255))
未注释时留下的痕迹。在没有鼠标移动的情况下程序停止之前的第一个初始痕迹似乎更加分散,我不确定这是全局变量还是随机数在起作用。
编辑:我通过取消缩进修复了程序仅在鼠标移动时运行的问题:
for foo in range(len(particles)):
particles[foo].update()
gm.draw.circle(main, (0, 0, 0), (int(particles[foo].pos_x), int(particles[foo].pos_y)), 5, 0)
然而,粒子似乎仍然几乎没有离开自己的位置,在局部振荡。
感谢 Marius 解决了问题 1。我通过简单地将 update
放在 event
循环之外来修复它。
问题 2 已通过添加我忘记的本地更新得到修复。
if self.pos_z < global_best[2]: # This was not forgotten
global_best = [self.pos_x, self.pos_y, self.pos_z]
if self.pos_z < local_best[2]: # This was forgotten
local_best = [self.pos_x, self.pos_y, self.pos_z]