使用parfor
加速蒙特卡罗编码
这个例子展示了如何通过使用加速蒙特卡罗代码parfor
循环。蒙特卡罗方法被发现在许多领域,包括物理,数学,生物和金融。蒙特卡罗方法涉及使用随机分布的输入多次执行一个函数。使用并行计算工具箱,您可以替换为
带a的-循环parfor
-loop可以轻松加速代码。
本例运行一个基于美元拍卖的简单随机模拟。使用蒙特卡罗方法进行多次模拟,找出一美元纸币的市场价值。在本例中,美元拍卖被视为产生依赖于随机过程的输出的黑盒函数。要了解关于该模型的更多信息,请参见美元拍卖.要了解如何在一般情况下加速蒙特卡罗代码,请参见使用parfor-loop估算市场价值.
美元拍卖
美元拍卖是一种非零和游戏,由马丁·舒比克(Martin Shubik)于1971年首次提出。在游戏中,玩家为一美元纸币出价。在一个玩家出价之后,其他所有玩家都可以选择比之前的出价更高的出价。拍卖结束时,没有更多的玩家决定出价。出价最高的人得到一美元,但与典型的拍卖不同的是,出价最高的人和第二高的人都向拍卖师出价。
随机模型
你可以使用随机模型来模拟类似于美元拍卖的游戏。状态(当前出价和活跃玩家数量)可以使用马尔科夫过程建模,因此结果(市场价值)可以预期具有定义良好的统计数据。结果来自条件分布,因此美元拍卖是蒙特卡罗分析的理想选择。市场价值受以下因素影响:
参赛人数(
nPlayers
)玩家采取的行动
在这个例子中,以下算法决定玩家根据状态采取什么行动(出价或退出)。
将出价设置为前一个出价加
增加
.从不是前一个出价人的玩家中随机选择一个玩家。
如果之前没有出价,执行8。
如果前一个出价小于1,则生成一个0到1之间的随机数。如果随机数小于
dropoutRate
,执行7。计算出多少钱
获得
可以获得,如果玩家使一个成功的出价。计算出多少钱
损失
如果玩家是第二高的出价,他们就输了。如果获得
大于损失
,执行8。玩家退出。将该玩家从玩家集合中移除,然后转到9。
玩家出价。
如果仍有2名或以上玩家,请转步骤1。
支持函数金宝appdollarAuction
模拟美元拍卖。要查看代码,请参见dollarAuction.m
.该函数有三个输入:nPlayers
,增加
,dropoutRate
.设置每一个值。
nPlayers =20.;增加=
0.05;dropoutRate =
0.01;
运行一个随机场景dollarAuction
函数。存储输出投标
而且辍学
.
[出价,dropouts] =美元拍卖(nPlayers,incr, dropoutate);
随着游戏的继续,一些玩家出价,一些玩家退出。如果出价超过1,玩家就会陷入“竞价大战”,直到只剩下一个玩家。
表辍学
包含两个变量:球员
,分配给每个玩家的唯一号码;时代
,本轮招标的时候球员
辍学了。使用findgroups
组辍学。时代
,并使用splitapply
求出在每轮比赛中退出的选手人数辍学。时代
.
[G,epoch] = findgroups(dropouts.Epoch);numberDropouts = splitapply(@ number,dropouts.Epoch,G);
最初,没有人中途退出。将此信息添加到时代
而且numberDropouts
通过将1
而且0
.
epoch = [1;epoch];numberDropouts = [0;numberDropouts];
使用nPlayers
而且cumsum
来计算剩余的玩家数量numberDropouts
.使用以下方法计算出价增加
而且时代
.使用楼梯
的累计金额来绘制出价numberDropouts
.
playersRemaining = nPlayers - cumsum(numberDropouts);楼梯(增加*时代,playersRemaining)包含(“收购”) ylabel (“剩余玩家数量”)
用蒙特卡罗方法估计市场价值
你可以用价值来估计这张票据的市场价值origValue
采用蒙特卡罗方法。在这里,您将生成一个蒙特卡罗模型,并比较使用和不使用Parallel Computing Toolbox的速度。设置试验次数nTrials
用于随机抽样结果。
nTrials = 10000;
您可以通过执行支持函数对可能的结果进行抽样金宝appdollarAuction
很多次了。使用一个为
-循环产生nTrials
样品,存储从每次试验的最后出价B
.每次运行dollarAuction
函数,你会得到不同的结果。但是,当您多次运行该函数时,您从所有运行中产生的结果将具有定义良好的统计信息。
记录计算所花费的时间nTrials
模拟。为了减少运行时间中的统计噪声,请重复此过程五次,然后选择最小的运行时间。
T = 0 (1,5);为j = 1:5 tic B =零(1,n个试验);为i = 1:nTrials投标=美元拍卖(nPlayers,incr, dropoutate);B(i) = bids.Bid(end);结束T (j) = toc;结束forTime = min(t)
forTime = 21.4323
使用柱状图
绘制最终出价的柱状图B
.使用参照线
将原始价值(一美元)和平均市场价值覆盖在图上的意思是
.
直方图(B);origLine = xline(1,“k”,“线宽”3);marketLine = xline(均值(B),“k——”,“线宽”3);包含(“市场价值”) ylabel (“频率”) legend([origLine, marketLine],{“原值”,“市场价值”},“位置”,“东北”)
在给定算法和输入参数的情况下,平均市场价值大于原始价值。
使用parfor
-loop估算市场价值
您可以使用并行计算工具箱轻松地加快您的蒙特卡罗代码。方法创建一个具有四个工作人员的并行池“本地”
概要文件。
P = parpool(“本地”4);
使用“本地”配置文件启动并行池(parpool)…连接到并行池(工人数量:4)。
取代为
带a的-循环parfor
循环。记录计算所花费的时间nTrials
模拟。为了减少运行时间中的统计噪声,请重复此过程5次,然后使用最小的运行时间。
T = 0 (1,5);为J = 1:5 ticparfori = 1:nTrials投标=美元拍卖(nPlayers,incr, dropoutate);B(i) = bids.Bid(end);结束T (j) = toc;结束parforTime = min(t)
parforTime = 5.9174
对于四个worker,结果表明当您使用parfor
循环。
产生可重复的结果与随机数字parfor
循环
当你生成随机数的时候parfor
-loop,每次运行循环都会产生不同的结果。为了创建可重复的结果,循环的每次迭代都必须具有随机数生成器的确定状态。有关更多信息,请参见在parfor-Loops中重复随机数.
支持函数金宝appdollarAuctionStream
用第四个参数,年代
.此支持函数金宝app使用指定的流产生随机数。要查看代码,请参见dollarAuctionStream.m
.
创建流时,该流的子流在统计上是独立的。有关更多信息,请参见RandStream
.为确保代码每次产生相同的结果分布,请在循环的每次迭代中创建一个随机数生成器流,然后设置Substream
属性设置为循环索引。取代dollarAuction
与dollarAuctionStream
,然后使用年代
运行dollarAuctionStream
在一个工人身上。
记录计算所花费的时间nTrials
模拟。为了减少运行时间中的统计噪声,请重复此过程五次,然后选择最小的运行时间。
T = 0 (1,5);为J = 1:5 ticparfori = 1:nTrials s = RandStream(“Threefry”);s.Substream = i;bids = dollarAuctionStream(nPlayers,incr, dropoutate,s);B(i) = bids.Bid(end);结束T (j) = toc;结束parforTime = min(t)
parforTime = 8.7355
从桌面扩展到集群
您可以将代码从桌面扩展到具有更多worker的集群。有关从桌面扩展到集群的更多信息,请参见从桌面扩展到集群.
使用删除
关闭现有的并行池。
删除(p);
计算支撑函数金宝appdollarAuctionStream
在一个parfor
循环。运行相同的程序parfor
-循环不同数量的工人,并记录所经过的时间。要减少运行时间中的统计噪声,请运行parfor
-循环五次,然后取最小的运行时间。记录数组中的最小次数elapsedTimes
.在下面的代码中,替换MyCluster
集群配置文件的名称。
工人= [1 2 4 8 16 32];elapsedTimes = 0(1,数字(工人));使用'MyCluster'集群配置文件创建一个池P = parpool(“MyCluster”、32);
启动并行池(parpool)使用'MyCluster'配置文件…连接到并行池(工人数:32)。
为K = 1:数字(工人)t =零(1,5);为J = 1:5 ticparfor(i = 1:nTrials, workers(k)) s = RandStream(“Threefry”);s.Substream = i;bids = dollarAuctionStream(nPlayers,incr, dropoutate,s);B(i) = bids.Bid(end);结束T (j) = toc;结束elapsedTimes(k) = min(t);结束
分析文件并将文件传输给工作人员…完成。
通过除法计算计算加速elapsedTimes (1)
《泰晤士报》elapsedTimes
.通过绘制加速与工人数量的关系来检查强缩放。
speedup = elapsedTimes(1) ./ elapsedTimes;情节(工人,加速)包含(“工人人数”) ylabel (“计算加速”)
计算速度随着工人数量的增加而增加。