蒙特卡罗模拟之书店买书

   书店买书之0-1规划(蒙特卡罗模拟)

蒙特卡罗方法又称随机抽样或统计试验方法,通常蒙特卡罗模拟通过构造符合一定规则的随机数来解决数学上的各种问题。对于那些由于计算过于复杂而难以得到解析解或者根本没有解析解的问题,蒙特卡罗模拟是一种有效的求出数值解的方法。

蒙特卡罗算法表示采样越多,越近似最优解。举个例子,假如筐里有100个苹果,让我每次闭眼拿1个,挑出最大的。于是我随机拿1个,再随机拿1个跟它比,留下大的,再随机拿1个……我每拿一次,留下的苹果都至少不比上次的小。拿的次数越多,挑出的苹果就越大,但我除非拿100次,否则无法肯定挑出了最大的。这个挑苹果的算法,就属于蒙特卡罗算法。告诉我们样本容量足够大,则最接近所要求解的概率。

问题如下:

         我们解决这种问题的根本思想是利用matlab的rand函数来模拟出每一种可能,并计算其结果,只要列出其全部结果或者列出其大部分情况,我就能无限接近最优答案。

解:设 i=1,2, … , 6 表示 A.B····E、F 六 家商城 , j=1,2···,5表示五本书。

        记m_{ij}表示第j本书在第i家店的售价,    q_{i}表示第i家店的运费。

        当x_{ij}=0时,则没有在该店买书;当x_{ij}=1时,则在该店买书。

      约束有:  \sum_{i=1}^{6}x_{ij}=1,j=1,2,···,5        (每本书只买一本)

         花费求和有两个方面:

1.书价=             \sum_{j=1}^{5}[\sum_{i=1}^{6}\left ( x_{ij}\cdot m_{ij} \right )]

2.运费  求解可参考如下代码

    result = randi([1, 6],1,5); % 在1-6这些整数中随机抽取一个1*5的向量,表示这五本书分别在哪家书店购买
    index = unique(result);  % 在哪些商店购买了商品,因为我们等下要计算运费
    money = sum(freight(index)); % 计算买书花费的运费

先通过unique函数确定在哪几家店买过书,然后通过其下标求和。(freight是一个记录每家店运费数组)

蒙特卡罗模拟和遗传算法的异同点:

同:都不同程度存在“随机性”

异:蒙特卡罗方法相当于一个人走迷宫,而遗传算法和粒子群可以找一群人来走迷宫。蒙特卡罗有一种究极暴力求解的感觉,而遗传算法则是看“运气”。

min_money = +Inf;  % 初始化最小的花费为无穷大,后续只要找到比它小的就更新
min_result = randi([1, 6],1,5);  % 初始化五本书都在哪一家书店购买,后续我们不断对其更新
%若min_result = [5 3 6 2 3],则解释为:第1本书在第5家店买,第2本书在第3家店买,第3本书在第6家店买,第4本书在第2家店买,第5本书在第3家店买  
n = 100000;  % 蒙特卡罗模拟的次数
M = [18	 39	29	48	59
        24	45	23	54	44
        22	45	23	53	53
        28	47	17	57	47
        24	42	24	47	59
        27	48	20	55	53];  % m_ij  第j本书在第i家店的售价
freight = [10 15 15 10 10 15];  % 第i家店的运费
for k = 1:n  % 开始循环
    result = randi([1, 6],1,5); % 在1-6这些整数中随机抽取一个1*5的向量,表示这五本书分别在哪家书店购买
    index = unique(result);  % 在哪些商店购买了商品,因为我们等下要计算运费
    money = sum(freight(index)); % 计算买书花费的运费
    % 计算总花费:刚刚计算出来的运费 + 五本书的售价
    for i = 1:5   
        money = money + M(result(i),i);  
    end
    if money < min_money  % 判断刚刚随机生成的这组数据的花费是否小于最小花费,如果小于的话
        min_money = money  % 我们更新最小的花费
        min_result = result % 用这组数据更新最小花费的结果
    end
end

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
问题 dp实现 题目: 有一书店引进了一套,共有3卷,每卷定价是60元,书店为了搞促销,推出一个活动,活动如下: 如果单独购其中一卷,那么可以打9.5折。 如果同时购两卷不同的,那么可以打9折。 如果同时购三卷不同的,那么可以打8.5折。 如果小明希望购第1卷x本,第2卷y本,第3卷z本,那么至少需要多少钱呢?(x、y、z为三个已知整数)。 1、过程为一次一次的购,每一次购也许只一本(这有三种方案),或者两本(这也有三种方案), 或者三本一起(这有一种方案),最后直到完所有需要的。 2、最后一步我必然会在7种购方案中选择一种,因此我要在7种购方案中选择一个最佳情况。 3、子问题是,我选择了某个方案后,如何使得购剩余的能用最少的钱?并且这个选择不会使得剩余的为负数 。母问题和子问题都是给定三卷的购量,求最少需要用的钱,所以有"子问题重叠",问题中三个购量设置为参数, 分别为i、j、k。 4、的确符合。 5、边界是一次购就可以完所有的,处理方式请读者自己考虑。 6、每次选择最多有7种方案,并且不会同时实施其中多种,因此方案的选择互不影响,所以有"子问题独立"。 7、我可以用minMoney[i][j][k]来保存购第1卷i本,第2卷j本,第3卷k本时所需的最少金钱。 8、共有x * y * z个问题,每个问题面对7种选择,时间为:O( x * y * z * 7) = O( x * y* z )。 9、用函数MinMoney(i,j,k)来表示购第1卷i本,第2卷j本,第3卷k本时所需的最少金钱,那么有: MinMoney(i,j,k)=min(s1,s2,s3,s4,s5,s6,s7),其中s1,s2,s3,s4,s5,s6,s7分别为对应的7种方案使用的最少金钱: s1 = 60 * 0.95 + MinMoney(i-1,j,k) s2 = 60 * 0.95 + MinMoney(i,j-1,k) s3 = 60 * 0.95 + MinMoney(i,j,k-1) s4 = (60 + 60) * 0.9 + MinMoney(i-1,j-1,k) s5 = (60 + 60) * 0.9 + MinMoney(i-1,j,k-1) s6 = (60 + 60) * 0.9 + MinMoney(i-1,j,k-1) s7 = (60 + 60 + 60) * 0.85 + MinMoney(i-1,j-1,k-1)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值