模拟退火算法在Matlab中的两个应用案例及代码

embedded/2025/1/13 12:28:09/

 

案例一:求解函数最小值

 

目标函数为f(x)=x^4-2x^2+3,求该函数在区间[-2,2]上的最小值。

 

function [x,fval] = simulated_annealing(fun,x0,options)

    % 设置默认选项

    default_options = struct('T0',100,'alpha',0.95,'T_min',1e-8,'max_iter',1000,'verbose',false);

    if nargin < 3

        options = default_options;

    else

        options = merge_options(default_options,options);

    end

    % 初始化参数

    T = options.T0;

    x = x0;

    fval = feval(fun,x);

    iter = 0;

    best_x = x;

    best_fval = fval;

    % 开始迭代

    while T > options.T_min && iter < options.max_iter

        % 产生新解

        new_x = x + randn*0.5;

        new_x = max(min(new_x,2),-2);

        new_fval = feval(fun,new_x);

        delta_f = new_fval - fval;

        % 接受新解

        if delta_f < 0 || exp(-delta_f/T) > rand()

            x = new_x;

            fval = new_fval;

            if fval < best_fval

                best_x = x;

                best_fval = fval;

            end

        end

        % 降温

        T = options.alpha * T;

        % 更新迭代计数器

        iter = iter + 1;

    end

    x = best_x;

    fval = best_fval;

end

 

function opt = merge_options(default_opt,opt)

    if isempty(opt)

        opt = default_opt;

    else

        fields = fieldnames(default_opt);

        for i = 1:length(fields)

            if ~isfield(opt,fields{i})

                opt.(fields{i}) = default_opt.(fields{i});

            end

        end

    end

end

 

fun = @(x) x^4 - 2*x^2 + 3;

x0 = 1;

options = struct('T0',100,'alpha',0.95,'T_min',1e-8,'max_iter',1000,'verbose',true);

[x,fval] = simulated_annealing(fun,x0,options);

 

 

案例二:旅行商问题(TSP)

 

假设有10个城市,坐标分别为(x,y),计算出一条最短的旅行路线。

 

% 城市坐标

city_coords = [

    1 2;

    3 4;

    5 6;

    7 8;

    9 10;

    11 12;

    13 14;

    15 16;

    17 18;

    19 20

];

n = size(city_coords, 1);

% 计算距离矩阵

distance_matrix = zeros(n);

for i = 1:n

    for j = 1:n

        distance_matrix(i, j) = norm(city_coords(i, :) - city_coords(j, :));

    end

end

% 模拟退火算法参数

T0 = 100;

alpha = 0.95;

T_min = 1e-8;

max_iter = 1000;

% 初始化路径

current_path = randperm(n);

current_distance = calculate_distance(current_path, distance_matrix);

best_path = current_path;

best_distance = current_distance;

T = T0;

for iter = 1:max_iter

    % 产生新路径

    new_path = generate_new_path(current_path);

    new_distance = calculate_distance(new_path, distance_matrix);

    delta_distance = new_distance - current_distance;

    % 接受新路径

    if delta_distance < 0 || exp(-delta_distance/T) > rand()

        current_path = new_path;

        current_distance = new_distance;

        if current_distance < best_distance

            best_path = current_path;

            best_distance = current_distance;

        end

    end

    % 降温

    T = alpha * T;

end

function distance = calculate_distance(path, distance_matrix)

    n = length(path);

    distance = 0;

    for i = 1:(n - 1)

        distance = distance + distance_matrix(path(i), path(i + 1));

    end

    distance = distance + distance_matrix(path(n), path(1));

end

function new_path = generate_new_path(current_path)

    n = length(current_path);

    i = randi([1, n]);

    j = randi([1, n]);

    while i == j

        j = randi([1, n]);

    end

    new_path = current_path;

    new_path(i) = current_path(j);

    new_path(j) = current_path(i);

end

 

 

上述代码,第一个案例中的函数 simulated_annealing 实现了模拟退火算法,用于求解函数的最小值,案例二中定义了城市坐标和距离矩阵,并实现了计算路径距离的函数 calculate_distance 和产生新路径的函数 generate_new_path ,最终得到最优旅行路线。


http://www.ppmy.cn/embedded/153562.html

相关文章

常用的排序算法(Java版)

文章目录 前言一、选择排序二、插入排序三、冒泡排序四、快速排序五、归并排序六、希尔排序七、堆排序总结 前言 排序算法有很多&#xff0c;这里列出最常用的一些&#xff0c;如选择排序、插入、冒泡等。 稳定性&#xff1a;待排序数据中有相同的数&#xff0c;排序之后相同…

“迎新系统”与“智慧”的融合:构建高效、便捷的新生入学体验

于当今之社会&#xff0c;“智慧教育”业已成为助推教育现代化之重要趋向。在此种背景之下&#xff0c;“迎新系统”身为高校迎新工作之核心环节&#xff0c;其智能化水准径直影响着新生之入学体验以及校园管理之效能。传统意义上的迎新工作&#xff0c;通常牵涉大量的信息收集…

【优选算法篇】:深入浅出位运算--性能优化的利器

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;优选算法篇–CSDN博客 文章目录 一.位运算一.位运算概述二.常见的位运算操作符三.常见的位运…

3. 使用springboot做一个音乐播放器软件项目【封装项目使用的工具类】

上一章文章 我们做了 音乐播放器这个项目的 框架搭建和一些基础配置文件。 参考网址&#xff1a; https://blog.csdn.net/Drug_/article/details/145044096 这篇文章我们来分享一些 项目中用到的一些工具类。 一般项目里 我会创建一个 utils 文件夹 来存放 项目中常用的工具类…

Rust 生命周期

Rust 生命周期 引言 Rust 是一种系统编程语言,以其内存安全、并发性和高性能而闻名。在 Rust 中,生命周期是一个核心概念,用于确保引用的有效性,从而防止内存安全问题。本文将深入探讨 Rust 的生命周期,包括其工作原理、使用场景以及最佳实践。 生命周期基础 什么是生…

UnityDots学习(三)

此篇记录Dots使用的步骤。 Demo逻辑是在场景内创建2000个物体。1000个是搜索&#xff0c;1000是被搜索的目标。 每个物体都随机朝某个方向移动。 在Update里。1000个搜索者会对1000被搜索的目标进行遍历查找到哪个目标离他最近&#xff0c;并且画出连线。 逻辑如下&#xf…

《分布式光纤测温:解锁楼宇安全的 “高精度密码”》

在楼宇建筑中&#xff0c;因其内部空间庞大&#xff0c;各类电器设施众多&#xff0c;如何以一种既高效又稳定&#xff0c;兼具低成本与高覆盖特性的方式&#xff0c;为那些关键线路节点开展温度监测&#xff0c;是目前在安全监测领域一项重点研究项目&#xff0c;而无锡布里渊…

QT 端口扫描附加功能实现 端口扫描5

上篇QT 下拉菜单设置参数 起始端口/结束端口/线程数量 端口扫描4-CSDN博客 在扫描结束后设置Scan按钮为可用&#xff0c;并提示扫描完成 在 MainWindow 类中添加一个成员变量来跟踪正在进行的扫描任务数量&#xff1a; 在 MainWindow 的构造函数中初始化 activeScanTasks&…