pyswarms的玩具示例 – 帮助理解简单的事情

huangapple go评论70阅读模式
英文:

pyswarms toy example - help to understand simple things

问题

尝试使用Python的pyswarms包理解粒子群优化

https://pyswarms.readthedocs.io/en/latest/intro.html

需要优化一个多变量函数如下所示

# 定义目标函数
def objective_function(x):
    return ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

如果我有一个接近全局最小值的初始猜测我想在一个有界区域中找到全局最小值

这是我所做的但实际上并不起作用
它报错

> ValueError: operands could not be broadcast together with shapes (3,) > (100,)

初始猜测或边界有问题吗需要以某种特定方式重塑它吗请给我一个解决这个问题的关键..

有人能看一下并解释一下问题在哪里吗
以下是要尝试的代码

import numpy as np
import pyswarms as ps

# 定义目标函数
def objective_function(x):
    return  ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

# 为x的每个元素定义边界
bounds = ([-5]*3, [5]*3)
print('Bounds:')
print(bounds)

# 为x的每个元素定义初始猜测
initial_guess_1 = np.array([1.0, 2.0, 2.9)

# 定义要优化的元素数量
dimensions = initial_guess_1.size
print('Dimensions:', dimensions)

# 定义要使用的粒子数量:
n_particles = 100

print('初始猜测的目标函数:')
print(objective_function(initial_guess_1))

# 重塑以获取所有粒子的初始猜测位置?
# 我不知道是否需要这样做?

initial_guess = initial_guess_1.reshape((1, dimensions))
init_pos = np.tile(initial_guess, (n_particles, 1))

print('一个粒子的初始猜测:')
print(initial_guess_1)

print('所有粒子的初始位置: ')
print(init_pos.shape)
print(init_pos)

# 为优化器定义选项

options = {
    'c1': 0.5,  # 认知参数
    'c2': 0.3,  # 社会参数
    'w': 0.9   # 惯性权重
}

# 创建一个PSO优化器
optimizer = ps.single.GlobalBestPSO(n_particles=n_particles, 
                                    dimensions=dimensions, 
                                    options=options, 
                                    bounds=bounds,
                                    init_pos=init_pos
                                    )

# 使用初始猜测初始化粒子
# optimizer.pos = init_pos

# 运行优化
best_cost, best_position= optimizer.optimize(objective_function, iters=1000, verbose=True)

# 打印结果
print("最佳位置:", best_position)
print("最佳成本:", best_cost)

print('在最佳位置的函数值', objective_function(best_cost))
英文:

trying to understand Particle Swarm Optimization using Python pyswarms package.

https://pyswarms.readthedocs.io/en/latest/intro.html

Need to optimize a function of multiple variables, given as:

# Define the objective function
def objective_function(x):
return ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

I want to find a global minimum in a bounded region if I have an initial guess near that global min.

Here is what I have done, but it's actually not working.
It gives the error:

> ValueError: operands could not be broadcast together with shapes (3,)
> (100,)

Something wrong with the initial guess or bounds? I need to reshape it in some specific way? Please give me a key to resolve that issue..

Can anyone look and explain - what is the problem?
Here is the code to try.

import numpy as np
import pyswarms as ps
# Define the objective function
def objective_function(x):
return  ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)
# Define the bounds for each element of x
bounds = ([-5]*3, [5]*3)
print('Bounds:')
print(bounds)
# Define the initial guesses for each element of x
initial_guess_1 = np.array([1.0, 2.0, 2.9])
# Define the number of elements to optimize
dimensions = initial_guess_1.size
print('Dimensions:', dimensions)
# defining the number of particles to use:
n_particles = 100
print('Objective function for initial guess:')
print(objective_function(initial_guess_1))
# reshaping to get all the particles initial guess positions? 
# I don't know if it's necessary to do this?
initial_guess = initial_guess_1.reshape((1, dimensions))
init_pos = np.tile(initial_guess, (n_particles, 1))
print('Initial guess of one particle:')
print(initial_guess_1)
print('Initial positions for all particles: ')
print(init_pos.shape)
print(init_pos)
# Define the options for the optimizer
options = {
'c1': 0.5,  # cognitive parameter
'c2': 0.3,  # social parameter
'w': 0.9   # inertia weight
}
# Create a PSO optimizer
optimizer = ps.single.GlobalBestPSO(n_particles=n_particles, 
dimensions=dimensions, 
options=options, 
bounds=bounds,
init_pos=init_pos
)
# Initialize the particles with the initial guesses
#optimizer.pos = init_pos
# Run the optimization
best_cost, best_position= optimizer.optimize(objective_function, iters=1000, verbose=True)
# Print the results
print("Best position:", best_position)
print("Best cost:", best_cost)
print('Func value at best pos', objective_function(best_cost))

答案1

得分: 3

你的问题在于你没有考虑模块的工作方式。当你定义了粒子群数量和目标维度时,优化器将创建一个大小为 (nb_swarms x dimensions) 的数组传递给你的目标函数。你可以通过以下方式检查形状和实际传递给目标函数的内容:

def objective_function(x):
    print(x.shape)
    print(f"x_0 : {x[0]}")
    print(f"x_1 : {x[1]}")
    print(f"x_2 : {x[2]}")
    return ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

运行这段代码,你会发现 x[0]、x[1] 和 x[2] 实际上是输入数组的行,而不是列。

修复这个问题的一种简单方法是在你的目标函数中添加类似以下的内容:

def objective_function(x):
    x = x.T
    return ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

这个方法可以解决问题。但更好的方式是测试输入数组的形状,使代码更健壮且易于阅读:

def objective_function(x):
    if x.shape[0] != dimensions:
        x = x.T
    return ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

希望这对你有所帮助,我之前也遇到过类似的问题!

另外,你还应该更正你的代码的最后一行,使用参数 "best_position" 而不是 "best_cost":

print('Func value at best pos', objective_function(best_position))
英文:

So your problem lies on the fact that you did not consider how the module works. When you define your number of swarms and the dimension of your target, the optimizer will create an array of size (nb_swarms x dimensions) to pass onto your objective function.
You can check the shape and what is actually passed to your objective function whith for example the following lines :

def objective_function(x):
print(x.shape)
print(f"x_0 : {x[0]}")
print(f"x_1 : {x[1]}")
print(f"x_2 : {x[2]}")
return  ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

Running this you will see that your x[0], x[1] and x[2] are actually the rows of your input array, not the columns.

A simple way to fix this is to add something like that in your objective function :

def objective_function(x):
x = x.T
return  ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

This works.
But a nicer way would be to test the shape of the input array so it is more robust and nice to read.

For example :

def objective_function(x):
if x.shape[0] != dimensions : 
x = x.T
return  ((x[0] - 1)**2 + (x[1]-2)**2 + (x[2] - 3)**2)

I hope this helps you, I bumped into this before !

P.S. : you should also correct the last line of your code, running the objective function with the argument "best_position" and not "best_cost" :

print('Func value at best pos', objective_function(best_position))

huangapple
  • 本文由 发表于 2023年3月1日 11:09:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75599247.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定