主要内容

使用parfor加速蒙特卡罗编码

这个例子展示了如何通过使用加速蒙特卡罗代码parfor循环。蒙特卡罗方法被发现在许多领域,包括物理,数学,生物和金融。蒙特卡罗方法涉及使用随机分布的输入多次执行一个函数。使用并行计算工具箱,您可以替换带a的-循环parfor-loop可以轻松加速代码。

本例运行一个基于美元拍卖的简单随机模拟。使用蒙特卡罗方法进行多次模拟,找出一美元纸币的市场价值。在本例中,美元拍卖被视为产生依赖于随机过程的输出的黑盒函数。要了解关于该模型的更多信息,请参见美元拍卖.要了解如何在一般情况下加速蒙特卡罗代码,请参见使用parfor-loop估算市场价值

美元拍卖

美元拍卖是一种非零和游戏,由马丁·舒比克(Martin Shubik)于1971年首次提出。在游戏中,玩家为一美元纸币出价。在一个玩家出价之后,其他所有玩家都可以选择比之前的出价更高的出价。拍卖结束时,没有更多的玩家决定出价。出价最高的人得到一美元,但与典型的拍卖不同的是,出价最高的人和第二高的人都向拍卖师出价。

随机模型

你可以使用随机模型来模拟类似于美元拍卖的游戏。状态(当前出价和活跃玩家数量)可以使用马尔科夫过程建模,因此结果(市场价值)可以预期具有定义良好的统计数据。结果来自条件分布,因此美元拍卖是蒙特卡罗分析的理想选择。市场价值受以下因素影响:

  • 参赛人数(nPlayers

  • 玩家采取的行动

在这个例子中,以下算法决定玩家根据状态采取什么行动(出价或退出)。

  1. 将出价设置为前一个出价加增加

  2. 从不是前一个出价人的玩家中随机选择一个玩家。

  3. 如果之前没有出价,执行8。

  4. 如果前一个出价小于1,则生成一个0到1之间的随机数。如果随机数小于dropoutRate,执行7。

  5. 计算出多少钱获得可以获得,如果玩家使一个成功的出价。

  6. 计算出多少钱损失如果玩家是第二高的出价,他们就输了。如果获得大于损失,执行8。

  7. 玩家退出。将该玩家从玩家集合中移除,然后转到9。

  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属性设置为循环索引。取代dollarAuctiondollarAuctionStream,然后使用年代运行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 (“计算加速”

计算速度随着工人数量的增加而增加。