当前位置: 首页 > news >正文

一文搞懂:0-1整数规划与蒙特卡罗模拟(附MATLAB代码详解)

前言:欢迎各位光临本博客,这里小编带你直接手撕Make/Makefile (自动化构建),文章并不复杂,愿诸君耐其心性,忘却杂尘,道有所长!!!!

解释_chmod_命令_(3).gif

**🔥个人主页:IF’Maxue-CSDN博客

🎬作者简介:C++研发方向学习者

📖**个人专栏:
《C语言》
《C++深度学习》
《Linux》
《数据结构》
《数学建模》
**

⭐️人生格言:生活是默默的坚持,毅力是永久的享受。不破不立,远方请直行!

文章目录

    • 一、0-1整数规划:直接用intlinprog函数搞定
    • 二、蒙特卡罗模拟:本质是“暴力随机试”
      • 例题一:0-1变量约束求“最小和”
        • 1. 问题背景
        • 2. 代码解析
          • (1)定义部分:初始化参数
          • (2)核心循环:随机试,找最优
      • 例题四:工厂设备分配求“最优成本”
        • 1. 问题背景
        • 2. 代码解析
          • (1)定义部分:初始化数据
          • (2)核心循环:随机分配,查约束,算成本
      • 例题二:蒲丰投针实验——用随机算π
        • 1. 问题背景
        • 2. 代码解析
          • (1)定义部分:初始化实验参数
          • (2)核心循环:抛针、计数、绘图
          • (3)计算π值
      • 五、张麻子例题三:蒙特卡罗解决特定场景问题
    • 总结:蒙特卡罗的核心逻辑

一、0-1整数规划:直接用intlinprog函数搞定

先从简单的开始——0-1整数规划,就是问题里的变量只能取0或1(比如“选不选某个方案”“用不用某个资源”)。这类问题不用自己写复杂算法,直接调用MATLAB的intlinprog函数就行,具体用法看下面这张图:

image.png

函数里只需按要求填“目标函数系数”“约束条件”等参数,就能自动算出最优解,适合快速解决0-1变量的规划问题。

二、蒙特卡罗模拟:本质是“暴力随机试”

如果问题复杂,或者不想纠结公式,蒙特卡罗方法就是个好选择——核心思路是“大量随机模拟,从结果里找最优”,比如想找最省钱的方案,就随机试1万次,挑花钱最少的那次。下面用3个例题讲透怎么用代码实现。

例题一:0-1变量约束求“最小和”

1. 问题背景

假设有6个变量(只能是0或1),要满足几个约束条件(比如“变量1+2+3至少为1”“变量4+6至少为1”等),最终要找这6个变量的和最小的解(相当于“用最少的变量满足约束”)。

2. 代码解析

代码分“定义部分”和“核心循环”,咱们逐行拆:

(1)定义部分:初始化参数
clear;clc;%清屏(清空工作区和命令行,避免之前的代码干扰)
n = 10000; %模拟次数(“蒙”1万次,次数越多越可能找到最优解)
res_min = +Inf;%最小值初始化(先设成“无穷大”,这样后面遇到更小的数才能更新)
res_x = 0;%存最优解(最后要输出的那组0-1变量)

这里重点说res_min = +Inf:就像你要找“班里最矮的人”,先假设“最矮是10米”,再逐个比,比10米矮就更新——用“无穷大”初始化,能确保第一次找到满足条件的解时,一定能更新它。

(2)核心循环:随机试,找最优
for i = 1 : n  %循环1万次,每次模拟一组解%生成6个0或1(像掷6次硬币,正面1、反面0)x = randi([0,1],6,1); %判断是否满足约束条件(括号里是题目给的所有约束,必须都满足才往下算)if((x(1) + x(2) + x(3) >=1) & (x(4) + x(6) >=1) & (x(3) + x(5) >= 1) & (x(2) + x(4) >= 1) & (x(1) >= 1) & (x(2) + x(4) + x(6) >= 1))sum_x = sum(x);%算当前这组解的变量和(比如x是[1,0,0,1,0,0],sum_x就是2)%如果当前和比之前的“最小和”还小,就更新最优解if(sum_x < res_min)res_x = x;%存下这组更好的解res_min = sum_x;%更新最小和endend
end

简单说:每次随机造6个0/1,检查是否符合所有要求,符合就算“变量和”,如果这个和比之前的最小值还小,就记下来——1万次试完,最后记下来的就是大概率最优的解。

例题四:工厂设备分配求“最优成本”

1. 问题背景

有6台设备要分给4个企业(每个企业至少分到1台设备),已知“第j台设备分给第i个企业”的成本(存在C这个成本矩阵里),要找“总成本最大”的分配方案(从代码里sum > res能看出来是求最大成本)。

2. 代码解析
(1)定义部分:初始化数据
clear;clc;%清屏
n = 10000; %模拟1万次
%成本矩阵C:C(j,i)表示“第j台设备分给第i个企业”的成本(共6台设备、4个企业)
C = [4,2,3,4;6,4,5,5;7,6,7,6;7,8,8,6;7,9,8,6;7,10,8,6];
res_x = 0;%存最优分配方案(比如[1,2,3,4,1,2]表示设备1分企业1、设备2分企业2...)
res = 0;%存最优成本(最后要输出的最大成本)
(2)核心循环:随机分配,查约束,算成本
for k = 1:n  %循环1万次flag = 1;%标记是否满足“每个企业至少1台”(1=满足,0=不满足)%生成分配方案:1行6列,每个数是1-4(表示设备分给1-4号企业)x = randi([1,4],1,6); %检查每个企业是否都分到设备(遍历4个企业)for j = 1 : 4 %ismember(j,x):判断j号企业是否在分配方案x里(在=1,不在=0)if(ismember(j,x) == 0)flag = 0;%有企业没分到设备,标记为不满足break;%不用再查了,跳出循环endend%如果满足“每个企业至少1台”,就计算总成本if(flag == 1)sum = 0;%当前方案的总成本%遍历6台设备,累加每台设备的成本for j = 1 : 6sum = sum + C(j, x(j));%C(j,x(j))=第j台设备分给x(j)号企业的成本end%如果当前总成本比之前的最优成本大,就更新if(sum > res)res = sum;%更新最优成本res_x = x;%更新最优分配方案endend
end

举个例子:如果x = [1,1,2,3,4,4],就会检查“1、2、3、4号企业都在x里吗?”——在,就计算成本:设备1分企业1(成本4)+设备2分企业1(成本2)+…+设备6分企业4(成本6),最后看这个总和是不是比之前的最大成本还大,是就记下来。

例题二:蒲丰投针实验——用随机算π

1. 问题背景

这是个经典实验:在画满平行线的纸上随机投针,通过“针与线相交的概率”反推出π的值。核心原理是:相交概率P = 2L/(aπ)(L是针长,a是平行线间距),所以π = 2L/(Pa)。

2. 代码解析
(1)定义部分:初始化实验参数
clear;clc;
a = 10;%平行线之间的间距(比如10cm)
L = 5;%针的长度(比如5cm,要小于a才合理)
n = 10000; %抛针次数(抛1万次,次数越多算的π越准)%生成随机参数
ph = rand(n,1) * pi;%随机角度(0到π,因为针旋转对称,超过π重复)
x = rand(n,1) * a/2;%针的中点到最近一条平行线的距离(0到a/2,再远就有更近的线)
m = 0; %记录针与线相交的次数
y = (L/2) * sin(ph); %相交的“临界距离”(针刚好碰到线时,x的最大值)%绘图设置:坐标轴范围(x轴角度0-π,y轴距离0-a/2),显示边框
axis([0,pi, 0,a/2]); 
box on; 

这里的y = (L/2)sin(ph)很关键:想象针绕中点转,当针与线的夹角是ph时,针的一半长度在垂直方向的投影是(L/2)sin(ph)——如果针中点到线的距离x小于这个投影,针就会和线相交(比如你把筷子斜着放,离桌边太近就会掉下去)。

(2)核心循环:抛针、计数、绘图
for i = 1 : n%判断是否相交:x(i)(中点距离)<= y(i)(临界距离)→ 相交if(x(i) <= y(i))m = m + 1;%相交次数加1plot(ph(i),x(i),'b.');%在图上画一个蓝色小点(记录这次相交的位置)hold on;%保持图形,后续点叠加画end
end
(3)计算π值
P = m/n;%相交概率(相交次数/总抛针次数)
mypi = 2*L/(P*a)%用公式反推π(代入L=5、a=10、P的值)

实验结果的可视化如图所示(蓝色小点就是相交的投针位置):

image.png

比如抛1万次,相交3180次,P=0.318,代入公式得mypi = 2*5/(0.318*10)≈3.14,和真实π值很接近。

五、张麻子例题三:蒙特卡罗解决特定场景问题

除了上面的通用场景,蒙特卡罗还能解决具体业务问题,比如张麻子例题的场景(如图所示):

image.png

这类问题的核心思路和前面一致:先明确“变量范围”(比如某个参数的取值区间)、“约束条件”(比如业务上的限制)、“目标函数”(比如求利润最大/成本最小),然后用代码做“大量随机模拟”,从结果里挑最优——本质还是“暴力试,但试得足够多,就接近最优解”。

总结:蒙特卡罗的核心逻辑

不管是0-1规划、设备分配还是算π,蒙特卡罗的本质就3步:

  1. 定规则:明确“变量能取什么值”“要满足什么约束”“要优化什么目标(最大/最小)”;
  2. 随机试:用randi/rand生成大量随机解,逐个检查是否满足约束;
  3. 找最优:从满足约束的解里,挑出目标函数最优的那个。

优点是简单好懂,不用推导复杂公式;缺点是需要足够多的模拟次数(次数越多越准)——适合解决公式难推、但能快速验证解是否有效的问题。


文章转载自:

http://XbtA8kIw.dgknL.cn
http://Vj51lJV6.dgknL.cn
http://2frfzIc0.dgknL.cn
http://bYMFIftO.dgknL.cn
http://8RkbmUsN.dgknL.cn
http://fP7fMrgW.dgknL.cn
http://PlzzlLzH.dgknL.cn
http://6HUnxWnQ.dgknL.cn
http://G9NGrAOU.dgknL.cn
http://72GDSTQ2.dgknL.cn
http://6e7dCZ05.dgknL.cn
http://UJLBi8Lx.dgknL.cn
http://nxQPfZci.dgknL.cn
http://DyDWfKc8.dgknL.cn
http://MfTuJRv4.dgknL.cn
http://BjEHwbMc.dgknL.cn
http://LHGk9jYw.dgknL.cn
http://cVprn2Qu.dgknL.cn
http://VpMrwGZc.dgknL.cn
http://Ih3TGjqS.dgknL.cn
http://2thf1cmV.dgknL.cn
http://kJsxg6zv.dgknL.cn
http://0bvCwvZp.dgknL.cn
http://YShAyoG5.dgknL.cn
http://53eX04My.dgknL.cn
http://akCgtRyM.dgknL.cn
http://As7K1GYd.dgknL.cn
http://D2hCI94n.dgknL.cn
http://AK819hwT.dgknL.cn
http://eK7Y4AkB.dgknL.cn
http://www.dtcms.com/a/363687.html

相关文章:

  • 命令行文本处理小工具:cut、sort、uniq、tr 详解与应用
  • 从零开始的python学习——函数(2)
  • shell复习(2)
  • Flutter环境搭建全攻略之-windows环境搭建
  • 毫米波雷达信号处理步骤顺序
  • 树莓派网页监控
  • [嵌入式embed][Qt]Qt5.12+Opencv4.x+Cmake4.x_用Qt编译Windows-Opencv库
  • LangGraph 重要注意事项和常见问题
  • MTK Linux DRM分析(二十六)- MTK mtk_drm_ddp_xxx.c
  • 如何创建逻辑卷
  • Shell脚本入门:从零到精通
  • 容器设备映射配置在海外云服务器GPU加速环境的实施规范
  • QML的focus与activeFocus
  • C++ 左值引用与右值引用介绍
  • MySQL数据库精研之旅第十五期:索引的 “潜规则”(下)
  • OpenCV Python
  • 0825-0829 | 大模型方向周报:多模态模型研究、训练与优化策略、安全与对齐等方向
  • SQL Server--提取性能最差的查询
  • 阿里云国际代理商:如何重置阿里云服务器密码?
  • 阿里云日志服务之WebTracking 小程序端 JavaScript SDK (阿里SDK埋点和原生uni.request请求冲突问题)
  • 现代CPU设计哲学——加载/存储(Load-Store)架构
  • 作为软件专业学生,我眼中新架构实践的‘稳’与‘进’
  • NLP学习系列 | Transformer代码简单实现
  • MySQL 事务隔离与 MVCC
  • 鸿蒙权限崩溃?一招解决闪退难题
  • 自建局域网gitlab如何修改提交时间
  • 365 天技术创作手记:从一行代码到四万同行者的相遇
  • 基本IP保护 Swagger UI 的中间件
  • Flutter doctor
  • 试用Augment编写python脚本实现智能家居3D环境交互响应