目录
粒子群算法(Particle Swarm Optimization,简称PSO)是一种优化算法,模拟了鸟群或鱼群等群体生物行为的优化思想。
其基本思想是将待求解问题看成一个在多维空间中寻找最优解的优化问题,将每个可能的解看成多维空间中的一个粒子,并将它们随机散布在搜索空间中。
粒子的位置表示一个可行解,粒子的速度表示更新时的变化量。通过给每个粒子分配一个随机的速度向量,指导每个粒子进行探索。同时,使用全局最优和局部最优导引粒子的搜索方向。全局最优即全局最优解的位置,局部最优为某个粒子在个体搜索阶段找到的最优解。将这些信息作为粒子的引导方向,逐渐逼近全局最优解,达到最优化的目的。
设定粒子群种群大小、目标函数及搜索空间。
初始化粒子群:每个粒子的位置和速度都要设置随机初值,并计算其个体适应度。
更新每个粒子的速度和位置:对于第i个粒子,分别计算其个体和全局最优解的影响,然后更新该粒子的速度和位置。
重新计算每个粒子的适应度。
判断是否满足停止条件,若满足停止条件,则输出当前种群中最优的粒子。
否则,返回第3步进行迭代。
PSO算法的优点是可以适应任意目标函数,复杂度不高,具有较好的搜索能力。根据个体最优和全局最优的影响参数的设置不同会影响算法收敛性和导致算法陷入局部最优。PSO算法由于其具有较强的随机性,导致其搜索过程缺乏自适应能力,可能会在搜索过程中出现较大波动。同时,在高维空间中表现欠佳,并且对于复杂问题,需要精细地调节参数才能取得良好的效果。

粒子群算法的核心就在于更新粒子的速度和位置,从而不断搜索搜寻空间寻找最优解。其速度和位置的更新公式包括两个部分:个体最优引导和全局最优引导。
以下是粒子群算法的速度和位置更新公式:
速度更新公式:
v
i
,
d
(
t
+
1
)
=
w
v
i
,
d
(
t
)
+
c
1
r
1
(
p
b
e
s
t
i
,
d
−
x
i
,
d
(
t
)
)
+
c
2
r
2
(
g
b
e
s
t
d
−
x
i
,
d
(
t
)
)
v_{i,d}(t+1) = wv_{i,d}(t) + c_{1}r_{1}(pbest_{i,d}-x_{i,d}(t)) + c_{2}r_{2}(gbest_{d}-x_{i,d}(t))
vi,d(t+1)=wvi,d(t)+c1r1(pbesti,d−xi,d(t))+c2r2(gbestd−xi,d(t))
其中,
v
i
,
d
(
t
)
v_{i,d}(t)
vi,d(t) 表示第 i 个粒子在第 d 维的速度,
t
t
t表示迭代次数,
w
w
w表示惯性权重,
c
1
c_1
c1和
c
2
c_2
c2 表示粒子个体和群体认知系数,
r
1
r_1
r1 和
r
2
r_2
r2 是 0 到 1 之间的随机数,
p
b
e
s
t
i
,
d
pbest_{i,d}
pbesti,d 表示第 i 个粒子在第 d 维度的个体最优位置,
g
b
e
s
t
d
gbest_{d}
gbestd 表示全局最优位置在第 d 维度的取值,
x
i
,
d
(
t
)
x_{i,d}(t)
xi,d(t) 是第 i 个粒子在第 d 维度的位置。
p
b
e
s
t
pbest
pbest是于该粒子之前最优的解,
g
b
e
s
t
gbest
gbest是于所有粒子之前最优的解。
公式中第一项是粒子本身的惯性,第二项是粒子向个体最优点的引力,第三项是粒子向全局最优点的引力。
位置更新公式:
x
i
,
d
(
t
+
1
)
=
x
i
,
d
(
t
)
+
v
i
,
d
(
t
+
1
)
x_{i,d}(t+1) = x_{i,d}(t) + v_{i,d}(t+1)
xi,d(t+1)=xi,d(t)+vi,d(t+1)
其中
x
i
,
d
(
t
)
x_{i,d}(t)
xi,d(t) 表示第 i 个粒子在维度 d 上的位置,
v
i
,
d
(
t
+
1
)
v_{i,d}(t+1)
vi,d(t+1) 表示第 i 个粒子在维度 d 上的速度。通过以上公式,粒子群不断迭代,直到达到所要求的精度或者达到最大迭代次数。
在实际应用中,惯性权重 w 是一个非常重要的参数,控制着算法的局部变化和全局探索的平衡。在迭代过程中,w 的值通常逐渐递减。同时,也需要通过多次实验和调整,确定其他参数的合理取值,以获得更好的优化结果。

实现粒子群算法求解TSP问题的代码:
定义一个 Particle 类用于存储粒子的相关信息;
initialize() 方法来初始化种群;
updatePBest()方法用于更新个体历史最优路径;
updateVelocity() 方法更新粒子速度;
updatePosition()方法更新粒子位置;
定义了 calculateFitness() 方法用于计算适应度(路径长度)。
在 main() 方法中,我们首先调用 initialize() 方法初始化种群,然后通过迭代不断更新粒子的速度、位置、适应度等相关参数,更新个体最优路径和全局最优路径
最终输出最优解路径和路径长度。
public class PSOTSP {
// 城市集合,第i号城市的编码为i
public static int[][] coordinates = {
{200, 40}, {180, 80}, {160, 100}, {140, 120}, {160, 140},
{180, 160}, {200, 200}, {220, 160}, {240, 140}, {260,120},
{240, 100}, {220, 60}, {200, 20}, {240, 20}, {260, 40}
};
// 城市数目
public static int cityNum = coordinates.length;
// 种群规模
public static int populationSize = 50;
// 最大迭代次数
public static int maxGeneration = 200;
// 学习因子,用于控制粒子速度和位置的更新
public static double learningFactor = 0.7;
// 粒子群
public static Particle[] particles = new Particle[populationSize];
// 全局最优解
public static int[] gbest = new int[cityNum];
// 全局最优解路径长度
public static double gbestValue = Double.MAX_VALUE;
// 计算城市间距离,采用欧氏距离
public static double[][] distanceMatrix = new double[cityNum][cityNum];
static {
for (int i = 0; i < cityNum; i++) {
for (int j = i + 1; j < cityNum; j++) {
int xDistance = coordinates[i][0] - coordinates[j][0];
int yDistance = coordinates[i][1] - coordinates[j][1];
distanceMatrix[i][j] = Math.sqrt(xDistance * xDistance + yDistance * yDistance);
distanceMatrix[j][i] = distanceMatrix[i][j];
}
}
}
public static void main(String[] args) {
initialize();
for (int g = 0; g < maxGeneration; g++) {
for (int i = 0; i < populationSize; i++) {
for (int j = 0; j < cityNum; j++) {
particles[i].updateVelocity(gbest, learningFactor);
particles[i].updatePosition();
particles[i].calculateFitness(distanceMatrix);
}
// 更新个体最优解
particles[i].updatePBest();
// 更新全局最优解
if (particles[i].getPBestValue() < gbestValue) {
gbestValue = particles[i].getPBestValue();
System.arraycopy(particles[i].getPBest(), 0, gbest, 0, cityNum);
}
}
}
System.out.print("最优解路径: ");
for (int i = 0; i < cityNum; i++) {
System.out.print(gbest[i] + 1 + " ");
}
System.out.println();
System.out.println("最短路径长度: " + gbestValue);
}
public static void initialize() {
// 初始化粒子
for (int i = 0; i < populationSize; i++) {
particles[i] = new Particle(cityNum);
particles[i].initialize();
particles[i].calculateFitness(distanceMatrix);
// 更新全局最优解
if (particles[i].getPBestValue() < gbestValue) {
gbestValue = particles[i].getPBestValue();
System.arraycopy(particles[i].getPBest(), 0, gbest, 0, cityNum);
}
}
}
// 定义粒子实体类
public static class Particle {
// 存储粒子经过的路径,初始化为-1
private int[] path;
// 存储粒子历史最优路径
private int[] pbest;
// 粒子当前位置的适应度值
private double fitness;
// 粒子历史最优位置的适应度值
private double pbestValue;
// 存储粒子当前速度
private double[] velocity;
// 最大速度
private static double vmax = 5;
public Particle(int length) {
path = new int[length];
pbest = new int[length];
velocity = new double[length];
}
// 随机初始化粒子位置和速度
public void initialize() {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < path.length; i++) {
list.add(i);
path[i] = -1;
velocity[i] = 0;
}
Collections.shuffle(list);
for (int i = 0; i < path.length; i++) {
path[i] = list.get(i);
}
System.arraycopy(path, 0, pbest, 0, path.length);
pbestValue = fitness;
}
// 计算当前位置的适应度值
public void calculateFitness(double[][] distanceMatrix) {
double pathLength = 0;
for (int i = 0; i < path.length - 1; i++) {
pathLength += distanceMatrix[path[i]][path[i + 1]];
}
pathLength += distanceMatrix[path[path.length - 1]][path[0]];
fitness = pathLength;
}
// 更新个体历史最优位置
public void updatePBest() {
if (fitness < pbestValue) {
System.arraycopy(path, 0, pbest, 0, path.length);
pbestValue = fitness;
}
}
// 更新粒子速度
public void updateVelocity(int[] gbest, double learningFactor) {
// 计算个体和全局最优差距
double[] deltaPbest = new double[path.length];
double[] deltaGbest = new double[path.length];
for (int i = 0; i < path.length; i++) {
deltaPbest[i] = pbest[i] - path[i];
deltaGbest[i] = gbest[i] - path[i];
}
for (int i = 0; i < path.length; i++) {
// 估算粒子的局部最优解和全局最优解的距离占所有点之间距离的比值
double alpha = Math.random() * learningFactor;
// 更新速度
velocity[i] = alpha * velocity[i] + deltaPbest[i] * Math.random()
+ (1 - alpha) * deltaGbest[i] * Math.random();
// 控制速度不超过最大限制
if (velocity[i] > vmax) {
velocity[i] = vmax;
} else if (velocity[i] < -vmax) {
velocity[i] = -vmax;
}
}
}
// 更新粒子位置
public void updatePosition() {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < path.length; i++) {
list.add(path[i]);
}
for (int i = 0; i < path.length; i++) {
int index = list.indexOf(i);
int moveLength = (int) Math.round(velocity[i]);
int newPosition = (index + moveLength + path.length) % path.length;
if (newPosition < list.size() && newPosition > 0) {
list.add(newPosition, i);
list.remove(index < 0 ? list.size() - 1 : index);
}
}
for (int i = 0; i < path.length; i++) {
path[i] = list.get(i);
}
}
public double getPBestValue() {
return pbestValue;
}
public int[] getPBest() {
return pbest;
}
}
}
☕物有本末,事有终始,知所先后。🍭
🍎☝☝☝☝☝我的CSDN☝☝☝☝☝☝🍓
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
我一直在尝试用Ruby实现Luhn算法。我一直在执行以下步骤:该公式根据其包含的校验位验证数字,该校验位通常附加到部分帐号以生成完整帐号。此帐号必须通过以下测试:从最右边的校验位开始向左移动,每第二个数字的值加倍。将乘积的数字(例如,10=1+0=1、14=1+4=5)与原始数字的未加倍数字相加。如果总模10等于0(如果总和以零结尾),则根据Luhn公式该数字有效;否则无效。http://en.wikipedia.org/wiki/Luhn_algorithm这是我想出的:defvalidCreditCard(cardNumber)sum=0nums=cardNumber.to_s.s
下面是我写的一个计算斐波那契数列中的值的方法:deffib(n)ifn==0return0endifn==1return1endifn>=2returnfib(n-1)+(fib(n-2))endend它工作到n=14,但在那之后我收到一条消息说程序响应时间太长(我正在使用repl.it)。有人知道为什么会这样吗? 最佳答案 Naivefibonacci进行了大量的重复计算-在fib(14)fib(4)中计算了很多次。您可以将内存添加到您的算法中以使其更快:deffib(n,memo={})ifn==0||n==1returnnen
为了防止在迁移到生产站点期间出现数据库事务错误,我们遵循了https://github.com/LendingHome/zero_downtime_migrations中列出的建议。(具体由https://robots.thoughtbot.com/how-to-create-postgres-indexes-concurrently-in概述),但在特别大的表上创建索引期间,即使是索引创建的“并发”方法也会锁定表并导致该表上的任何ActiveRecord创建或更新导致各自的事务失败有PG::InFailedSqlTransaction异常。下面是我们运行Rails4.2(使用Acti
我正在开发一个类似微论坛的项目,其中一个特殊用户发布一条快速(接近推文大小)的主题消息,订阅者可以用他们自己的类似大小的消息来响应。直截了当,没有任何形式的“挖掘”或投票,只是每个主题消息的响应按时间顺序排列。但预计会有很高的流量。我们想根据它们引起的响应嗡嗡声来标记主题消息,使用0到10的等级。在谷歌上搜索了一段时间的趋势算法和开源社区应用示例,到目前为止已经收集到两个有趣的引用资料,但我还没有完全理解它们:Understandingalgorithmsformeasuringtrends,关于使用基线趋势算法比较维基百科页面浏览量的讨论,在SO上。TheBritneySpearsP
我收到错误:unsupportedcipheralgorithm(AES-256-GCM)(RuntimeError)但我似乎具备所有要求:ruby版本:$ruby--versionruby2.1.2p95OpenSSL会列出gcm:$opensslenc-help2>&1|grepgcm-aes-128-ecb-aes-128-gcm-aes-128-ofb-aes-192-ecb-aes-192-gcm-aes-192-ofb-aes-256-ecb-aes-256-gcm-aes-256-ofbRuby解释器:$irb2.1.2:001>require'openssl';puts
文章目录一.Dijkstra算法想解决的问题二.Dijkstra算法理论三.java代码实现一.Dijkstra算法想解决的问题解决的问题:求解单源最短路径,即各个节点到达源点的最短路径或权值考察其他所有节点到源点的最短路径和长度局限性:无法解决权值为负数的情况二.Dijkstra算法理论参数:S记录当前已经处理过的源点到最短节点U记录还未处理的节点dist[]记录各个节点到起始节点的最短权值path[]记录各个节点的上一级节点(用来联系该节点到起始节点的路径)Dijkstra算法步骤:(1)初始化:顶点集S:节点A到自已的最短路径长度为0。只包含源点,即S={A}顶点集U:包含除A外的其他顶
对于体育新闻中文文本的关键字提取,常用的算法包括TF-IDF、TextRank和LDA等。它们的基本步骤如下:1.TF-IDF算法: -将文本进行分词和词性标注处理。-统计每个词在文本中的词频(TF)。-计算每个词在整个语料库中出现的文档频率(DF)和逆文档频率(IDF)。-计算每个词的TF-IDF值,并按照值的大小进行排序,选择排名前几的词作为关键字。2.TextRank算法:-将文本进行分词和词性标注处理。-将分词结果转化成图模型,每个词语为节点,根据词语之间的共现关系建立边。-对图模型进行迭代计算,计算每个节点的PageRank值,表示该节点的重要性。-选择排名前几的节点作为关键字。3.
我正在尝试计算由二进制形式的1和0的P数表示的数字的数量。如果P=2,则表示的数字为0011、1100、0110、0101、1001、1010,所以计数为6。我试过:[0,0,1,1].permutation.to_a.uniq但这不是大数的最佳解决方案(P可以什么可能是最好的排列技术,或者我们是否有任何直接的数学来做到这一点? 最佳答案 Numberofpermutationcanbecalculatedusingfactorial.a=[0,0,1,1](1..a.size).inject(:*)#=>4!=>24要计算重复项,