蒙特卡罗 随机化算法
蒙特卡罗(Monte Carlo)方法是一种以概率统计为指导思想的方法,通过使用随机数来解决许多问题。
基本思想:
当所求解问题时是一种随机事件,或者是某个随机变量的数学期望时,我们通过统计随机事件出现的频率,或者得到随机变量的数字特征,来得到问题的解。在实际应用中,不论采用确定性算法,还是随机化算法,都无法保证每次都得到正确的解答。
蒙特卡罗算法采样越多,越接近最优解;(强调每一次随机都在进步,提高的过程);
拉斯维加斯算法采样越多,越有可能找到最优解;(强调直接想要最优解)
1.主元素问题
设T[n]是有n个元素的数组,其实如果x出现的概率p(x)>1/2,则称x为数组T的主元素,现在给了一组数T[]={12,12,61,62,42,62,12,12,12,12,12,43}。求T[]的主元素。
如果使用蛮力法,依次将所有的数做比较,需要比较n*(n-1)/2次,时间复杂度为0(n^2);
蒙特卡罗方法,先随机抽取一个数x,与其他数做比较,主元素出现所占数组总数的概率大于二分之一,所以这个数是主元素的概率p(x)>1/2,随着抽取数的次数增多,越来越确定主元素是谁,逼近最优解。
1 //随机化算法 蒙特卡罗算法 主元素问题 2 #include "stdafx.h" 3 #include "RandomNumber.h" 4 #include <cmath> 5 #include <iostream> 6 using namespace std; 7 8 //判定主元素的蒙特卡罗算法 9 template<class Type> 10 bool Majority(Type *T,int n) 11 { 12 RandomNumber rnd; 13 int i = rnd.Random(n); 14 15 Type x = T[i]; //随机选择数组元素 16 int k = 0; 17 18 for(int j=0; j<n; j++) 19 { 20 if(T[j] == x) 21 { 22 k++; 23 } 24 } 25 26 return (k>n/2); //k>n/2时,T含有主元素 27 } 28 29 //重复k次调用算法Majority 30 template<class Type> 31 bool MajorityMC(Type *T,int n,double e) 32 { 33 int k = ceil(log(1/e)/log((float)2)); 34 for(int i=1; i<=k; i++) 35 { 36 if(Majority(T,n)) 37 { 38 return true; 39 } 40 } 41 return false; 42 } 43 44 int main() 45 { 46 int n = 10; 47 float e = 0.001; 48 int a[] = {5,5,5,5,5,5,1,3,4,6}; 49 cout<<"数组a的元素如下:"<<endl; 50 for(int i=0; i<10; i++) 51 { 52 cout<<a[i]<<" "; 53 } 54 cout<<endl; 55 cout<<"调用MajorityMC判断数组是否含有主元素结果是:"<<MajorityMC(a,n,e)<<endl; 56 }