LV10算法实现与分析

来源:互联网 发布:网络舆情监测员 编辑:程序博客网 时间:2024/06/11 02:54

LV10算法实现与分析

      Las Vegas算法

         Las Vegas(拉斯维加斯)算法是一个能够保证输出结果为正确的随机化算法,因为它的正确性,使它成为适用情况下的首选算法。Las Vegas算法模型不允许错误的输出,但是它可以允许程序输出“?”结果,即“不知道结果正不正确”。

       Las Vegas算法有两种情况:不允许“?”输出与允许“?”输出。

       其中定义为:

A(x):程序输出结果,F(x):理论输出结果,x:输入值

(1)   不允许:

理论结果与程序结果一致的概率为1,即:

Prob(A(x)= F(x)) = 1.

(2)   允许:

出现“?”的概率不得超过总数的一半:

1              Prob(A(x) = F(x)) ≥ 1/2, and

2       Prob(A(x)= “?”) = 1 − Prob(A(x)= F(x)) ≤ 1/2.

       LV10算法

         算法思想

       初始化:定义两个数组RI,RII;每个数组里面有10个长度为n的01串,RI:x1, x2, ...,x10;RII:y1, y2, ...,y10,

       第一步:从n*n中随机选出10个素数存到p数组中,p1, p2, . . .,p10,

       第二步:将RI中的01字符串转换为数字,然后对素数p取模,将其余数存到s数组中:

si= Number(xi) mod pi

       第三步:RII一样计算取模:

qi= Number(yi) mod pi

       第四步:如果对于所有的i∈ {1, 2, . . ., 10}, si !=qi,则对于所有的 i ∈ {1, 2, . . ., 10}  xi != yi,输出结果为“0”;

       若si = qi,则对RI与RII中的xi与yi进行逐比特比较,如果xi=yi,则输出“1”,否则,输出“?”。

       Las Vegas* 算法

         Las Vegas* 算法是将Las Vegas的第二种带有“?”结果输出的算法改为第一种不带“?”输出的完全正确的结果输出。

       理论分析

       定义:

       A为允许“?”输出的Las Vegas算法,A′为不允许“?”输出的Las Vegas算法。我们将A变为A′,转变过程为当遇见要“?”输出的结果时,即遇见了坏素数,则重新生成素数,对原01序列进行重新求模计算。循环该次过程,直到结果没有“?”输出为止。

    那么这个计算过程的计算次数即坏素数个数,循环的深度是多少呢?

    我们先用理论进行证明:

         令 TimeA(w)为A最坏的一次计算的复杂度,当运行次数至少TimeA(w) 时,A′得到正确结果的概率为1/2,当运行次数至少2TimeA(w) 时,A′得到正确结果的概率为3/4,则当运行次数达到kTimeA(w)时,则A′得到正确结果的概率为:


    那么A′运行得到正确值的期望次数为多少呢?,我们令:


       假设每个“?”的消除都需要TimeA(w)的次数,那么令: i∈IN-{0},set为A的第i次运行。


       当r!=s时



因此:

对于所有的整数i>1;


因此,我们得到:


即期望值不大于6倍TimeA(w)可以得到A′。 [1]

       实验证明

         算法实现:

         初始化:

int R1[LENGTH] = {0};

    intR2[LENGTH] = {0};

    int i;

    for(i = 0; i< LENGTH; i++)

    {

        R1[i] =rand() % 2;/*产生LENGTH以内的随机整数*/

        R2[i] =rand() % 2;/*产生LENGTH以内的随机整数*/

    }

/////////////////////////////////////////////////////////////////////////////////

从n*n中随机选出10个素数存到p数组:

double Ni;

    int e,M,Na;

    Ni=pow(SHORT,2);

    Na=(int)Ni;

    int a1,a2,J[Na],SUN=1;

    J[0]=2;

    for(a1=2;a1<=Na;a1++)

    {

        for(a2=2;a2<a1;a2++)

        {

            if(a1%a2==0)

            break;

            if(a2==a1-1)

            {

                J[SUN]=a1;

                SUN=SUN+1;

            }

        }

    }

    srand((unsigned)time(NULL));/*播种子*/

    for(e = 0; e < 10; e++)

    {

        M = rand() %(SUN+1);

        p[e]=J[M];

    }

////////////////////////////////////////////////////////////////////////////////////////////////////////////

01字符串转换为数字,然后对素数p取模,将其余数存到s数组中:

//求值

    int a,b[SHORT],sum=0,c,d=0,E[10],f[SHORT],sum2=0,G[10];

    int s[10],q[10],p[10];

    for(d=0;d<10;d++)

    {

        sum=0;

        for(a=9+SHORT*d;a>=0+SHORT*d;a--)//算出10个数的每个数每个位的值

        {

            b[a]=R1[a]*pow(2,(9+SHORT*d-a));//pow(2, (9-a))

            f[a]=R2[a]*pow(2, (9+SHORT*d-a));//pow(2,(9-a))

        }

       for(c=0+SHORT*d;c<SHORT+SHORT*d;c++)//把每一位都加起来

        {

            sum=sum+b[c];

            sum2=sum2+f[c];

        }

        E[d]=sum;

        G[d]=sum2;

    }

//取模

    int l;

    for(l=0;l<10;l++)

    {

        s[l]=E[l]%p[l];

        q[l]=G[l]%p[l];

    }

////////////////////////////////////////////////////////////////////////////////////////////////////////////

计算与输出结果:

//比较

    int z,v=0,w=0,A=2,B=1;

    for(z=0;z<10;z++)//x1...x10分别与y1...y10进行对比

    {

        if(s[z]==q[z])//余数相同进行逐位对比

        {

            for(v=SHORT*z;v<(SHORT+1)*z;v++)

                if(R1[v]==R2[v])//每一位都相同,输出成功匹配

                {

                    A=1;

                    break ;

                    exit(0);

                }

 

                else//余数相同,x与y不同,再次循环,直到出现准确结果

                {

                    for(;A==2;)

                    {

                        B=B+1;

                       srand((unsigned)time(NULL));/*播种子*/

                        M = rand() %(SUN+1);

                        p[v]=J[M];

                        if(s[z]==q[z])

                            A=2;

                        else

                            {

                                A=0;

                            }break;

                    }

                }

        }

        else

            w++;

        if(w==9){

            A=0;

        }

    }

////////////////////////////////////////////////////////////////////////////////////////////////////////////

实验数据:(数据为相同数据量n运算程序100次得到结果的均值)

表1实验数据(1)

n的大小

2

3

4

5

6

7

8

9

10

实验次数

5.38

3.73

2.45

2.81

2.6

3.77

1.89

1.19

3.3

 

表2实验数据(2)

11

12

13

14

15

16

17

18

19

20

30

40

50

60

1.62

1.08

1.55

1.02

1.4

1.03

1.65

1.33

1.09

1

1

1

1

1.02

 

图形表示:

图1LV10实验数据

       结论

       当n数据量大时,即R数组里面每个子串位数很多时, n*n很大,素数p的选择范围相应变大,所以si 与qi 相等的概率变小,即RI与RII里面的xi与yi相等的概率也很小,所以“?”出现得少,kT imeA(w)里面的k很小,最后结果次数少。总的实验结果符合理论计算结果。

注意:因为数组是int型,所以最前面的一位为符号位,即n至少为2,长度又不超过64位,所以只运算到60位,基本从n=20位开始,次数平均为1次,且后面趋于稳定,所以可以得出结论。

       参考文献



[1] Prof. Dr. Juraj Hromkovic,Springer - Design and Analysis of RandomizedAlgorithms,© Springer-Verlag Berlin Heidelberg 2005、


作业评论指出的问题(不止针对本文档)

1、长度限制要说明(本身使用语言的精度限制)

2、算法描述跳到哪一步要说明清楚

3、描述要清晰,不要惜字如金,别人看不懂

4、字与曲线大小要匹配好

5、表格设计,重复的可以统一说明

6、文字编辑通顺 

7、变量要斜体,最好用公式编辑器编写字母与公式

8、算法描述均匀,不要一条很多,一条很少

9、大数据用推荐python,不溢出

10、理论再次推导,而不是实验证明就得到与其一致的结论,计算其偏差,优化

11、可以大于6,均值小于就行

12、跨步大,数据差距大,有同学直接跨步太大,直接得到出1,没有波动,要实际情况分析

13、要用与大家一致的表达。



1 0