Ant Colony Algorithm of Intelligent Algorithm Series (Detailed Supplementary Version)

insert image description here

  The cover of this blog ChatGPT + DALL·E 2was co-authored.

foreword

  This article is the sixth article of the Intelligent Algorithm (Python Reproduction) column, which is mainly a supplement to the ant colony algorithm.
  In the previous blog, the principle of the ant colony algorithm was briefly introduced, and the pythonapplication of the ant colony algorithm in finding the extreme value of the function was realized, but after careful study, it was found that the key points were not highlighted, and it was different from TSPthe ant colony in the original problem. The algorithm is quite different, and it feels that it only involves the shell of the ant colony algorithm, and does not touch the soul.
  Therefore, in this article, a detailed supplement is made to the application of the ant colony algorithm in finding the extreme value of the function, and the soul of the ant colony algorithm is touched as much as possible.

  Paper Reference: Applying Ant Colony Algorithm to Solve All Extreme Values ​​of a Function ( HowNet )

1. Improvement method

  Let the one-dimensional function y = f ( x ) y=f(x)y=The domain of f ( x ) is [ a , b ] [a, b][a,b ] .
  (1)the interval[ a , b ] [a, b][a,b ] is divided into several subintervals of equal length, these subintervals are recorded as{ I 1 , I 2 , . . . , I n } \{I_1,I_2,...,I_n\}{ I1,I2,...,In} , intervalI i I_iIiThe midpoint of xi is denoted as x_ixi;
  (2)Let and interval I i I_iIiThe adjacent interval is I i + 1 I_{i+1}Ii+1, I i I_iIiSum I i + 1 I_{i+1}Ii+1There is a virtual edge e between ( I i + 1 , I i + 1 ) e(I_{i+1}, I_{i+1})e ( Ii+1,Ii+1) , the weight of the edge (virtual distance) andf ( xi ) − f ( xi + 1 ) f(x_i) - f(x_{i+1})f(xi)f(xi+1) ,f ( xi ) − f ( xi + 1 ) f(x_i) - f(x_{i+1})f(xi)f(xi+1) is bigger, the ant from the intervalI i I_iIiShift to interval I i + 1 I_{i+1}Ii+1The greater the possibility;
  (3)the ant from the interval I i I_iIiShift to interval I i + 1 I_{i+1}Ii+1Finally, to leave the pheromone, the size of the pheromone left is the same as f ( xi ) − f ( xi + 1 ) f(x_i) - f(x_{i+1})f(xi)f(xi+1) related quantity, intervalI i + 1 I_{i+1}Ii+1The more pheromones there are, the more ants in the adjacent intervals are attracted to transfer to it;
  (4)after the ants have transferred many times, some intervals contain many ants, while some intervals do not contain ants. The intervals containing ants are exactly the intervals containing extreme points, and the intervals without ants are unlikely to contain extreme points;
  (5)take out the intervals containing ants and refine them again, repeat the above search process until the refinement interval is small enough.
  In the end, the ants stayed near the extreme point, and the midpoint of the interval where the ants were located was exactly the position of the extreme point.

2. Ant colony initialization

  First, the domain of the problem [ a , b ] [a, b][a,b ] fornnn equal division, the length of each interval after equal division is σ = b − an \sigma = \frac {ba} {n}p=nbaEach interval is written as { I 1 , I 2 , . . . , In } \{I_1,I_2,...,I_n\}{ I1,I2,...,In} , ), whereI i ( i = 1 , 2 , . . , n ) I_i(i=1,2,..,n)Ii(i=1,2,..,n ) means theiii个区间,则 I i = [ a + ( i − 1 ) σ , a + i σ ] I_i=[a+(i-1)\sigma, a+i\sigma] Ii=[a+(i1 ) p ,a+] , display intervalI i I_iIiThe left and right endpoints of the interval I i I_iIiThe midpoint position of is denoted as xi x_ixi,则 x i = a + ( i − 1 2 ) σ x_i=a+(i-\frac {1} {2})\sigma xi=a+(i21) σ assumes that there is a total of mm  in the ant colonym ants, recorded as{ a 1 , a 2 , . . . , an } \{a_1,a_2,...,a_n\}{ a1,a2,...,an} In general,m ≥ nm \geq nmn . At the beginning, an interval is randomly assigned to each ant, and the position of the ant is the midpoint of the interval. τ i ( t ) \tau _i(t)ti( t ) meansttSubintervalii at time tFor the pheromone on i , the pheromone concentration of each subinterval is the same at the beginning, and the default is1.0;Δ τ i ( t ) \Delta \tau _i(t)D ti( t ) meansttSubintervalii at time tThe pheromone increment on i , the initial pheromone increment of each subinterval is also the same, the default is0.

3. Ant mobile strategy

  假设 n e i g h b o r ( I i ) neighbor(I_i) neighbor(Ii) display intervalI i I_iIiNeighboring interval set, function neighbor ( I i ) = { { I i + 1 } , i = 1 { I i − 1 , I i + 1 } , i = 2 , 3 , . . . , n − 1 { I i − 1 } , i = n neighbor(I_i) = \begin{cases} \{I_{i+1}\}, & i=1\\ \{I_{i-1}, I_{ i+1}\}, & i=2,3,...,n-1\\ \{I_{i-1}\}, & i=n \end{cases}neighbor(Ii)= { Ii+1},{ Ii1,Ii+1},{ Ii1},i=1i=2,3,...,n1i=n  in interval I i I_iIiThe ants of the adjacent interval I j I_jIjtransfer, assuming I i I_iIiSum I j I_jIjThere is a virtual edge e ( I i , I j ) e(I_i,I_j)e ( Ii,Ij) , the weight of this edge is∣ f ( xi ) − f ( xj ) ∣ \bigg| f(x_i) - f(x_j) \bigg| f(xi)f(xj) , then the heuristic function η ij = ∣ f ( xi ) − f ( xj ) ∣ \eta_{ij} = \bigg| f(x_i) - f(x_j) \bigg|theij= f(xi)f(xj)   Let ant ak a_kakCurrently in interval I i I_iIi,若 f ( x i ) − f ( x j ) > 0 f(x_i) - f(x_j) > 0 f(xi)f(xj)>0,The interval before displayI i I_iIiThe value above is larger, the ant ak a_kakcan be transferred to its adjacent interval I j I_jIj; Otherwise, the ants will not transfer to it. Let allowedk allow_kallowedkmeans ant ak a_kakA collection of subintervals that can be transferred in the next step.
  Use pijk ( t ) p_{ij}^k(t)pijk( t ) means thetttht cycle antak a_kakFrom child section I i I_iIiTransfer to subinterval I j I_jIjThe probability of imitating the basic ant colony algorithm, defining ant ak a_kakDerive the functions: pijk ( t ) = { τ j α ( t ) η ij β ∑ h ∈ allowedk τ j α ( t ) η ih β , j ∈ allowedk 0 , j ∉ allowedk p_{ij}^k(t). ) = \begin{cases}\frac {\tau_j^{\alpha}(t) \\eta_{ij}^{\beta}} {\sum_{h\in allowed_k} \tau_j^{\alpha}(t ) \\eta_{ih}^{\beta}}, &j \in allowed_k\\\\0, &j \notin allowed_k\end{cases}pijk(t)= hallowedktja( t ) h ihbtja( t ) h ijb,0,jallowedkj/allowedk  Among them, α \alphaα is the information heuristic factor (pheromone importance factor),β \betaβ is the expected heuristic factor (heuristic function importance factor),τ j \tau _jtjToshi interval I i {I_i}Iipheromone concentration.

4. Pheromone update

  if ant ak a_kakFrom subinterval I i I_i according to probabilityIitransferred to the subinterval I j I_jIj, then the ant ak a_kakIt will leave pheromone in the interval, and the amount of pheromone left is expressed by Δ τ jk ( t ) \Delta \tau_j^{k}(t)D tjk(t)表示,则 Δ τ j k ( t ) = C ( f ( x i ) − f ( x j ) ) \Delta \tau_j^{k}(t) = C\bigg( f(x_i) - f(x_j) \bigg) D tjk(t)=C(f(xi)f(xj) )   Among them,CCC represents a constant,f ( xi ) − f ( xj ) f(x_i) - f(x_j)f(xi)f(xj) is bigger, it means antak a_kakThe more pheromone left, the more it attracts other ants to the interval I j I_jIjtransfer.
  All transfers to interval I j I_jIjThe ants of all must leave corresponding pheromones, assuming that at ttt cycles, withbbb ants moved to intervalI j I_jIj, then this bbb ants are in the intervalI j I_jIjThe sum of pheromone left on is Δ τ j ( t ) = ∑ c = 1 b Δ τ jc ( t ) \Delta \tau_j(t) = \sum_{c=1} ^{b} \Delta \tau_j^{ c}(t)D tj(t)=c=1bD tjc( t )   After all ants complete a neighboring interval transfer, they need to update the pheromone
. IntervalI j I_jIjThe pheromone concentration of τ j \tau_jtj手机的τ j ( t + 1 ) = ( 1 − 1 ρ ) τ j ( t ) + Δ τ j ( t ) \tau_j(t+1) = (1-1\rho)\tau_j(t) + \ Delta \tau_j(t)tj(t+1)=(11 r ) tj(t)+D tj( t )   where,ρ \rhoρ represents the pheromone volatilization coefficient.

5. Reducing the search space of ant colony

  The interval with smaller function value will contain more pheromone, which is more likely to attract ants to transfer to it. After some cycles, when all the ants stop transferring, the ant colony distribution will have such characteristics: all ants are distributed in the interval with smaller extreme points, while there are no ants in other intervals, that is, the interval containing ants contains extreme points. small value point.
  Take out these intervals containing ants, and refine these intervals again, and let the ant colony search for the minimum point in these intervals in the next cycle. If this cycle continues, the search range of the ant colony will become smaller and smaller. When the refined interval is small enough, all ants will stay near the extreme point, and the midpoint of the interval where the ant stays is the extreme value point location.
  A threshold is set in the paper. After all, it is impossible to subdivide indefinitely. When the step size of the interval is smaller than the threshold, the subdivision of the interval is stopped and the search ends. In the implementation of this paper, the operation in the paper is not adopted, but a small interval step is directly adopted at the beginning, so that the optimal solution searched is very close to the theoretical optimal value.

6. Code implementation

# -*- coding:utf-8 -*-
# Author:   xiayouran
# Email:    [email protected]
# Datetime: 2023/5/6 14:59
# Filename: ant_colony_optimization.py
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from base_algorithm import BaseAlgorithm


__all__ = ['AntColonyOptimization']


class Ant:
    def __init__(self):
        self.id = None          # 蚂蚁所在区间的id
        self.eta = None         # 启发式信息, 存放本区间与其左右两个区间的函数差值
        self.tran_prob = None   # 状态转移概率


class Interval:
    def __init__(self):
        self.position = None    # 该区间上的中点
        self.tau = 1.           # 信息素浓度值
        self.delta_tau = 0.     # 信息素浓度增量
        self.count = 0          # 此区间上蚂蚁的数量


class AntColonyOptimization(BaseAlgorithm):
    def __init__(self, population_size=100, max_iter=200, alpha=1.5, beta=0.8, rho=0.3, epsilon=1e-4,
                 q=1.0, step=0.01, x_range=(0, 5), seed=10086):
        super(AntColonyOptimization, self).__init__()
        self.__population_size = population_size  # 蚂蚁种群大小
        self.__max_iter = max_iter  # 最大迭代次数
        self.__alpha = alpha        # 信息素重要程度因子
        self.__beta = beta          # 启发函数重要程度因子
        self.__rho = rho            # 信息素蒸发系数
        self.__epsilon = epsilon    # 停止搜索门限
        self.__q = q                # 信息素释放增量系数, 常量C
        self.__step = step          # 子区间间隔
        self.__x_range = x_range    # 变量x的定义域
        self.__population = []      # 蚁群
        self.__interval_set = []    # 区间集合(对应TSP问题中的city)
        self.__tabu = []            # 禁忌表
        self.__seed = seed
        self.optimal_solution = None

        np.random.seed(seed)

    def init_interval_set(self):
        for left_point in np.arange(*self.__x_range, self.__step):
            interval = Interval()
            interval.position = left_point + self.__step / 2  # 区间中点
            self.__interval_set.append(interval)

        if len(self.__interval_set) > self.__population_size:
            tmp_size = self.__population_size
            self.__population_size = int(np.ceil(len(self.__interval_set) / self.__population_size) * self.__population_size)
            print("Suggest a larger value for population_size, the value for population_size has been "
                  "changed from {} to {}".format(tmp_size, self.__population_size))

    def init_tabu(self):
        self.__tabu = np.zeros(shape=(len(self.__interval_set), 2))   # 初始禁忌表, 当前点与左右两坐标
        # TSP中的禁忌表的shape是(m, n), 其中m为蚂蚁数量, n为城市数量, 确保每只蚂蚁仅能访问城市一次

    def update_eta(self, ant):
        index = ant.id
        interval = self.__interval_set[index]
        ant.eta = []

        if index == 0:
            ant.eta.append(0)
            ant.eta.append(self.problem_function(interval.position) - self.problem_function(
                interval.position + self.__step))
        elif index == len(self.__interval_set) - 1:
            ant.eta.append(self.problem_function(interval.position) - self.problem_function(
                interval.position - self.__step))
            ant.eta.append(0)
        else:
            ant.eta.append(self.problem_function(interval.position) - self.problem_function(
                interval.position - self.__step))  # 当前区间(中点)与左邻居区间(中点)的差值
            ant.eta.append(self.problem_function(interval.position) - self.problem_function(
                interval.position + self.__step))  # 当前区间(中点)与右邻居区间(中点)的差值

    def update_tabu(self, ant):
        index = ant.id
        if ant.eta[0] > 0:
            self.__tabu[index, 0] = 1  # 表示左子区间值较小, 可以跳转
        if ant.eta[1] > 0:
            self.__tabu[index, 1] = 1  # 表示右子区间值较小, 可以跳转

    def init_population(self):
        # 初始化区间集合
        self.init_interval_set()

        # 初始化禁忌表
        self.init_tabu()

        for i in range(self.__population_size):
            index = np.random.choice(range(len(self.__interval_set)))   # 随机选择一个区间
            # index = i
            interval = self.__interval_set[index]
            interval.count += 1

            ant = Ant()
            ant.id = index

            # 更新eta
            self.update_eta(ant)

            # 更新禁忌表tabu
            self.update_tabu(ant)

            # 更新蚂蚁的状态转移概率
            ant.tran_prob = interval.tau * ant.eta[0] / (interval.tau * ant.eta[0] + interval.tau * ant.eta[1])  # 蚂蚁向左区间跳转概率

            self.__population.append(ant)

    def skip_left(self, ant):
        index = ant.id

        interval = self.__interval_set[index]
        interval.count -= 1  # 此区间蚂蚁数-1
        left_interval = self.__interval_set[index - 1]
        left_interval.count += 1  # 左区间蚂蚁数+1
        ant.id -= 1  # 蚂蚁跳转至左区间
        left_interval.delta_tau = left_interval.delta_tau + self.__q * ant.eta[0]

    def skip_right(self, ant):
        index = ant.id

        interval = self.__interval_set[index]
        interval.count -= 1  # 此区间蚂蚁数-1
        right_interval = self.__interval_set[index + 1]
        right_interval.count += 1  # 右区间蚂蚁数+1
        ant.id += 1  # 蚂蚁跳转至右区间
        right_interval.delta_tau = right_interval.delta_tau + self.__q * ant.eta[1]

    def search_local_optimal_solution(self):
        flag = np.ones(self.__population_size)
        while np.sum(flag):
            for i, ant in enumerate(self.__population):
                index = ant.id
                if self.__tabu[index, 0] and not self.__tabu[index, 1]:
                    # 蚂蚁可以向左区间跳转
                    self.skip_left(ant)
                elif not self.__tabu[index, 0] and self.__tabu[index, 1]:
                    # 蚂蚁可以向右区间跳转
                    self.skip_right(ant)
                elif self.__tabu[index, 0] and self.__tabu[index, 1]:
                    # 两个区间都可以跳转, 计算一下蚂蚁的状态转移概率
                    if ant.tran_prob > np.random.rand():
                        # 蚂蚁向左区间跳转
                        self.skip_left(ant)
                    else:
                        # 蚂蚁向右区间跳转
                        self.skip_right(ant)
                else:
                    flag[i] = 0     # 表示此蚂蚁不再进行跳转了

                self.update_eta(ant)    # 更新eta
                self.update_tabu(ant)   # 更新禁忌表

            for interval in self.__interval_set:
                # 更新区间上的信息素
                interval.tau = (1 - self.__rho) * interval.tau + interval.delta_tau

    def print_local_optimal_solution(self):
        print('local optimal solution:')
        local_optimal_solution = {
    
    }
        best_point = np.inf
        for ant in self.__population:
            index = ant.id
            if not local_optimal_solution.get(index, ''):
                local_optimal_solution[index] = (self.__interval_set[index].position,
                                                 self.problem_function(self.__interval_set[index].position))
                print(local_optimal_solution[index])
                if best_point > local_optimal_solution[index][1]:
                    best_point = local_optimal_solution[index][1]
                    self.optimal_solution = local_optimal_solution[index]

    def solution(self):
        self.init_population()
        self.search_local_optimal_solution()
        self.print_local_optimal_solution()

        print('the optimal solution is', self.optimal_solution)


if __name__ == "__main__":
	algo = AntColonyOptimization()
	algo.solution()

  The visualization effect of the ant colony algorithm is as follows:

insert image description here

Code repository: IALib[GitHub]

  The code of this article has been synchronized to Pythonthe exclusive warehouse of the [Smart Algorithm (Recurrence)] column: Algorithms in the IALib
  runtime library:IALibACO

git clone [email protected]:xiayouran/IALib.git
cd examples
python main.py -algo aco

Guess you like

Origin blog.csdn.net/qq_42730750/article/details/130662474