C#,动态规划(DP)模拟退火(Simulated Annealing)算法与源代码

1 模拟退火

*问题:**给定一个成本函数f:r^n–>r*,找到一个 n 元组,该元组最小化 f 的值。请注意,最小化函数值在算法上等同于最大化(因为我们可以将成本函数重新定义为 1-f)。 很多有微积分/分析背景的人可能都熟悉单变量函数的简单优化。例如,函数 f(x) = x^2 + 2x 可以通过将一阶导数设置为零来优化,从而获得产生最小值 f(-1) = -1 的解 x = -1 。这种技术适用于变量很少的简单函数。然而,通常情况下,研究人员对优化几个变量的函数感兴趣,在这种情况下,只能通过计算获得解。

一个困难的优化任务的极好例子是芯片平面规划问题。假设你在英特尔工作,你的任务是设计集成电路的布局。您有一组不同形状/大小的模块,以及可以放置模块的固定区域。你想要达到的目标有很多:最大化导线连接元件的能力,最小化净面积,最小化芯片成本,等等。考虑到这些,您创建了一个成本函数,取所有,比如说, 1000 个变量配置,并返回一个代表输入配置“成本”的实数值。我们称之为目标函数,因为目标是最小化它的值。 一个简单的算法是完全的空间搜索——我们搜索所有可能的配置,直到找到最小值。这对于变量很少的函数来说可能就足够了,但是我们想到的问题需要这样一个强力算法来玩 *O(n!)*。

由于这类问题和其他 NP 难问题的计算困难,许多优化试探法已经被开发出来,试图产生一个好的,尽管可能是次优的值。在我们的例子中,我们不一定需要找到一个严格的最优值——找到一个接近最优的值将满足我们的目标。一种广泛使用的技术是模拟退火,通过它我们引入了一定程度的随机性,有可能从一个更好的解转移到一个更差的解,试图逃离局部极小值并收敛到一个更接近全局最优的值。

模拟退火是基于冶金实践,通过这种实践,材料被加热到高温并冷却。在高温下,原子可能会不可预测地移动,通常会随着材料冷却成纯晶体而消除杂质。这是通过模拟退火优化算法复制的,能量状态对应于当前解。 在这个算法中,我们定义了一个初始温度和一个最低温度,初始温度通常设置为 1,最低温度的数量级为 10^-4.当前温度乘以某个分数α,然后降低,直到达到最低温度。对于每个不同的温度值,我们运行核心优化例程的次数是固定的。优化程序包括找到一个相邻解并以概率e^(f(c–f(n)】接受它,其中 c 是当前解而 n 是相邻解。通过对当前解施加微小的扰动来找到相邻解。这种随机性有助于避开优化启发式算法的常见陷阱——陷入局部极小值。通过潜在地接受一个比我们目前拥有的更差的最优解,并以与成本增加相反的概率接受它,算法更有可能收敛到全局最优。设计一个邻居函数是相当棘手的,必须在个案的基础上完成,但以下是在位置优化问题中寻找邻居的一些想法。

  • 在随机方向上将所有点移动 0 或 1 个单位
  • 随机移动输入元素
  • 交换输入序列中的随机元素
  • 置换输入序列
  • 将输入序列分成随机数量的段和置换段

一个警告是,我们需要提供一个初始解决方案,以便算法知道从哪里开始。这可以通过两种方式来实现:(1)使用关于问题的先验知识来输入良好的起点,以及(2)生成随机解。尽管生成随机解更糟糕,有时会抑制算法的成功,但对于我们对环境一无所知的问题,这是唯一的选择。

还有许多其他优化技术,尽管模拟退火是一种有用的随机优化启发式方法,适用于大型离散搜索空间,在这些空间中,随着时间的推移,最优性是优先的。下面,我包含了一个基于位置的模拟退火的基本框架(可能是模拟退火最适用的优化风格)。当然,成本函数、候选生成函数和邻居函数必须根据手头的具体问题来定义,尽管核心优化例程已经实现。

2 源程序(文本格式)

using System;
using System.Text;

namespace Legalsoft.Truffer.Algorithm
{
    /// <summary>
    /// 算法核心数据类
    /// 含:方差系数均方根误差,配置参数(数组)
    /// </summary>
    public class Anneal_Solution
    {
        /// <summary>
        /// 方差系数均方根误差
        /// Coefficient of Variance Root Mean Squared Error
        /// 默认初值0.0;不超过1.0;
        /// </summary>
        public double CVRMSE { get; set; } = 0.0;
        /// <summary>
        /// 配置参数(数组)
        /// 整型数组;无初值(null);
        /// </summary>
        public int[] Config { get; set; } = null;
        /// <summary>
        /// (无参)默认构造函数
        /// </summary>
        public Anneal_Solution()
        {
        }
        /// <summary>
        /// (有参)构造函数
        /// </summary>
        /// <param name="CVRMSE">方差系数均方根误差</param>
        /// <param name="configuration">配置参数(数组)</param>
        public Anneal_Solution(double CVRMSE, int[] configuration)
        {
            this.CVRMSE = CVRMSE;
            Config = configuration;
        }
    }

    /// <summary>
    /// 模拟退火算法
    /// </summary>
    public class Simulated_Annealing
    {
        private static Random rand { get; set; } = new Random((int)DateTime.Now.Ticks);

        public static string Solve(int M = 15, int N = 15, double T_Minium = 0.0001, double Alpha = 0.9, int Maxium_Iterations = 100)
        {
            string[,] sourceArray = new string[M, N];
            Anneal_Solution min = new Anneal_Solution(double.MaxValue, null);
            Anneal_Solution currentSol = Rand_Solution(M);

            double temperature = 1.0;
            while (temperature > T_Minium)
            {
                for (int i = 0; i < Maxium_Iterations; i++)
                {
                    if (currentSol.CVRMSE < min.CVRMSE)
                    {
                        min = currentSol;
                    }

                    Anneal_Solution newSol = Neighbor(currentSol);
                    double ap = Math.Pow(Math.E, (currentSol.CVRMSE - newSol.CVRMSE) / temperature);
                    if (ap > rand.NextDouble())
                    {
                        currentSol = newSol;
                    }
                }
                temperature *= Alpha;
            }
            #endregion

            for (int i = 0; i < sourceArray.GetLength(0); i++)
            {
                for (int j = 0; j < sourceArray.GetLength(1); j++)
                {
                    sourceArray[i, j] = "X";
                }
            }

            foreach (int k in min.Config)
            {
                int[] coord = Index_To_Points(M, N, k);
                sourceArray[coord[0], coord[1]] = "-";
            }

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < sourceArray.GetLength(0); i++)
            {
                for (int j = 0; j < sourceArray.GetLength(1); j++)
                {
                    sb.Append(sourceArray[i, j] + ", ");
                }
                sb.AppendLine("<br>");
            }
            return sb.ToString();
        }

        public static Anneal_Solution Neighbor(Anneal_Solution currentSol)
        {
            return currentSol;
        }

        public static Anneal_Solution Rand_Solution(int n)
        {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
            {
                a[i] = i + 1;
            }
            return new Anneal_Solution(-1, a);
        }

        public static double Cost(int[] inputConfiguration)
        {
            return -1;
        }

        public static int[] Index_To_Points(int M, int N, int index)
        {
            int[] points = { index % M, index / M };
            return points;
        }
    }
}
 

3 代码格式

using System;
using System.Text;namespace Legalsoft.Truffer.Algorithm
{/// <summary>/// 算法核心数据类/// 含:方差系数均方根误差,配置参数(数组)/// </summary>public class Anneal_Solution{/// <summary>/// 方差系数均方根误差/// Coefficient of Variance Root Mean Squared Error/// 默认初值0.0;不超过1.0;/// </summary>public double CVRMSE { get; set; } = 0.0;/// <summary>/// 配置参数(数组)/// 整型数组;无初值(null);/// </summary>public int[] Config { get; set; } = null;/// <summary>/// (无参)默认构造函数/// </summary>public Anneal_Solution(){}/// <summary>/// (有参)构造函数/// </summary>/// <param name="CVRMSE">方差系数均方根误差</param>/// <param name="configuration">配置参数(数组)</param>public Anneal_Solution(double CVRMSE, int[] configuration){this.CVRMSE = CVRMSE;Config = configuration;}}/// <summary>/// 模拟退火算法/// </summary>public class Simulated_Annealing{private static Random rand { get; set; } = new Random((int)DateTime.Now.Ticks);public static string Solve(int M = 15, int N = 15, double T_Minium = 0.0001, double Alpha = 0.9, int Maxium_Iterations = 100){string[,] sourceArray = new string[M, N];Anneal_Solution min = new Anneal_Solution(double.MaxValue, null);Anneal_Solution currentSol = Rand_Solution(M);double temperature = 1.0;while (temperature > T_Minium){for (int i = 0; i < Maxium_Iterations; i++){if (currentSol.CVRMSE < min.CVRMSE){min = currentSol;}Anneal_Solution newSol = Neighbor(currentSol);double ap = Math.Pow(Math.E, (currentSol.CVRMSE - newSol.CVRMSE) / temperature);if (ap > rand.NextDouble()){currentSol = newSol;}}temperature *= Alpha;}#endregionfor (int i = 0; i < sourceArray.GetLength(0); i++){for (int j = 0; j < sourceArray.GetLength(1); j++){sourceArray[i, j] = "X";}}foreach (int k in min.Config){int[] coord = Index_To_Points(M, N, k);sourceArray[coord[0], coord[1]] = "-";}StringBuilder sb = new StringBuilder();for (int i = 0; i < sourceArray.GetLength(0); i++){for (int j = 0; j < sourceArray.GetLength(1); j++){sb.Append(sourceArray[i, j] + ", ");}sb.AppendLine("<br>");}return sb.ToString();}public static Anneal_Solution Neighbor(Anneal_Solution currentSol){return currentSol;}public static Anneal_Solution Rand_Solution(int n){int[] a = new int[n];for (int i = 0; i < n; i++){a[i] = i + 1;}return new Anneal_Solution(-1, a);}public static double Cost(int[] inputConfiguration){return -1;}public static int[] Index_To_Points(int M, int N, int index){int[] points = { index % M, index / M };return points;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2808692.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习手写字符识别:推理过程

说明 本篇博客主要是跟着B站中国计量大学杨老师的视频实战深度学习手写字符识别。 第一个深度学习实例手写字符识别 深度学习环境配置 可以参考下篇博客&#xff0c;网上也有很多教程&#xff0c;很容易搭建好深度学习的环境。 Windows11搭建GPU版本PyTorch环境详细过程 数…

万字长文带你由浅入深夯实ARM汇编基础——汇编指令及寻址方式最全梳理(附示例)!

《嵌入式工程师自我修养/C语言》系列——由浅入深夯实ARM汇编基础&#xff0c;汇编指令及寻址方式梳理&#xff08;附示例&#xff09;&#xff01; 一、引言二、ARM汇编语言2.1 ARM汇编的特点2.2 ARM指令集格式标准2.2.1 机器指令格式2.2.2 汇编指令格式 三、ARM寻址方式3.1 立…

如何做到三天内完成智能直流伺服电机系统开发?

适应EtherCAT/CANopen协议三相伺服电机直流伺服电机直线伺服音圈电机 如何开发高性能直流伺服电机驱动控制器&#xff1f; 需要熟悉高性能单片机&#xff08;至少是ARM或DSP水平的&#xff09;&#xff0c;需要掌握空间磁场矢量控制FOC&#xff0c;需要掌握运动轨迹算法……此…

谁是单身狗?——C语言刷题

创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 单身狗1 题述 在一个整型数组中&#xff0c;只有一个数字出现一次&#xff0c;其他数组都是成对出现的&#xff0c;请找出那个只出现一次的数字。 例如&#xff1a; 数组中有&#xff1a;1 2 3 4 5 1 2 3 4&a…

FairyGUI × Cocos Creator 3.7.3 引入报错解决

Cocos Creator 3.7.3引入fgui库 package.json添加这个依赖 "devDependencies": {"fairygui-cc": "latest"}执行npm i 报错解决 使用import引入fairygui-cc&#xff0c;就会有报错和警告&#xff0c;简单处理一下。 鼠标随便点一下也会出警告…

2024“薪”风口、学习鸿蒙开发就业钱景如何?

随着华为的鸿蒙系统从诞生之初就备受关注&#xff0c;对于那些对鸿蒙开发感兴趣并希望在这一领域寻找职业发展的人来说&#xff0c;这是一个非常重要的问题。 那么&#xff0c;2024年学鸿蒙开发的就业前景如何呢&#xff1f; 一、彻底摆脱“安卓套壳”&#xff01; HarmonyO…

天拓四方:工业智能网关如何助力企业实现智能制造升级

工业智能网关是一种具备数据处理、通信转换和智能控制功能的硬件设备。它能够采集来自不同传感器和执行器的数据&#xff0c;通过标准化协议将数据上传到云端或本地服务器进行分析处理&#xff0c;并实现对设备的远程监控和控制。同时&#xff0c;工业智能网关还具备强大的数据…

靡语IT:JavaScript数组

目录 1.数组&#xff1a;Array 2.Array.length 3.数组的声明(创建)方法 4.数组去重 5.数组遍历 6.类数组对象 1.数组&#xff1a;Array 数组对象的作用是&#xff1a;使用单独的变量名来存储一系列的值。 参数 参数 size 是期望的数组元素个数。返回的数组&#xff0…

抖音视频提取软件怎么用|抖音数据抓取工具

针对用户获取抖音视频的需求&#xff0c;我们开发了一款功能强大的抖音视频提取软件&#xff0c;旨在帮助用户轻松获取他们感兴趣的视频内容。无需逐个复制链接&#xff0c;无需繁琐的下载步骤&#xff0c;我们的软件让抖音视频获取变得简单快捷。 使用我们的软件非常简单&…

深入探究Nginx的使用方法

目录 引言 一、网络状态页 二、Nginx 第三方模块 三、变量 &#xff08;一&#xff09;内置变量 &#xff08;二&#xff09;自定义变量 四、自定义日志 &#xff08;一&#xff09;有关日志的配置信息 &#xff08;二&#xff09;error日志的设置 1.日志的等级 2.自…

Python循环结构你学会了吗?

1.while 循环 需求&#xff1a;输出 10 遍的 今天天气不错 python 中的循环分为 while 循环和 for 循环 """ while 循环的基础语法&#xff1a; 1.初始化的表达式 while 2.条件表达式循环体&#xff08;重复执行的程序&#xff09;3.更新条件执行流程&#x…

我是如何深入学习理解Linux权限的,答案就在这里。

目录 1. shell命令以及运行原理2. Linux权限的概念3.Linux权限管理01.文件访问者的分类&#xff08;三种人&#xff09;02.文件类型和访问权限&#xff08;事物属性&#xff09;(1)文件类型 03.文件权限值的表示方法a)字符表示方法&#xff08;三三为一组&#xff09;b)8进制数…

市场复盘总结 20240223

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 57% 最常用的…

python 运算符总结

什么是运算符 什么是运算符? 先看如下示例 549 例子中&#xff0c;4 和 5 被称为操作数&#xff0c; 称为运算符。 而Python 语言支持以下类型的运算符: 算术运算符比较&#xff08;关系&#xff09;运算符赋值运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级 …

JavaAPI常用类01

目录 概述 Object类 Object类_toString() 代码展示 重写toString()方法前后输出 Object类_equals() 代码展示 重写equals()方法前后输出对比 Arrays类 equals()方法 Binary Search&#xff08;二分查找&#xff09; copyOf()方法 sort()方法 了解sort()方法 进阶…

从ChatGPT到Sora,来了解大模型训练中的存储

1 从chatGPT到Sora 2022年底&#xff0c;OpenAI推出人工智能聊天机器人ChatGPT&#xff0c;开启了大模型领域的“竞速跑”模式。2024年2月15日&#xff0c;随着视频生成模型Sora的横空出世&#xff0c;OpenAI再度掀起热潮。 Sora将视频生成内容拉到了一个全新的高度&#xff0c…

01|Mysql底层存储引擎

1. 聚集索引&#xff08;聚簇&#xff09;与非聚集索引 1.1 聚集索引 索引和数据存储在一起。叶子节点存储了完整的数据记录&#xff1b; 1.2 非聚集索引 MyISAM存储引擎就是非聚集索引&#xff0c;索引和数据文件是分开存储的。索引在MYI文件中&#xff0c;数据在MYD文件中…

YOLO系列论文阅读(v1--v3)

搞目标检测&#xff0c;绕不开的一个框架就是yolo&#xff0c;而且更糟糕的是&#xff0c;随着yolo的发展迭代&#xff0c;yolo网络可以做的事越来越多&#xff0c;语义分割&#xff0c;关键点检测&#xff0c;3D目标检测。。。这几天决定把YOLO系列彻底梳理一下&#xff0c;在…

Linux——缓冲区封装系统文件操作

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、FILE二、封装系统接口实现文件操作1、text.c2、mystdio.c3、mystdio.h 一、FILE 因为IO相…

机器学习打分函数在分子对接中的应用系列-GB_Score

欢迎浏览我的CSND博客&#xff01; Blockbuater_drug …点击进入 文章目录 前言一、GB-Score是什么&#xff1f;二、文献复现 -训练和验证环境1. GB score验证虚拟环境的配置2. Usage1- Preparing ligand and protein file2- Generating features3 - Repeat and extend current…