使用搜索算法实现罗马尼亚问题的求解

使用搜索算法实现罗马尼亚问题的求解

#include<iostream>
#include<stack>
#include<queue>
#include<fstream>
using namespace std;
struct node{
	int city;
	int cost;
	node(){
	}
	node(int mcity,int mcost){
		city=mcity;
		cost=mcost;
	}
	bool operator >(const node &s)const{
		return cost<s.cost;//最小值优先 
	}
	bool operator <(const node &s)const{
		return cost>s.cost;//最小值优先 
	}
	bool operator ==(const node &s)const{
		return cost==s.cost;//最小值优先 
	}
}; 
int depth=1,iter=1;		//标记位,如果搜索到了目标城市,则终止,无需搜索全部路径 
int sum=0,num=0;		//记录代价值  
void BFS(int begin,int start1,int *sign,int father[],int finish,string city[],int street[][20])
{
	queue<int> Q;
	cout<<"宽度优先搜索的路径为:"<<city[begin];
	for(int i=0;i<20;i++)		//扩展可以扩展的结点,并加入队列依次扩展 
	if(street[begin][i]>0)
	{
		if(sign[i]==0)
		{
			sign[i]=1;
			Q.push(i);
			father[i]=begin;		//更新父结点的值 
		}
	}
	while(!Q.empty())		//循环扩展,直到所有结点都被扩展 
	{
		int x=Q.front();
		Q.pop();
		if(x==finish)
		{
			stack<int> temp1;
			int tmp=12;
			while(tmp!=2)
			{
				temp1.push(tmp);
				tmp=father[tmp];		//依据父结点,递推倒序输出即为路径 
				 
			}
			int n=0;
			int t=0;
			while(!temp1.empty()){
				cout<<"->"<<city[temp1.top()];
				if(n==0){
				sum+=street[start1][temp1.top()];
				n++;
				t=temp1.top();
			}
			else{
				sum+=street[t][temp1.top()];
				t=temp1.top();
			}
				temp1.pop();
			}
			cout<<endl<<"路径耗散为:"<<sum<<endl;
			cout<<"时间复杂度为:"<<num<<endl;	
			break;
		}
		for(int i=0;i<20;i++)
		if(street[x][i]>0)
		{
			if(sign[i]==0)
			{
				num++;
				sign[i]=1;
				Q.push(i); 
				father[i]=x;
			}
		}
	}
}
void DFS(int start,int start1,stack<int> temp,int *sign,int finish,string city[],int street[][20])
{ 
	if(start==finish)		//如果搜到了目标 
	{
		depth=0;
		cout<<"深度优先的路径为:";
		stack<int> temp1;
		while(!temp.empty())
		{
			temp1.push(temp.top());
			temp.pop();
		}
		cout<<city[start1];
		int n=0;
		int t=0;
		while(!temp1.empty())
		{		
			cout<<"->"<<city[temp1.top()];
			if(n==0){
				sum+=street[start1][temp1.top()];
				n++;
				t=temp1.top();
			}
			else{
				sum+=street[t][temp1.top()];
				t=temp1.top();
			}
			temp1.pop();
		}
        cout<<endl;
        cout<<"路径耗散为:"<<sum<<endl;
        cout<<"时间复杂度为:"<<num<<endl; 
		return;
	}
	for(int i=0;i<20;i++)		//找到可以扩展的结点,并递归扩展 
	{
		if(street[start][i]>0 &&depth)
		{
			temp.push(i);
			if(sign[i]==0)
			{
				num++; 
				sign[i]=1;
				DFS(i,start1,temp,sign,finish,city,street);
				sign[i]=0;
			}
			temp.pop();
		}
	}
}
 
void IDS(int start,int start1,stack<int> temp,int *sign,int deep,int now,int finish,string city[],int street[][20])
{
	sign[start]=1;
	if(start==finish)		//如果搜到了目标,停止搜索,计算代价和路径 
	{
		iter=0;
		cout<<"迭代加深的深度优先搜索路径为:";
		stack<int> temp1;
		while(!temp.empty())
		{
			temp1.push(temp.top());
			temp.pop();
		}
		cout<<city[start1];
		int n=0;
		int t=0;
		while(!temp1.empty())
		{		
			cout<<"->"<<city[temp1.top()];
			if(n==0){
				sum+=street[start1][temp1.top()];
				n++;
				t=temp1.top();
			}
			else{
				sum+=street[t][temp1.top()];
				t=temp1.top();
			}
			temp1.pop();
		}
        cout<<endl;
        cout<<"路径耗散为:"<<sum<<endl;
        cout<<"时间复杂度为:"<<num<<endl;
		return;
	}
	for(int i=0;i<20;i++)		//如果找到了可以扩展的结点,那么扩展它 
	{
		if(street[start][i]>0&&iter)
		{
			temp.push(i);
			if(sign[i]==0)
			{
				sign[i]=1;
				if(now<deep)		//如果还没有超过深度限制,那么可以继续递归下一层 
				{
					num++;
					now++;
					IDS(i,start1,temp,sign,deep,now,finish,city,street);
					now--;
				}
				sign[i]=0;
			}
			temp.pop();
		}
	}
}
 


void UCS(int begin,int start1,int *sign,int father[],int finish,string city[],int street[][20],int gred[])
{
	priority_queue<node>Q;
	int s,c;
	cout<<"一致代价搜索路径为:"<<city[begin];
	for(int i=0;i<20;i++)		//扩展可以扩展的结点,并加入队列依次扩展 
	if(street[begin][i]>0)
	{
		if(sign[i]==0)
		{
			sign[i]=1;
			Q.push(node(i,street[begin][i]));
			father[i]=begin;		//更新父结点的值 
		}
	}
	while(!Q.empty())		//循环扩展,直到所有结点都被扩展 
	{
		struct node Node;
		Node=Q.top();
		Q.pop();
		if(Node.city==finish)
		{
			stack<int> temp1;
			int tmp=12;
			while(tmp!=2)
			{
				temp1.push(tmp);
				tmp=father[tmp];		//依据父结点,递推倒序输出即为路径 
				 
			}
			int n=0;
			int t=0;
			while(!temp1.empty()){
				cout<<"->"<<city[temp1.top()];
				if(n==0){
				sum+=street[start1][temp1.top()];
				n++;
				t=temp1.top();
			}
			else{
				sum+=street[t][temp1.top()];
				t=temp1.top();
			}
				temp1.pop();
			}
			cout<<endl<<"路径耗散为:"<<sum<<endl;	
			cout<<"时间复杂度为:"<<num<<endl;
			break;
		}
		for(int i=0;i<20;i++)
		if(street[Node.city][i]>0)
		{
			if(sign[i]==0)
			{
				num++;
				sign[i]=1;
				Q.push(node(i,street[Node.city][i]+Node.cost)); 
				if(i==finish)
				sign[i]=0;
				father[i]=Node.city;
			}
		}
	}
}
void GBS(int begin,int start1,int *sign,int father[],int finish,string city[],int street[][20],int gred[])
{
	priority_queue<node>Q;
	int s,c;
	cout<<"贪婪最佳搜索路径为:"<<city[begin];
	for(int i=0;i<20;i++)		//扩展可以扩展的结点,并加入队列依次扩展 
	if(street[begin][i]>0)
	{
		if(sign[i]==0)
		{
			sign[i]=1;
			Q.push(node(i,gred[i]));
			father[i]=begin;		//更新父结点的值 
		}
	}
	while(!Q.empty())		//循环扩展,直到所有结点都被扩展 
	{
		struct node Node;
		Node=Q.top();
		Q.pop();
		if(Node.city==finish)
		{
			stack<int> temp1;
			int tmp=12;
			while(tmp!=2)
			{
				temp1.push(tmp);
				tmp=father[tmp];		//依据父结点,递推倒序输出即为路径 
				 
			}
			int n=0;
			int t=0;
			while(!temp1.empty()){
				cout<<"->"<<city[temp1.top()];
				if(n==0){
				sum+=street[start1][temp1.top()];
				n++;
				t=temp1.top();
			}
			else{
				sum+=street[t][temp1.top()];
				t=temp1.top();
			}
				temp1.pop();
			}
			cout<<endl<<"路径耗散为:"<<sum<<endl;
			cout<<"时间复杂度为:"<<num<<endl;	
			break;
		}
		for(int i=0;i<20;i++)
		if(street[Node.city][i]>0)
		{
			if(sign[i]==0)
			{
				num++;
				sign[i]=1;
				Q.push(node(i,gred[i])); 
				//if(i==finish)
				//sign[i]=0;
				father[i]=Node.city;
			}
		}
	}
} 
void ASS(int begin,int start1,int *sign,int father[],int finish,string city[],int street[][20],int gred[])
{
	priority_queue<node>Q;
	int s,c;
	cout<<"A*搜索路径为:"<<city[begin];
	for(int i=0;i<20;i++)		//扩展可以扩展的结点,并加入队列依次扩展 
	if(street[begin][i]>0)
	{
		if(sign[i]==0)
		{
			sign[i]=1;
			Q.push(node(i,gred[i]+street[begin][i]));
			father[i]=begin;		//更新父结点的值 
		}
	}
	while(!Q.empty())		//循环扩展,直到所有结点都被扩展 
	{
		struct node Node;
		Node=Q.top();
		Q.pop();
		if(Node.city==finish)
		{
			stack<int> temp1;
			int tmp=12;
			while(tmp!=2)
			{
				temp1.push(tmp);
				tmp=father[tmp];		//依据父结点,递推倒序输出即为路径 
				 
			}
			int n=0;
			int t=0;
			while(!temp1.empty()){
				cout<<"->"<<city[temp1.top()];
				if(n==0){
				sum+=street[start1][temp1.top()];
				n++;
				t=temp1.top();
			}
			else{
				sum+=street[t][temp1.top()];
				t=temp1.top();
			}
				temp1.pop();
			}
			cout<<endl<<"路径耗散为:"<<sum<<endl;
			cout<<"时间复杂度为:"<<num<<endl;	
			break;
		}
		for(int i=0;i<20;i++)
		if(street[Node.city][i]>0)
		{
			if(sign[i]==0)
			{
				num++;
				sign[i]=1;
				Q.push(node(i,gred[i]+street[Node.city][i]+Node.cost)); 
				if(i==finish)
				sign[i]=0;
				father[i]=Node.city;
			}
		}
	}
}  
int main()
{
	ifstream ff("1.txt");
	string city[20];//城市名 
	for(int i=0;i<20;i++){
		ff>>city[i];
	} 
	int street[20][20];//路径 
	for(int i=0;i<20;i++){
		for(int j=0;j<20;j++){
			ff>>street[i][j];
		}
	} 
	int gred[20];//启发式 
	for(int i=0;i<20;i++){
		ff>>gred[i];
	}
	ff.close();
	int start,finish;		//起始城市为Ared,终止城市为Bucharest
	cout<<"请输入开始城市和结束城市,当前题目开始城市为2,结束城市为12"<<endl;
	cin>>start>>finish;
	int a;
	cout<<"请选择搜索方法1~6"<<endl;
	while(1){
		cin>>a;
		sum=0,num=0;
    	stack<int> p;
    	int father[20]={0}; 
    	int sign[20]={0};
    	int deep=0;
    	//当前结点已经访问,避免死循环
		switch(a){
			case 1:sign[start]=1;BFS(start,start,sign,father,finish,city,street);break;
			case 2:sign[start]=1;DFS(start,start,p,sign,finish,city,street);break;
			case 3:sign[start]=1;UCS(start,start,sign,father,finish,city,street,gred);break;
			case 4:
    while(iter) 
	{
    	deep++;
    	stack<int> ptemp;
    	int sign_temp[20]={0};
    	sign_temp[start]=1;
    	IDS(start,start,ptemp,sign_temp,deep,0,finish,city,street);
	}
	break;
		case 5:sign[start]=1;GBS(start,start,sign,father,finish,city,street,gred);break;
		case 6:sign[start]=1;ASS(start,start,sign,father,finish,city,street,gred);break;
		default:cout<<"error"<<endl;break;
	}
	}
	return 0;
}

1:宽度优先搜索,深度优先搜索,一致代价搜索,迭代加深的深度优先搜索算法哪种方法最 优?一致代价是最优的,因为它拓展的是路径消耗 g(n)最小的结点 n.而深度优先的搜索算法,当 一条路径找到解就不会执行了,这种情况下找到解可能会非常糟糕,而宽度优先搜索和迭代 加深的深度优先搜索算法找到的是最浅深度的解,没有对代价大小进行比较,所以也不是最 优的。
2:贪婪最佳优先搜索和 A搜索那种方法最优? A搜索算法是最优的。这两种算法都是有信息的搜索。贪婪最佳优先算法试图拓展离目标最 近的结点,它只用启发式信息 f(n)=h(n),它与深度优先算法类似,找到的不一定是最优的。而 A*算法,它对结点的评价结合了 g(n)和 h(n),f(n)=g(n)+h(n)经过结点 n 的最小代价解的估计代 价。满足一致性和可采纳性所以是最优的。
3:分析比较无信息搜索策略和有信息搜索策略。 无信息搜索算法是指算法除了问题本身定义没有任何其他信息,有信息搜索算法是指利用给 定的知识引导能够更有效的找到解。无信息是不包含启发式,有信息包含了启发式

发布了32 篇原创文章 · 获赞 25 · 访问量 4121

猜你喜欢

转载自blog.csdn.net/weixin_44143695/article/details/103228802