Lishengxie
  • Posts
  • About
  • Contact
  1. Home
  2. Posts
  3. 启发式优化算法学习-模拟退火

启发式优化算法学习-模拟退火

Apr 30, 2023 算法学习 Lishengxie

模拟退火算法(SA)

参考教程 https://blog.csdn.net/brilliantZC/article/details/124436967

模拟退火算法(Simulated Annealing,SA)是一种模拟物理退火过程而设计的优化算法。模拟退火算法采用类似于物理退火的过程。先在一个高温状态下(算法初始化随机解),然后逐渐退火,在每个温度下慢慢冷却,最终达到物理基态(相当于算法找到最优解)。模拟退火算法采用Metropolis准则,并用一组称为冷却进度表的参数控制算法的进程,使得算法在多项式时间里可以给出一个近似最优解。

SA算法运行流程

step1: 设定当前解(即为当前的最优解):令\(T =T_0\),即开始退火的初始温度,随机生成一个初始解\(x_0\),并计算相应的目标函数值\(E(x_0)\)。 step2: 产生新解与当前解差值:根据当前解\(x_i\)进行扰动,产生一个新解\(x_j\),计算相应的目标函数值\(E(x_j)\),得到\(\Delta E = E(x_j)-E(x_i)\)。 step3: 判断新解是否被接受 :若\(\Delta E< 0\),则新解\(x_j\)被接受;若\(\Delta E> 0 \),则新解\(x_j\)按概率\(e^{\frac{-(E(x_j)-E(x_i))}{T_i}}\)被接受,\(T_i\)为当前温度。 step4: 当新解被确定接受时,新解\(x_j\)被作为当前解。 step5: 循环以上四个步骤:在温度\(T_i\)下,重复\(k\)次的扰动和接受过程,接着执行下一步骤。 step6: 最后找到全局最优解:判断\(T\)是否已经达到终止温度\(T_f\),是,则终止算法;否,则转到循环步骤继续执行。

SA算法求解映射问题

映射问题本质上可以看作一个序列的排序问题,使用SA算法求解时,需要关注的是如何产生新解,这里我们采用如下的方法:再序列中随机选取两个不重合的位置,将这两个位置中间的序列反转达到局部扰动的目的。

SA算法求解映射问题代码

# -*- coding: utf-8 -*-
# Lishengxie
# 2023-02-23
# Implementation of a Simulated Annealing algorithm for crossbar mapping/placing
# 参考链接: https://blog.csdn.net/weixin_58427214/article/details/125901431
# 参考链接: https://blog.csdn.net/brilliantZC/article/details/124436967

import numpy as np
import copy
import sys
import random

class SAPlacer:
    """
        SA algorithm
        -------------
        Class used to find the mapping from computing cores to routers on NoC which minizes the communication cost
    """
    def __init__(self, dim_x, dim_y, spike_table, L=200, K=0.95, S=0.04, T=100, T_threshold=0.01):
        """
            Initialization of PsoPlacer.
            Args:
                dim_x: int, the `x` dimension on NoC 
                dim_y: int, the `y` dimension on NoC 
                spike_table: 2D-array, the number of spikes between core `i` and core `j`
                L: int, 每个温度下的迭代次数
                K: float, 温度的衰减参数, T = K*T
                S: float, 步长因子
                T: float, 初始温度
                T_threshold: float, 终止温度
        """
        self.dim_x = dim_x
        self.dim_y = dim_y
        self.dim_size = dim_x * dim_y
        self.L = L
        self.K = K
        self.S = S
        self.T = T
        self.T_threshold = T_threshold
        if spike_table is not None:
            self.init_solution(spike_table)

    def init_solution(self, spike_table):
        """
            Init spike table, hop distance table and solution.
        """
        # init spike table
        self.spike_table = np.zeros((self.dim_size, self.dim_size))
        h, w = spike_table.shape
        for i in range(h):
            for j in range(w):
                self.spike_table[i,j] = spike_table[i,j]

        # init hop distance table
        self.hop_xy()

        # init solution
        self.pre_x = np.arange(self.dim_size)
        np.random.shuffle(self.pre_x)
        self.pre_bestx = self.pre_x
        self.pre_x = np.arange(self.dim_size)
        np.random.shuffle(self.pre_x)
        self.prex_cost = self.fitnessFuntcion(self.pre_x)
        self.bestx = self.pre_x
        self.bestx_cost = self.fitnessFuntcion(self.bestx)

    def hop_xy(self):
        """
            The hop distance between router `x` and `y` in the 2D-Mesh NoC using XY routing
        """
        self.hop_dist = np.zeros((self.dim_size, self.dim_size))
        for i in range(self.dim_size):
            for j in range(self.dim_size):
                self.hop_dist[i,j] = abs(i % self.dim_x - j % self.dim_x) \
                                + abs(i // self.dim_x - j // self.dim_x)
        
    def fitnessFuntcion(self, solution):
        """
            Compute the communication cost for each mapping solution
            Args:
                solution: List, a possible mapping solution
        """
        cost = 0
        for i in range(self.dim_size):
            for j in range(self.dim_size):
                cost +=  self.spike_table[i,j] * self.hop_dist[solution[i], solution[j]]
        return cost

    def place(self):
        """
            Execute the Simulated Annealing algorithm
        """
        P = 0
        next_x = np.arange(self.dim_size)
        np.random.shuffle(next_x)
        nextx_cost = self.fitnessFuntcion(next_x)

        while (self.T > self.T_threshold):
            self.T = self.K * self.T        # 降温
            # 当前温度T下迭代次数
            for i in range(self.L):
                # ====在此点附近随机选下一点=====
                # 选择两个随机位置, 将两个位置之间的数组进行翻转
                positions = np.random.choice(list(range(self.dim_size)), replace=False, size=2)
                x = min(positions[0], positions[1])
                y = max(positions[0], positions[1])
                mid_reversed = next_x[x:y+1][::-1]
                next_x[x:y+1] = mid_reversed
                
                if random.random() <= 0.0001:
                    np.random.shuffle(next_x)
                    
                nextx_cost = self.fitnessFuntcion(next_x)
                if nextx_cost < self.bestx_cost:
                    self.pre_bestx = self.bestx
                    self.bestx = next_x
                    self.bestx_cost = nextx_cost

                if nextx_cost < self.prex_cost:
                    self.pre_x = next_x
                    self.prex_cost = nextx_cost
                    P = P + 1
                else:
                    changer = -1 * (nextx_cost - self.prex_cost) / self.T
                    p1 = np.exp(changer)
                    if p1 > np.random.random():
                        self.pre_x = next_x
                        self.prex_cost = nextx_cost
                        P = P + 1

            print("Current T: {:.7f}, best cost: {}".format(self.T, self.bestx_cost))

        return self.bestx

Table of Contents

  • 模拟退火算法(SA)
    • SA算法运行流程
    • SA算法求解映射问题
    • SA算法求解映射问题代码

Recent Posts

  • 分布式ID生成方案全解析:从数据库到雪花算法 Jun 25, 2026
  • Let's Encrypt 免费申请 SSL 证书,并实现自动续期 Sep 14, 2025
  • Redis ziplist、quicklist 和 listpack Mar 3, 2025
  • Nginx禁止使用IP直接访问服务器上相应端口 May 11, 2024
  • LeetCode刷题 - KMP算法 Feb 4, 2024

Categories

  • Linux7
  • 算法学习7
  • 论文笔记6
  • C++4
  • 未分类3
  • Go学习2
  • Redis1
  • SystemC1
  • Verilog1

Tags

← 启发式优化算法学习-PSO 多目标优化问题及两种常用解法 →

Related Posts

  • 算法学习-差分数组 Dec 23, 2023
  • LeetCode刷题-二叉树遍历迭代法 Oct 17, 2023
  • LeetCode刷题 - 滑动窗口最大值 Oct 17, 2023
  • 多目标优化问题及两种常用解法 Apr 30, 2023
皖ICP备2023003716号-1 | 公安备案皖公网安备34012202341113 | 违法和不良信息举报邮箱:1141751053@qq.com
Powered by Hugo & Explore Theme.