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