C#,数值计算——基于模拟退火的极小化问题单纯形(下山)算法的计算方法与C#源程序

news2024/10/7 4:37:04

1 模拟退火

模拟退火算法其实是一个类似于仿生学的算法,模仿的就是物理退火的过程。
我们炼钢的时候,如果我们急速冷凝,这时候的状态是不稳定的,原子间杂乱无章的排序,能量很高。而如果我们让钢水慢慢冷凝,很缓慢的降温,那么这个时候的状态就是很稳定的,各个分子都趋向于自己能量最低的位置。而模拟退火算法,恰恰就是利用了物理退火这一过程的原理,求解一个优化目标(目标函数)的最小值。

模拟退火算法来源于固体退火原理,是一种基于概率的算法,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。
 

2 模拟退火算法

模拟退火算法(Simulated Annealing,SA)最早由Metropolis等人于 1953 年提出。1983 年Kirkpatrick等人第一次使用模拟退火算法求解组合优化问题后,它就发表在了 Science 上。直到今天,它依然被广泛使用,这篇文章将详细介绍C#的代码实现。
 

3 单纯形法

单纯形法是针对求解线性规划问题的一个算法,这个名称里的'单纯形'是代数拓扑里的一个概念
实际问题当中变量x是多维的,约束条件也会比示例多的多,这就需要一个一劳永逸的算法能通过计算机来获得正解,单纯形法就是这样的一个算法。单纯形法最早由 George Dantzig于1947年提出,单纯形法对于求解线性规划问题是具有跨时代意义的,其实不仅仅是针对线性规划,对于非线性规划问题在求解的过程中也大量依赖单纯形法,George Dantzig本人也被称为'线性规划之父',他是好莱坞电影《心灵捕手》的原型。
 

4 C#源程序

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// 模拟退火下山单纯形极小化
    /// Downhill simplex minimization with simulated annealing
    /// </summary>
    public class Amebsa
    {
        public RealValueFun funk;

        public Ranq1 ran;
        private int mpts { get; set; }
        private int ndim { get; set; }
        private double[] pb { get; set; }
        private double[] y { get; set; }
        private double[,] p { get; set; }
        private double ftol { get; }
        private double yb { get; set; }
        private double tt { get; set; }

        public Amebsa(double[] point, double del, RealValueFun funkk, double ftoll)
        {
            this.funk = funkk;
            this.ran = new Ranq1(1234);
            this.ftol = ftoll;
            this.yb = double.MaxValue;
            this.ndim = point.Length;
            this.pb = new double[ndim];
            this.mpts = ndim + 1;
            this.y = new double[mpts];
            this.p = new double[mpts, ndim];
            for (int i = 0; i < mpts; i++)
            {
                for (int j = 0; j < ndim; j++)
                {
                    p[i, j] = point[j];
                }
                if (i != 0)
                {
                    p[i, i - 1] += del;
                }
            }
            inity();
        }

        public Amebsa(double[] point, double[] dels, RealValueFun funkk, double ftoll)
        {
            this.funk = funkk;
            this.ran = new Ranq1(1234);
            this.ftol = ftoll;
            this.yb = double.MaxValue;
            this.ndim = point.Length;
            this.pb = new double[ndim];
            this.mpts = ndim + 1;
            this.y = new double[mpts];
            this.p = new double[mpts, ndim];
            for (int i = 0; i < mpts; i++)
            {
                for (int j = 0; j < ndim; j++)
                {
                    p[i, j] = point[j];
                }
                if (i != 0)
                {
                    p[i, i - 1] += dels[i - 1];
                }
            }
            inity();
        }

        public Amebsa(double[,] pp, RealValueFun funkk, double ftoll)
        {
            this.funk = funkk;
            this.ran = new Ranq1(1234);
            this.ftol = ftoll;
            this.yb = double.MaxValue;
            this.ndim = pp.GetLength(1);
            this.pb = new double[ndim];
            this.mpts = pp.GetLength(0);
            this.y = new double[mpts];
            this.p = pp;

            inity();
        }

        public void inity()
        {
            double[] x = new double[ndim];
            for (int i = 0; i < mpts; i++)
            {
                for (int j = 0; j < ndim; j++)
                {
                    x[j] = p[i, j];
                }
                y[i] = funk.funk(x);
            }
        }

        public bool anneal(ref int iter, double temperature)
        {
            double[] psum = new double[ndim];
            tt = -temperature;
            get_psum(p, psum);
            for (; ; )
            {
                int ilo = 0;
                int ihi = 1;
                double ylo = y[0] + tt * Math.Log(ran.doub());
                double ynhi = ylo;
                double yhi = y[1] + tt * Math.Log(ran.doub());
                if (ylo > yhi)
                {
                    ihi = 0;
                    ilo = 1;
                    ynhi = yhi;
                    yhi = ylo;
                    ylo = ynhi;
                }
                for (int i = 3; i <= mpts; i++)
                {
                    double yt = y[i - 1] + tt * Math.Log(ran.doub());
                    if (yt <= ylo)
                    {
                        ilo = i - 1;
                        ylo = yt;
                    }
                    if (yt > yhi)
                    {
                        ynhi = yhi;
                        ihi = i - 1;
                        yhi = yt;
                    }
                    else if (yt > ynhi)
                    {
                        ynhi = yt;
                    }
                }
                double rtol = 2.0 * Math.Abs(yhi - ylo) / (Math.Abs(yhi) + Math.Abs(ylo));
                if (rtol < ftol || iter < 0)
                {
                    Globals.SWAP(ref y[0], ref y[ilo]);
                    for (int n = 0; n < ndim; n++)
                    {
                        Globals.SWAP(ref p[0, n], ref p[ilo, n]);
                    }
                    if (rtol < ftol)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                iter -= 2;
                double ytry = amotsa(p, y, psum, ihi, ref yhi, -1.0);
                if (ytry <= ylo)
                {
                    ytry = amotsa(p, y, psum, ihi, ref yhi, 2.0);
                }
                else if (ytry >= ynhi)
                {
                    double ysave = yhi;
                    ytry = amotsa(p, y, psum, ihi, ref yhi, 0.5);
                    if (ytry >= ysave)
                    {
                        for (int i = 0; i < mpts; i++)
                        {
                            if (i != ilo)
                            {
                                for (int j = 0; j < ndim; j++)
                                {
                                    psum[j] = 0.5 * (p[i, j] + p[ilo, j]);
                                    p[i, j] = psum[j];
                                }
                                y[i] = funk.funk(psum);
                            }
                        }
                        iter -= ndim;
                        get_psum(p, psum);
                    }
                }
                else
                {
                    ++iter;
                }
            }
        }

        public void get_psum(double[,] p, double[] psum)
        {
            for (int n = 0; n < ndim; n++)
            {
                double sum = 0.0;
                for (int m = 0; m < mpts; m++)
                {
                    sum += p[m, n];
                }
                psum[n] = sum;
            }
        }

        public double amotsa(double[,] p, double[] y, double[] psum, int ihi, ref double yhi, double fac)
        {
            double[] ptry = new double[ndim];
            double fac1 = (1.0 - fac) / ndim;
            double fac2 = fac1 - fac;
            for (int j = 0; j < ndim; j++)
            {
                ptry[j] = psum[j] * fac1 - p[ihi, j] * fac2;
            }
            double ytry = funk.funk(ptry);
            if (ytry <= yb)
            {
                for (int j = 0; j < ndim; j++)
                {
                    pb[j] = ptry[j];
                }
                yb = ytry;
            }
            double yflu = ytry - tt * Math.Log(ran.doub());
            if (yflu < yhi)
            {
                y[ihi] = ytry;
                yhi = yflu;
                for (int j = 0; j < ndim; j++)
                {
                    psum[j] += ptry[j] - p[ihi, j];
                    p[ihi, j] = ptry[j];
                }
            }
            return yflu;
        }
    }
}
 

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

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

相关文章

PowerDesigner使用实践

PowerDesigner使用实践 一、前言 1.简介 PowerDesigner DataArchitect 是业界领先的数据建模工具。 它提供了一种模型驱动的方法来增强业务和 IT 的能力并使其保持一致。 PowerDesigner 使企业能够更轻松地可视化、分析和操作元数据&#xff0c;以实现有效的企业信息架构。 …

通向架构师的道路之weblogic的集群与配置

一、Weblogic的集群 还记得我们在第五天教程中讲到的关于Tomcat的集群吗? 两个tomcat做node即tomcat1, tomcat2&#xff0c;使用Apache HttpServer做请求派发。 现在看看WebLogic的集群吧&#xff0c;其实也差不多。 区别在于&#xff1a; Tomcat的集群的实现为两个物理上…

Kotin协程的基础

协程是什么&#xff1f; 就是同步方式去编写异步执行的代码。协程是依赖于线程&#xff0c;但是协程挂起的时候不需要阻塞线程。几乎没有任何代价。 协程的创建 一个线程可以创建多个协程。协程的创建是通过CoroutineScope创建&#xff0c;协程的启动方式有三种。 runBlockin…

湘大oj1088 N!:求阶乘 数据太大怎么处理 常规的递归求阶乘

一、链接 N&#xff01; 二、题目 Description 请求N&#xff01;&#xff08;N<10000&#xff09;&#xff0c;输出结果对10007取余 输入 每行一个整数n&#xff0c;遇到-1结束。 输出 每行一个整数&#xff0c;为对应n的运算结果。 Sample Input 1 2 -1 Sample Outp…

【数据结构与算法】左叶子之和

左叶子之和 递归三部曲 确定递归函数的参数和返回值 int sumOfLeftLeaves(TreeNode* root)确定终止条件 遍历遇到空节点 if (root NULL) return 0;单层的递归逻辑 遍历顺序&#xff1a;左右中&#xff08;后序遍历&#xff09; 选择后序遍历的原因&#xff1a;要通过递归函…

【Linux操作系统】深入了解系统编程gdb调试工具

在软件开发过程中&#xff0c;调试是一个非常重要的步骤。无论是在开发新的软件还是维护现有的代码&#xff0c;调试都是解决问题的关键。对于Linux开发者来说&#xff0c;GDB是一个非常有用的调试工具。在本文中&#xff0c;我们将探讨Linux中使用GDB进行调试的方法和技巧。 …

C# OpenCvSharp 读取rtsp流

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Extensions; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using Syste…

HTTPS安全通信

HTTPS,TLS/SSL Hyper Text Transfer Protocol over Secure Socket Layer,安全的超文本传输协议,网景公式设计了SSL(Secure Sockets Layer)协议用于对Http协议传输的数据进行加密,保证会话过程中的安全性。 使用TCP端口默认为443 TLS:(Transport Layer Security,传输层…

30、Flink SQL之SQL 客户端(通过kafka和filesystem的例子介绍了配置文件使用-表、视图等)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

【移动机器人运动规划】03 —— 基于运动学、动力学约束的路径规划

文章目录 前言相关代码整理:相关文章&#xff1a; 介绍什么是kinodynamic&#xff1f;为什么需要kinodynamic&#xff1f;模型示例unicycle model&#xff08;独轮车模型&#xff09;differential model&#xff08;两轮差速模型&#xff09;Simplified car model (简化车辆模型…

YOLO相关原理(文件结构、视频检测等)

超参数进化(hyperparameter evolution) 超参数进化是一种使用了genetic algorithm&#xff08;GA&#xff09;遗传算法进行超参数优化的一种方法。 YOLOv5的文件结构 images文件夹内的文件和labels中的文件存在一一对应关系 激活函数&#xff1a;非线性处理单元 activation f…

WWW 23 | Facebook Marketplace的意图理解:用双塔模型处理结构化的产品目录

©PaperWeekly 原创 作者 | 何允中 单位 | Meta 研究方向 | Information Retrieval 摘要 本文介绍了 Facebook Marketplace 团队提出的 HierCat 构架&#xff0c;以解决电商搜索中的意图理解难题。HierCat 利用线上产品交互挖掘弱监督数据&#xff0c;并通过基于 Transfor…

sqlserver 数据库显示 正在还原

问题描述之前不太会搞差异备份的恢复&#xff0c;然后恢复发生了失败之后这个数据库一直处于(正在还原……状态 并且出现数据库无法访问的情况 尝试解决1执行查询Restore Database 数据库名称 with Recovery然后不太能行 2执行查询Restore Database 数据库名称 with NoRecovery…

10个最流行的免费3D模型下载网站

作为一名独立游戏开发者&#xff0c;自己创建图形、配乐、动画和更多东西是相当具有挑战性的。 创建资产所需的成本和时间有时是许多游戏开发商无法承受的。 这就是他们选择在互联网上搜索免费内容的原因。 现在&#xff0c;在浩瀚的内容海洋中获得如此免费的东西有点困难。 本…

uniapp 微信小程序 使用高德地图 定制气泡

前言 我们常说的uniapp或者原生微信小程序框架使用高德地图&#xff0c;并不是ui就是高德地图&#xff0c;而是api用的高德地图&#xff0c;ui仍然是框架内置的地图&#xff0c;也就是说&#xff0c;地图和api是分开&#xff0c;微信小程序的内置地图自然是腾讯地图。 高德地…

SpringBoot第34讲:SpringBoot集成ShardingJDBC - 基于JPA的DB隔离多租户方案

SpringBoot第34讲&#xff1a;SpringBoot集成ShardingJDBC - 基于JPA的DB隔离多租户方案 本文是SpringBoot第34讲&#xff0c;主要介绍ShardingJDBC的分片算法和分片策略&#xff0c;并在此基础上通过SpringBoot集成ShardingJDBC的几种策略&#xff08;标准分片策略&#xff0c…

DevOps最佳实践和工具在本地环境中的概述

引言 最近&#xff0c;我进行了一次网上搜索&#xff0c;以寻找DevOps的概述&#xff0c;尽管有大量的DevOps工具和实践&#xff0c;但我无法找到一个综合的概述。因此&#xff0c;我开始了对DevOps生态系统和最佳实践的梳理&#xff0c;以创建一个整体视图,方便后续研究实践 C…

Fabric系列 - 知识点整理

知识点 源码编译 主机编译 容器编译 手动部署(docker-compose) 单peer 多peer 中途加peer 多主机多peer 链码 语法, 接口 (go版) 命令行调用 ca server 在DApp中使用SDK调用 (js版) 部署的几个阶段 部署1排序和1节点, 1组织1通道 光部署能Dapp 带ca server (每个组织一个)…

SQL SERVER 2019 数据库还原测试库的方法

1、备份正式库数据 2、在其它电脑上还原备份的数据库 不需要覆盖其它数据库&#xff0c;直接还原出数据库 还原时修改文件名和数据库名称&#xff1a; 修改文件名称 还原成功

【数学建模】--时间序列分析

时间序列分析概念与时间序列分解模型 定义&#xff1a;时间序列也称动态序列&#xff0c;是指将某种现象的指标数值按照时间顺序排列而成的数值序列。时间序列分析大致可分成三大部分&#xff0c;分别是描述过去&#xff0c;分线规律和预测未来&#xff0c;本讲将主要介绍时间序…