蒙特卡洛 (Monte Carlo)方法,或称计算机随机模拟方法,是一种基于"随机数"的计算方法。这一方法源于美国在第二次世界大战中研制原子弹的"曼哈顿计划"。该计划的主任之一、数学家冯·诺伊曼用驰名世界的赌城-摩纳哥的Monte Carlo-来命名这种方法,为它蒙上了一层神秘色彩。
Monte Carlo方法的基本思想很早以前就被人们所发现和利用。早在17世纪,人们就知道用事件发生的"频率"来决定事件的"概率"。19世纪人们用投针试验的方法来决定圆周率π。本世纪40年代电子计算机的出现,特别是近年来高速电子计算机的出现,使得用数学方法在计算机上大量、快速地模拟这样的试验成为可能。 考虑平面上的一个边长为1的正方形及其内部的一个形状不规则的"图形",如何求出这个"图形"的面积呢?Monte Carlo方法是这样一种"随机化"的方法:向该正方形"随机地"投掷N个点,其中有M个点落于"图形"内,则该"图形"的面积近似为M/N。
可用民意测验来作一个不严格的比喻。民意测验的人不是征询每一个登记选民的意见,而是通过对选民进行小规模的抽样调查来确定可能的优胜者。其基本思想是一样的。
科技计算中的问题比这要复杂得多。比如金融衍生品(期权、期货、掉期等)的定价及交易风险估算,问题的维数(即变量的个数)可能高达数百甚至数千。对这类问题,难度随维数的增加呈指数增长,这就是所谓的"维数的灾难"(Course Dimensionality),传统的数值方法难以对付(即使使用速度最快的计算机)。Monte Carlo方法能很好地用来对付维数的灾难,因为该方法的计算复杂性不再依赖于维数。以前那些本来是无法计算的问题现在也能够计算量。为提高方法的效率,科学家们提出了许多所谓的"方差缩减"技巧。蒙特卡洛方法还有一个优点,就是可以很容易的改成并行计算。
另一类形式与Monte Carlo方法相似,但理论基础不同的方法-"拟蒙特卡罗方法"(Quasi-Monte Carlo方法)-近年来也获得迅速发展。我国数学家华罗庚、王元提出的"华-王"方法即是其中的一例。这种方法的基本思想是"用确定性的超均匀分布序列(数学上称为Low Discrepancy Sequences)代替Monte Carlo方法中的随机数序列,一些著名的超均匀分布序列如Halton序列,Sobol序列。对某些问题该方法的实际速度一般可比Monte Carlo方法提出高数百倍,并可计算精确度。
Cpp程序示例:
计算现价100,执行价100,波动率.025,利率0.1,期限一年的欧式看涨期权
#include<iostream>
#include<math.h>
#include"runtime.h"
#include"Matrix.h"
#include"Random.h"
using namespace std;
int main()
{
clock_t t1,t2;
t1=clock();
double S,X,r,sigma,time,n;
S=100.0;
X=100.0;
r=0.1;
sigma=0.25;
time=1.0;
n=500000;
double R=(r-0.5*sigma*sigma)*time;
double SD=sigma*sqrt(time);
double call=0.0;
double call_t=0.0;
int i,j;
Rand<double> rand("time");
for (j=0;j<40;j++)
{
for (i=1;i<=n;i++)
{
double ST=S*exp(R+SD*rand.norm_dev());
call_t+=max(0.0,ST-X);
}
call+=exp(-r*time)*call_t/n;
call_t=0.0;
}
t2=clock();
cout<<"price="<<call/40<<endl;
runtime(t2-t1);
}
|
|