算法作业代码

Exercise 1;

#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;
			}
		}
		cout << "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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值