蒙特卡洛(Monte Carlo)

Monte-Carlo算法泛指一类算法。在这些算法中,要求解的问题是某随机事件的概率或某随机变量的期望。这时,通过“实验”方法,用频率代替概率或得到随机变量的某些数字特征,以此作为问题的解。


在一个1平方米的正方形木板上,随意画一个圈,求这个圈的面积。

假设我手里有一支飞镖,我将飞镖掷向木板。并且,我们假定每一次都能掷在木板上,不会偏出木板,但每一次掷在木板的什么地方,是完全随机的。即,每一次飞镖扎进木板的任何一点的概率的相等的。

当投掷次数足够大时,例如100次,然后我们统计这100次中,扎入不规则图形内部的次数有32次,那么,可以用 32/100近似估计不规则图形的面积。


Monte-Carlo算法区别于确定性算法,它的解不一定是准确或正确的,其准确或正确性依赖于概率和统计,但在某些问题上,当重复实验次数足够大时,可以从很大概率上(这个概率是可以在数学上证明的,但依赖于具体问题)确保解的准确或正确性,所以,我们可以根据具体的概率分析,设定实验的次数,从而将误差或错误率降到一个可容忍的程度。

上述问题中,设总面积为S,不规则图形面积为s,共投掷n次,其中掷在不规则图形内部的次数为k。根据伯努利大数定理,当试验次数增多时,k/n依概率收敛于事件的概率s/S


优点:
1、能够比较逼真地描述具有随机性质的事物的特点及物理实验过程
2、受几何条件限制小
3、收敛速度与问题的维数无关
4、具有同时计算多个方案与多个未知量的能力
5、误差容易确定
6、程序结构简单,易于实现

缺点:
1收敛速度慢
2误差具有概率性
3在粒子输运问题中,计算结果与系统大小有关
 


TSP案例

一个售货员必须访问n个城市,这n个城市是一个完全图,售货员需要恰好访问所有城市一次,并且回到最终的城市。城市与城市之间有一个旅行费用,售货员希望旅行费用之和最少

Matlab

clear;clc

%只有10个城市的简单情况
 coord =[0.6683 0.6195 0.4 0.2439 0.1707 0.2293 0.5171 0.8732 0.6878 0.8488 ;
         0.2536 0.2634 0.4439 0.1463 0.2293 0.761  0.9414 0.6536 0.5219 0.3609]' ;  
% 城市坐标矩阵,n行2列,第一列横坐标,第二列纵坐标,第一个城市坐标(0.6683,0.2536)

n = size(coord,1);  % 城市的数目,size(A,1)返回的是矩阵A所对应的行数

figure(1)  % 新建一个编号为1的图形窗口
plot(coord(:,1),coord(:,2),'o');   % 画出城市的分布散点图:plot函数画图,A(:,1)就表示A的第1列的所有元素依次取
for i = 1:n
    text(coord(i,1)+0.01,coord(i,2)+0.01,num2str(i))   % 在图上标上城市的编号(加上0.01表示把文字的标记往右上方偏移一点)
end
hold on % 等一下要接着在这个图形上画图的


d = zeros(n);   % 初始化两个城市的距离矩阵全为0,zeros(n)生成n*n的矩阵
for i = 2:n  
    for j = 1:i  
        coord_i = coord(i,:);   x_i = coord_i(1);     y_i = coord_i(2); 
         % coord_i依次取i行里数,城市i的横坐标为x_i,纵坐标为y_i(2号--10号)
        coord_j = coord(j,:);   x_j = coord_j(1);     y_j = coord_j(2); 
         % 城市j的横坐标为x_j,纵坐标为y_j

        d(i,j) = sqrt((x_i-x_j)^2 + (y_i-y_j)^2);   % 计算城市i和j的距离
    end
end
d = d+d';   % 生成距离矩阵的对称的一面

min_result = +inf;  
% 假设最短的距离为min_result,初始化为无穷大,后面只要找到比它小的就对其更新
min_path = [1:n];  
% 初始化最短的路径就是1-2-3-...-n
N = 10000;  
% 蒙特卡罗模拟的次数,设为10000次
for i = 1:N  % 开始循环
    result = 0;  % 初始化走过的路程为0
    path = randperm(n);  % 生成一个1-n的随机打乱的序列
    for i = 1:n-1  
        result = d(path(i),path(i+1)) + result;  % 按照这个序列不断的更新走过的路程这个值
    end
    result = d(path(1),path(n)) + result;  % 最后一个城市返回到最开始那个城市的距离
    if result < min_result  % 判断这次模拟走过的距离是否小于最短的距离,如果小于就更新最短距离和最短的路径
        min_path = path;
        min_result = result
    end
end

min_path = [min_path,min_path(1)];   
% 在最短路径的最后面加上一个元素,即第一个点(我们要生成一个封闭的图形)
n = n+1;  % 城市的个数加一个
for i = 1:n-1 
     j = i+1;
    coord_i = coord(min_path(i),:);   x_i = coord_i(1);     y_i = coord_i(2); 
    coord_j = coord(min_path(j),:);   x_j = coord_j(1);     y_j = coord_j(2);
    plot([x_i,x_j],[y_i,y_j],'-')    % 每两个点就作出一条线段,直到所有的城市都走完
    pause(0.5)  % 暂停0.5s再画下一条线段
    hold on
end


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值