随机算法

目录

一,蒙特卡洛算法

1,圆周率估算

2,弗里瓦德算法(Frievald's Algorithm)

51Nod 1140 矩阵相乘结果的判断

3,数组中出现次数超过一半的数字

力扣 剑指 Offer 39. 数组中出现次数超过一半的数字

4,其他蒙特卡洛方法

二,蒙特卡洛算法的正确性

1,带校验的随机算法

2,不校验的随机算法

三,快速排序

四,数论中的随机算法

Pollard‘s rho大数分解算法


一,蒙特卡洛算法

蒙特卡洛算法是一类随机算法的总称,这些随机算法都是基于一个已知的分布规律进行计算的。

1,圆周率估算

取一个1*1的正方形,在其中随机取一个点,点在正方形内切圆中的概率就是PI/4

取的点越多,估算越精确。

2,弗里瓦德算法(Frievald's Algorithm)

弗里瓦德算法是专门用来解决下面这个问题的。

51Nod 1140 矩阵相乘结果的判断

给出三个N*N的矩阵A, B, C,问A * B是否等于C?

Input

第1行,1个数N。(0 <= N <= 500) 第2 - N + 1行:每行N个数,对应矩阵A的元素。(0 <= Mii <= 16) 第N + 2 - 2N + 1行:每行N个数,对应矩阵B的元素。(0 <= Mii <= 16) 第2N + 2 - 3N + 1行:每行N个数,对应矩阵C的元素。

Output

如果相等输出Yes,否则输出No。

Sample Input

2
1 0
0 1
0 1
1 0
0 1
1 0

Sample Output

Yes
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int p = 1000000007;

template<typename T>
vector<vector<T>> multi(vector<vector<T>>&v1,vector<vector<T>>&v2)
{
    vector<vector<T>>ans(v1.size(),vector<T>(v2[0].size(),0));
    for(int i=0;i<v1.size();i++)for(int j=0;j<v2[0].size();j++)for(int k=0;k<v2.size();k++)ans[i][j]+=v1[i][k]*v2[k][j],ans[i][j]%=p;
    return ans;
}

#define CIN(x) while (!(cin >> x)) { \
        cin.clear();      \
        cin.ignore();     \
        }

//输入一维vector
template<typename T>
void fcin(vector<T>&v,int len)
{
    v.resize(len);
    for(int i=0;i<v.size();i++)CIN(v[i]);
}
//输入二维vector
template<typename T>
void fcin2(vector<vector<T>>&v,int row,int col)
{
    v.resize(row);
    for(int i=0;i<v.size();i++)fcin(v[i],col);
}


int main()
{
    int n;
    cin>>n;
    vector<vector<long long>>A,B,C;
    fcin2(A,n,n);
    fcin2(B,n,n);
    fcin2(C,n,n);
    vector<vector<long long>>x(n);
    for(int i=0;i<n;i++){
        x[i].resize(1);
        x[i][0]=rand();
    }
    vector<vector<long long>>ans1=multi(B,x),ans2=multi(A,ans1),ans3=multi(C,x);
    if(VecIsSame(ans2,ans3))cout<<"Yes";
    else cout<<"No";
    return 0;
}

看着代码很多,但是只有main函数是需要独立写的,其他都可以从我的ACM模板中找到。

3,数组中出现次数超过一半的数字

力扣OJ 剑指 Offer(31-68)_nameofcsdn的博客-CSDN 博客

力扣 剑指 Offer 39. 数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

限制:

1 <= 数组长度 <= 50000

思路:

不校验的随机算法

一层逻辑:随机取2个数,如果不同就继续取,直到2个数相同,此时这个数大概率就是正确答案。

二层逻辑:取2个数,如果不同就继续取,直到2个数相同,此时这个数大概率就是正确答案,但是,不是随机取,而是直接取一层逻辑得到的值。

同理,我们可以不停的这样嵌套,想要几层就有几层。

代码:

class Solution {
public:
    int err=123456789;
    int get0(vector<int>& nums){
        return nums[rand()%nums.size()];
    }
    int get1(vector<int>& nums){
        int a=0,b=1;
        while(a!=b){
            a=err,b=err;
            while(a==err)a=get0(nums);
            while(b==err)b=get0(nums);
        }
        return a;
    }
    int get2(vector<int>& nums){
        int a=0,b=1;
        while(a!=b){
            a=err,b=err;
            while(a==err)a=get1(nums);
            while(b==err)b=get1(nums);
        }
        return a;
    }
    int get3(vector<int>& nums){
        int a=0,b=1;
        while(a!=b){
            a=err,b=err;
            while(a==err)a=get2(nums);
            while(b==err)b=get2(nums);
        }
        return a;
    }
    int get4(vector<int>& nums){
        int a=0,b=1;
        while(a!=b){
            a=err,b=err;
            while(a==err)a=get3(nums);
            while(b==err)b=get3(nums);
        }
        return a;
    }
    int majorityElement(vector<int>& nums) {
        return get4(nums);
    }
};

然而最坏情况下算法是错的,失败用例:

[233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333,2333]

这是501个233和499个2333

改进思路:

带校验的随机算法

不需要嵌套,只要任何时候有怀疑的值,直接确定性检测即可

class Solution {
public:
    int err=123456789;
    int get0(vector<int>& nums){
        return nums[rand()%nums.size()];
    }
    int get(vector<int>& nums){
        int a=0,b=1;
        while(a!=b){
            a=err,b=err;
            while(a==err)a=get0(nums);
            while(b==err)b=get0(nums);
        }
        return a;
    }
    int majorityElement(vector<int>& nums) {
        while(true){
            int a=get(nums),s=0;
            for(int i=0;i<nums.size();i++)if(nums[i]==a)s++;
            if(s>nums.size()/2)return a;
        }
    }
};

4,其他蒙特卡洛方法

蒙特卡洛方法_nameofcsdn的博客-CSDN博客

二,蒙特卡洛算法的正确性

随机算法根据是否校验计算结果,可以分为两种。

1,带校验的随机算法

带校验的随机算法,可以确保计算结果正确,算法没有时间上限。

例如:

剑指 Offer 39. 数组中出现次数超过一半的数字  其中的带校验的随机算法

2,不校验的随机算法

不校验的随机算法,无法保证计算结果正确,但相对来说不需要大量重复,有些算法有时间上限,有的没有。

例如:

圆周率估算,这个只能说误差不超过某个值的概率至少为多少,不能保证误差一定不超过它。

弗里瓦德算法,这个可以重复几次,增大正确的概率,但是还是无法保证正确性。

剑指 Offer 39. 数组中出现次数超过一半的数字  其中的不校验的随机算法

三,快速排序

快速排序选取划分节点的这一步,可以随机选一个,也可以固定选待排序段的第一个元素,本质上是一样的,所以也可以说快速排序也是一种随机算法。
这种排序算法不属于蒙特卡洛算法,运行结果一定是正确的而且运行时间有上界。

四,数论中的随机算法

Pollard‘s rho大数分解算法

Pollard‘s rho大数分解算法_nameofcsdn的博客-CSDN博客

通过用递推数列模拟随机数列,用周期找到因子

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值