算法设计与分析
实验结果:
n 10000000 100000000 1000000000 test1结果 5.329416 5.332534 3.33383 test2结果 -0.034848 0.001925 0.000091 精度 2 3 4
EX4.若I 是∫0
f (x)dx的正确值,h是由HitorMiss算法 返回的值,则当n ≥ I (1 − I )/ε2 δ时有: Prob[∣h − I ∣ < ε] ≥ 1– δ
实验代码
#include <iostream> #include <cmath> #include <random> #include <cstdlib> using namespace std; #define target 1 int n=15,head=7; int val[15] = { 2, 5,10, 7, 4,14, 8, 1, 9, 6,11,13,12,15, 3}; int ptr[15] = {14, 9,10, 6, 1,13, 8, 0, 2, 3,12, 5,11,100,4}; int int int int int search(int x,int i); A(int x); //确定性O(n)算法 B(int x); //时间为O(√n)的确定性算法 C(int x); //在算法B基础上改进的sherwood算法 D(int x); //时间为O(n)的概率算法
解答过程
1
证明 :任取 n
≥ I(1 − I)/ε2 δ,H(n)表示 n次命中的次数,则 H(n) = nh为一个二项分布 E[H(n)] = nI,D[H(n)] = nI(1 − I)
H(n ) H(n ) ∣ < ε] = Prob[∣ ∣ n − E ( n )∣ < ε ] nI(1−I) ε2 n 2
}
实验结果
查找对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 均值 A算法比较次数 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 7 B算法比较次数 3 3 4 5 3 4 3 4 5 3 4 5 6 7 8 4.53 C算法比较次数 3 3 3 5 3 3 3 3 3 3 4 4 3 3 5 4.2 D算法比较次数 0 1 1 3 4 0 6 7 8 3 10 6 9 4 9 4.67
实验代码
#include #include #include #include <iostream> <cstdlib> <set> <random>
using namespace std; #define N 1000000 #define pi 3.1415926 int main() { random_device rd; mt19937 engine(rd); uniform_int_distribution<> dist(1,N); int i=0,number=dist(engine); double count=0; set<int> myset; for(i=0;i<50;i++) { do{ myset.insert(number); count++; number=dist(engine);
结论
算法在 N较大时效果更加明显,误差更加小,性能更加优越
3.2随机数的预处理
EX.分析dlogRH的工作原理,指出该算法相应的u和v
解: dlogRH采用了 Sherwood算法进行随机化的预处理
dlogRH(g, a, p) { // Sherwood算法 r ← uniform(0..p-2); b ← ModularExponent(g, r, p); //求幂模b=gr mod p,随机取出一个元素 c ← ba mod p; //((gr modp)(gxmodp))modp=gr+xmodp=c,将实例X转化为实例Y y ← logg,pc; // 使用确定性算法求logp,gc, y=r+x return (y-r) mod (p-1); // 将解变为X的实例 }
int main() { cout<<A(target)<<endl; cout<<B(target)<<endl; cout<<C(target)<<endl; cout<<D(target)<<endl; system("pause"); } int search(int x,int i) { int count=0; while(x>val[i]) { count++; i = ptr[i]; } return count; } int A(int x) { return search(x,head); }
int B(int x) { int i = head; int max = val[i]; int y; for(int j = 0;j<sqrt(float(n));j++) { y = val[j]; if(max<y&&y<=x) { max = y; i=j; } } return (search(x,i)+(int)sqrt((float)n)); } int C(int x) { random_device rd; mt19937 engine(rd); uniform_int_distribution<> dist(0,n-1); int i = dist(engine); int max = val[i]; int y; for(int j = 0;j<sqrt(float(n));j++) { int temp = dist(engine); y = val[temp]; if(max<y&&y<=x) { max = y; i=temp; } } return search(x,i)+(int)sqrt((float)n); } int D(int x) { random_device rd; mt19937 engine(rd); uniform_int_distribution<> dist(0,n-1); int i=dist(engine); int y=val[i]; if(x<y) return search(x,head); else if(x>y) return search(x,ptr[i]); else return i;
结论:性能方面 C>B>D>A
4.1八皇后问题
Ex.证明:当放置(k+1)th皇后时,若有多个位置是开 放的,则算法QueensLV选中其中任一位置的概率相等。
证明:假设放置 (k+1)个皇后时,有 nb个位置是开放,分别记为 a,b…i…nb 那么第 a个位置被选到的概率为 1 ∗ 1
2
∗
2 3
由切比雪夫不等式 Prob[∣h − I∣
≥1−
因为 所以 所以
D(
H (n ) n ε2
)
=1−
D(H(n ) ε2 n 2
=1−
=1−
I(1−I) n ε2
n≥
I(1−I) ε2 δ
I(1−I) n ε2
≤δ
Prob[∣h − I∣ < ε] ≥ 1– δ
2.3概率算法
EX.用上述算法,估计整数子集1~n的大小,并分析n对 估计值的影响。
int main() { srand(time(NULL)); HitorMiss(); system("pause"); }
实验结果
n 1000000 10000000 100000000 1000000000 结果 3.142348 3.141209 3.141371 3.141530 精度 3位 4位 4位 5位
#include #include #include #include <ctime> <stdio.h> <cstdlib> <math.h>
1
2 dx估计π 值,给出不同 1‾‾‾‾ − x‾ √‾
#define N 1000000 void HitorMiss() { double x,y,f_x; int i,k=0; for(i=0;i<N;i++) { x = (double)rand()/(double)(RAND_MAX); y = (double)rand()/(double)(RAND_MAX); f_x = sqrt(1-x*x); if(y<f_x) k++; } printf("%6f\n",4*(double)k/N); }
EX3
设 a, b, c和 d是实数,且 a ≤ b, c ≤ d, f:[a, b] → [c,d]是一个连续函数,写一概率算法计算 积分 ∫a
b
f (x)dx
注意,函数的参数是 a, b, c, d, n和 f, 其中 f用函数指针实现,请选一连续函数做实验,并给 出实验结果。
实验代码
#include <ctime> #include <iostream> #include <cstdlib> #include<math.h> using namespace std; /*MC积分函数*/ void MC(double a,double b ,double c ,double d,double (*func)(double)); /*测试函数1*/ double test1(double x); /*测试函数2*/ double test2(double x); int main() { srand(time(NULL)); MC(0,4,-1,8,test1);