PSO算法实践

  • 高级AI留了课后题PSO算法计算最值,一时兴起就做了一下

  • 在这里插入图片描述

  • PSO算法的大致流程如下图所示:

  • 在这里插入图片描述

  • 对于实现来说,f(x)函数就是那个适应度函数:
    f ( x ) = x 3 − 5 x 2 − 2 x + 3 f(x) = x^3-5x^2-2x+3 f(x)=x35x22x+3

  • 然后pbest是数组,gbest是单独维护的最值,考虑到两个最值的求法相似,于是分开写(主要是维护双倍变量很麻烦~~),代码如下,有点长,两个类的方法差不多的,看一个即可:

import random
class PSOMax:
    def __init__(self,
                 xList: list,
                 vList: list,
                 xmax: int = 5,
                 xmin: int = -2) -> None:
        self.xList = xList
        self.pBest = xList

        self.vList = vList
        self.gBest = -2
        self.c1, self.c2 = 2, 2
        self.xmax = xmax
        self.xmin = xmin
        self.init()
        self.printInfo()

    def runPSO(self):
        tmpBest = self.fun(self.gBest)
        for index in range(len(self.xList)):
            self.vList[index] += self.c1 * random.random() * (
                self.pBest[index] - self.xList[index]
            ) + self.c2 * random.random() * (self.gBest - self.xList[index])
            self.xList[index] += self.vList[index]

            # 保证是落在范围里
            while self.xList[index] > self.xmax or self.xList[
                    index] < self.xmin:
                if self.xList[index] > self.xmax:
                    self.xList[index] = 2 * self.xmax - self.xList[index]
                if self.xList[index] < self.xmin:
                    self.xList[index] = 2 * self.xmin - self.xList[index]

            tmp = self.fun(self.xList[index])
            # 更新 gbest pbest
            self.pBest[index] = self.xList[index] if tmp > self.fun(
                self.pBest[index]) else self.pBest[index]
            self.gBest = self.xList[index] if tmp > tmpBest else self.gBest
        # self.printInfo()

    def fun(self, x):
        # return x**3 - 5 * x**2 - 2 * x + 3
        return x**3 - 5 * x**2 - 2 * x + 3

    def init(self):

        for x in self.xList:
            self.gBest = x if self.fun(x) > self.fun(
                self.gBest) else self.gBest

    def printInfo(self):
        print("{}::self.gBest={},bestValue={}".format(self.__class__.__name__, self.gBest,
                                                      self.fun(self.gBest)))
        # print("self.pBest={}".format(self.pBest))
        # print("self.xList={}".format(self.xList))


class PSOMin:
    def __init__(self,
                 xList: list,
                 vList: list,
                 xmax: int = 5,
                 xmin: int = -2) -> None:
        self.xList = xList
        self.pBest = xList

        self.vList = vList
        self.gBest = -2
        self.c1, self.c2 = 2, 2
        self.xmax = xmax
        self.xmin = xmin
        self.init()
        self.printInfo()

    def runPSO(self):
        tmpBest = self.fun(self.gBest)
        for index in range(len(self.xList)):
            self.vList[index] += self.c1 * random.random() * (
                self.pBest[index] - self.xList[index]
            ) + self.c2 * random.random() * (self.gBest - self.xList[index])
            self.xList[index] += self.vList[index]

            # 保证是落在范围里
            while self.xList[index] > self.xmax or self.xList[
                    index] < self.xmin:
                if self.xList[index] > self.xmax:
                    self.xList[index] = 2 * self.xmax - self.xList[index]
                if self.xList[index] < self.xmin:
                    self.xList[index] = 2 * self.xmin - self.xList[index]

            tmp = self.fun(self.xList[index])
            # 更新 gbest pbest
            self.pBest[index] = self.xList[index] if tmp < self.fun(
                self.pBest[index]) else self.pBest[index]
            self.gBest = self.xList[index] if tmp < tmpBest else self.gBest
        # self.printInfo()

    def fun(self, x):
        # return x**3 - 5 * x**2 - 2 * x + 3
        return x**3 - 5 * x**2 - 2 * x + 3

    def init(self):
        for x in self.xList:
            self.gBest = x if self.fun(x) < self.fun(
                self.gBest) else self.gBest

    def printInfo(self):
        print("{}::self.gBest={},bestValue={}".format(self.__class__.__name__, self.gBest,
                                                      self.fun(self.gBest)))
        # print("self.pBest={}".format(self.pBest))
        # print("self.xList={}".format(self.xList))


if __name__ == '__main__':
    p = PSOMin(xList=[-2, 3, -1, 2],
               vList=[0.001, 0.001, 0.001, 0.001, 0.001],
               xmax=5,
               xmin=-2)
    for _ in range(100):
        p.runPSO()
    p.printInfo()
    p = PSOMax(xList=[-2, 3, -1, 2],
               vList=[0.001, 0.001, 0.001, 0.001, 0.001],
               xmax=5,
               xmin=-2)
    for _ in range(100):
        p.runPSO()
    p.printInfo()

猜你喜欢

转载自blog.csdn.net/symuamua/article/details/121505265
pso