算法作业代码
2016-01-16 23:24
309 查看
Exercise 1;
Exercise 2:
Exercise 3:
Exercise9:
#include<iostream>
#include<math.h>
#include<time.h>//随机函数的种子
using namespace std;
#define AVG 200//产生200个正确的解,然后再统计相关数据
int failure = 0; //算法运行失败的次数
int success = 0; //算法运行成功的次数
int nsnode = 0; //一次成功搜索访问的结点数
int nfnode = 0; //一次不成功搜索访问的结点数
int tempLVNode = 0;
int tempBackNode = 0;
class RandomNumber
{
public: int Random(int n)
{
//生成0 ~ n-1之间的随机整数,n不大于32767
if (n>32767)
{
cout << "您输入的n值不能大于32767" << endl;
exit(-1);
}
int x;
x = rand();
return x%n;
}
};
class Queen
{
friend void nQueen(int n, int stopVegas);
public:
Queen(int n);
bool Place(int k); //测试皇后k置于第x[k]列的合法性, 注意:x[k]的值可以取从1到n
bool Backtrack(int t); //解n后问题的回溯法
bool QueensLV(int stopVegas); //随机放置stopVegas个皇后的LV算法
int n, *x, *y; //x,y 是解向量
};
Queen::Queen(int m)
{
n = m;
}
bool Queen::Place(int k)
{
for (int j = 1; j<k; j++)
{
if ((abs(k - j) == abs(x[k] - x[j])) || (x[j] == x[k]))
return false;
}
return true;
}
bool Queen::Backtrack(int t)
{
if (t>n)
{
for (int i = 1; i <= n; i++)
y[i] = x[i];
return true;
}
else
{
for (int i = 1; i <= n; i++)
{
x[t] = i;
if (Place(t) && Backtrack(t + 1)) //要理解回溯法的精髓
{
tempBackNode++;
return true;
}
}
}
tempBackNode++;//某皇后放置失败
return false;
}
bool Queen::QueensLV(int stopVegas)
{
RandomNumber rnd; //随机数生成器
int k = 1; //从第1个皇后开始放置
int count = 1;
tempLVNode = 0;
while ((k <= stopVegas) && (count>0))
{
count = 0;
for (int i = 1; i <= n; i++)
{
x[k] = i;
//tempLVNode++;
if (Place(k))
y[count++] = i; //数组y中存放的是放置皇后k,可用的列号,以便于等会随机选择第k个皇后的位置
}
if (count>0)
{
//皇后k可以找到一个随机放置的位置
int r = rnd.Random(count);
x[k++] = y[r]; //随机选择一列放置皇后k,然后k++,继续while循环
tempLVNode++;
}
else
{
//皇后k找不到随机放置的位置,QueensLv算法失败
}
}
return (count>0); //表示放置成功
}
void nQueen(int n, int stopVegas)
{
Queen X(n);
//初始化X
int *p = new int[n + 1];
int *q = new int[n + 1];
for (int i = 0; i <= n; i++)
{
p[i] = 0;
q[i] = 0;
}
X.x = q;
X.y = p;
failure = 0; //算法运行失败的次数
success = 0; //算法运行成功的次数
nsnode = 0; //一次成功搜索访问的结点数
nfnode = 0; //一次不成功搜索访问的结点数
while (1)
{
while (1)
{
if (!X.QueensLV(stopVegas)) //说明随机放置部分算法失败
{
nfnode += tempLVNode;
//nsnode+=tempLVNode;
failure++;
//cout<<"LV搜索失败,算法重新搜索...."<<endl;
}
else
{
//随机放置部分算法成功,但还不能保证整个算法运行成功,还要看回溯部分是否成功,才能确定算法成功
//cout<<"LV随机放置完毕"<<endl;
break; //推出while循环,开始回溯
}
}//while.....LV的循环搜索,直到成功为止
//算法回溯部分
//cout<<"开始回溯..."<<endl;
tempBackNode = 0;
if (X.Backtrack(stopVegas + 1))
{
//回溯搜索成功
//cout<<"回溯成功,"<<n<<"皇后问题找到正确解。"<<endl;
nsnode += tempLVNode;//LV算法部分搜索的结点数也要算在其内
nsnode += tempBackNode;
success++;
if (success >= AVG)
break;
}
else
{
//回溯部分搜索失败,这也是由随机放置皇后的算法运行的结果导致的失败
failure++;
nfnode += tempLVNode;
nfnode += tempBackNode;
//cout<<"回溯失败!!"<<endl;
}
}//while.....LV成功后,若回溯失败,则继续循环搜索,直到成功AVG次为止,然后求平均值
}
int main()
{
int n, stopVegas, Beststop;
float p, s, e, t;
float tArray[21];
srand(time(0));//为随机数的生成选定种子
/***********实现结果向文件中输出**********************/
FILE *fp; //声明文件指针
fp = fopen("result.txt", "a+");//新建文件,文件名自定,保存路径自定注意/必须为//转义字符
if (!fp)
{
printf("File Open ERROR!");
exit(-1);
}
for (n = 8; n <= 20; n++)
{
fprintf(fp, "\nstopVegas\tp\t\ts\t\te/t\tt\n");
for (stopVegas = 0; stopVegas <= n; stopVegas++)
{
nQueen(n, stopVegas);
p = (float)success / (success + failure);
s = (float)nsnode / success; //一次 成功搜索访问的结点数平均值s
if (failure == 0) //一次不成功搜索访问的结点数平均值e
{
e = 0;
}
else
{
e = (float)nfnode / failure;
}
tArray[stopVegas] = s + ((1 - p)*e) / p; //反复调用算法使得最终找到一个解所访问的结点数的平均 值t
fprintf(fp, "\n%d\t\t%f\t%f\t%f\t%f\n", stopVegas, p, s, e, tArray[stopVegas]);
}
//找出t值最小的stopVegas值
t = tArray[0];
for (int m = 1; m <= n; m++)
{
if (tArray[m]<t)
{
t = tArray[m];
Beststop = m;
}
}
c
4000
out << "n=" << n << "," << "stopVegas=" << Beststop << "时,算法效率很高。" << endl;
fprintf(fp, "/n当n=%d时,取stopVegas=%d时,算法效率很高/n", n, Beststop); //文件输出结果
}
fclose(fp);
return 1;
}
Exercise10:
#include <iostream> #include<stdlib.h> #include<time.h> using namespace std; double darts(int n); int main() { clock_t start, finish; int n[3] = {10000000, 100000000, 1000000000}; for(int i=0; i<3; i++) { start = clock(); cout << "n = " << n[i] << " Pi = " << darts(n[i]); finish = clock(); cout << " Running time: " << finish-start << "ms" << endl; } return 0; } double darts(int n) { int k=0; for(int i=0; i<n; i++) { double x=rand()/double(RAND_MAX); //double y=rand()/double(RAND_MAX); double y=x; if(x*x+y*y<=1) k++; } return 4.0*k/n; }
Exercise 2:
#include <iostream> #include <stdlib.h> #include <math.h> #include <time.h> using namespace std; double func(double x); double HitorMiss(double (*func_ptr)(double), int n); int main() { clock_t start, finish; srand(unsigned(time(NULL))); double (*fun)(double); fun = func; int n[3] = {10000000, 100000000, 1000000000}; for(int i=0; i<3; i++) { start = clock(); cout << "n = " << n[i] << " Pi = " << HitorMiss(fun, n[i]); finish = clock(); cout << " Running time: " << finish-start <<endl; } return 0; } double func(double x) { double r; if(x>1 || x<0) cout << "x is out of range!!!" <<endl; r = 1 - x * x; return sqrt(r); } double HitorMiss(double (*func_ptr)(double), int n) { int k = 0; for(int i=0; i<n; i++) { double x = rand()/double(RAND_MAX); double y = rand()/double(RAND_MAX); if(y < func_ptr(x)) k++; } return 4.0*k/n; }
Exercise 3:
#include <iostream> #include <stdlib.h> #include <math.h> #include <time.h> using namespace std; double func(double x); double Integral(double (*func_ptr)(double), double a, double b, double c, double d, int n); int main() { clock_t start, finish; srand(unsigned(time(NULL))); double (*fun)(double); fun = func; int n[3] = {1000000, 10000000, 100000000}; double a = 0; double b = 1; double c = 1; double d = 5; for(int i=0; i<3; i++) { start = clock(); cout << "n = " << n[i] << " Pi = " << Integral(fun, a, b, c, d, n[i]); finish = clock(); cout << " Running time: " << finish-start <<endl; } return 0; } double func(double x) { double r; r = 3*x*x + 2*x + 1; return r; } double Integral(double (*func_ptr)(double), double a, double b, double c, double d, int n) { int k = 0; double r; for(int i=0; i<n; i++) { double x = rand()/double(RAND_MAX); double y = 1 + 4.0 * rand()/double(RAND_MAX); if(y < func_ptr(x)) k++; } r = 1.0 * k/n * (d - c) * (b - a) + c * (b - a); return r; }
Exercise9:
#include<iostream>
#include<math.h>
#include<time.h>//随机函数的种子
using namespace std;
#define AVG 200//产生200个正确的解,然后再统计相关数据
int failure = 0; //算法运行失败的次数
int success = 0; //算法运行成功的次数
int nsnode = 0; //一次成功搜索访问的结点数
int nfnode = 0; //一次不成功搜索访问的结点数
int tempLVNode = 0;
int tempBackNode = 0;
class RandomNumber
{
public: int Random(int n)
{
//生成0 ~ n-1之间的随机整数,n不大于32767
if (n>32767)
{
cout << "您输入的n值不能大于32767" << endl;
exit(-1);
}
int x;
x = rand();
return x%n;
}
};
class Queen
{
friend void nQueen(int n, int stopVegas);
public:
Queen(int n);
bool Place(int k); //测试皇后k置于第x[k]列的合法性, 注意:x[k]的值可以取从1到n
bool Backtrack(int t); //解n后问题的回溯法
bool QueensLV(int stopVegas); //随机放置stopVegas个皇后的LV算法
int n, *x, *y; //x,y 是解向量
};
Queen::Queen(int m)
{
n = m;
}
bool Queen::Place(int k)
{
for (int j = 1; j<k; j++)
{
if ((abs(k - j) == abs(x[k] - x[j])) || (x[j] == x[k]))
return false;
}
return true;
}
bool Queen::Backtrack(int t)
{
if (t>n)
{
for (int i = 1; i <= n; i++)
y[i] = x[i];
return true;
}
else
{
for (int i = 1; i <= n; i++)
{
x[t] = i;
if (Place(t) && Backtrack(t + 1)) //要理解回溯法的精髓
{
tempBackNode++;
return true;
}
}
}
tempBackNode++;//某皇后放置失败
return false;
}
bool Queen::QueensLV(int stopVegas)
{
RandomNumber rnd; //随机数生成器
int k = 1; //从第1个皇后开始放置
int count = 1;
tempLVNode = 0;
while ((k <= stopVegas) && (count>0))
{
count = 0;
for (int i = 1; i <= n; i++)
{
x[k] = i;
//tempLVNode++;
if (Place(k))
y[count++] = i; //数组y中存放的是放置皇后k,可用的列号,以便于等会随机选择第k个皇后的位置
}
if (count>0)
{
//皇后k可以找到一个随机放置的位置
int r = rnd.Random(count);
x[k++] = y[r]; //随机选择一列放置皇后k,然后k++,继续while循环
tempLVNode++;
}
else
{
//皇后k找不到随机放置的位置,QueensLv算法失败
}
}
return (count>0); //表示放置成功
}
void nQueen(int n, int stopVegas)
{
Queen X(n);
//初始化X
int *p = new int[n + 1];
int *q = new int[n + 1];
for (int i = 0; i <= n; i++)
{
p[i] = 0;
q[i] = 0;
}
X.x = q;
X.y = p;
failure = 0; //算法运行失败的次数
success = 0; //算法运行成功的次数
nsnode = 0; //一次成功搜索访问的结点数
nfnode = 0; //一次不成功搜索访问的结点数
while (1)
{
while (1)
{
if (!X.QueensLV(stopVegas)) //说明随机放置部分算法失败
{
nfnode += tempLVNode;
//nsnode+=tempLVNode;
failure++;
//cout<<"LV搜索失败,算法重新搜索...."<<endl;
}
else
{
//随机放置部分算法成功,但还不能保证整个算法运行成功,还要看回溯部分是否成功,才能确定算法成功
//cout<<"LV随机放置完毕"<<endl;
break; //推出while循环,开始回溯
}
}//while.....LV的循环搜索,直到成功为止
//算法回溯部分
//cout<<"开始回溯..."<<endl;
tempBackNode = 0;
if (X.Backtrack(stopVegas + 1))
{
//回溯搜索成功
//cout<<"回溯成功,"<<n<<"皇后问题找到正确解。"<<endl;
nsnode += tempLVNode;//LV算法部分搜索的结点数也要算在其内
nsnode += tempBackNode;
success++;
if (success >= AVG)
break;
}
else
{
//回溯部分搜索失败,这也是由随机放置皇后的算法运行的结果导致的失败
failure++;
nfnode += tempLVNode;
nfnode += tempBackNode;
//cout<<"回溯失败!!"<<endl;
}
}//while.....LV成功后,若回溯失败,则继续循环搜索,直到成功AVG次为止,然后求平均值
}
int main()
{
int n, stopVegas, Beststop;
float p, s, e, t;
float tArray[21];
srand(time(0));//为随机数的生成选定种子
/***********实现结果向文件中输出**********************/
FILE *fp; //声明文件指针
fp = fopen("result.txt", "a+");//新建文件,文件名自定,保存路径自定注意/必须为//转义字符
if (!fp)
{
printf("File Open ERROR!");
exit(-1);
}
for (n = 8; n <= 20; n++)
{
fprintf(fp, "\nstopVegas\tp\t\ts\t\te/t\tt\n");
for (stopVegas = 0; stopVegas <= n; stopVegas++)
{
nQueen(n, stopVegas);
p = (float)success / (success + failure);
s = (float)nsnode / success; //一次 成功搜索访问的结点数平均值s
if (failure == 0) //一次不成功搜索访问的结点数平均值e
{
e = 0;
}
else
{
e = (float)nfnode / failure;
}
tArray[stopVegas] = s + ((1 - p)*e) / p; //反复调用算法使得最终找到一个解所访问的结点数的平均 值t
fprintf(fp, "\n%d\t\t%f\t%f\t%f\t%f\n", stopVegas, p, s, e, tArray[stopVegas]);
}
//找出t值最小的stopVegas值
t = tArray[0];
for (int m = 1; m <= n; m++)
{
if (tArray[m]<t)
{
t = tArray[m];
Beststop = m;
}
}
c
4000
out << "n=" << n << "," << "stopVegas=" << Beststop << "时,算法效率很高。" << endl;
fprintf(fp, "/n当n=%d时,取stopVegas=%d时,算法效率很高/n", n, Beststop); //文件输出结果
}
fclose(fp);
return 1;
}
Exercise10:
#include<iostream> #include<cmath> #include<random> #include<ctime> using namespace std; bool isprime(int n); bool Btest(int a, int n); bool MillRab(int n); bool RepeatMillRab(int n, int k); int PrintPrimes(); int ModularExponent(int a, int j, int p);//get s=a^j (mod p) int main() { int Naive_Count=1, MC_Count; for (int n = 3; n < 10000; n = n + 2) { if (isprime(n)) { cout << n << " "; Naive_Count++; } } MC_Count = PrintPrimes(); cout << "100 ~ 10000之之间素数个数:" << endl; cout << "朴素算法:" << Naive_Count-25 << endl;//100以内素数个数为25 cout << "MC概率算法:" << MC_Count-25 << endl; cout << endl; return 0; } bool isprime(int n) { for (int i = 2; i*i < n+1; i++) if (n%i == 0) return false; return true; } int PrintPrimes() { int count = 2; //cout << 2 << " " << 3 << " "; int n = 5; do { int k = floor(log2(n)); if (RepeatMillRab(n, k)) { //cout << n << " "; count++; } n = n + 2; } while (n<10000); return count; } bool RepeatMillRab(int n, int k) { for (int i = 1; i < k + 1; i++) { if (MillRab(n) == false) return false; } return true; } bool MillRab(int n) { srand(unsigned(time(0))); int a = 2 + rand() % (n - 3); return Btest(a, n); } bool Btest(int a, int n) { int s = 0; int t = n - 1; do { s++; t = t / 2; } while (t % 2 == 0); int x = ModularExponent(a, t, n); if (x == 1 || x == n - 1) return true; for (int i = 1; i < s; i++) { x = (x*x) % n; if (x == n - 1) return true; } return false; } int ModularExponent(int a, int j, int p) { int s = 1; while (j>0) { if (j % 2 == 1) s = (s*a) % p; a = (a*a) % p; j = j / 2; } return s; }
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析