一、实验目的
1.了解4种无信息搜索策略和2种有信息搜索策略的算法思想;
2.能够运用计算机语言实现搜索算法;
3.应用搜索算法解决实际问题(如罗马尼亚问题);
4.学会对算法性能的分析和比较
二、实验的硬件、软件平台
硬件:计算机
软件:操作系统:WINDOWS 2000
应用软件:C,Java或者MATLAB
三、实验内容及步骤
使用搜索算法实现罗马尼亚问题的求解
1:创建搜索树;
2:实现搜索树的宽度优先搜索,深度优先搜索,一致代价搜索,迭代加深的深度优先搜索算法;
3:实现贪婪最佳优先搜索和A*搜索
4:使用编写的搜索算法代码求解罗马尼亚问题;
5:记录各种算法的时间复杂度并绘制直方图
四 问题求解
地图的存储:
ARad Timiisoara 118
ARad Zerind 75
ARad Sibiu 140
Timiisoara Lugoj 111
Zerind Oradea 71
Sibiu Fagaras 99
Sibiu Rimnicu_Vilcea 80
Oradea Sibiu 151
Lugoj Mehadia 70
Mehadia Dobreta 75
Dobreta Craiova 120
Rimnicu_Vilcea Craiova 146
Rimnicu_Vilcea Pitesti 97
Craiova Pitesti 138
Pitesti Bucharest 101
Fagaras Bucharest 211
Bucharest Giurgiu 90
Bucharest Urziceni 85
Urziceni Hirsova 98
Urziceni Vaslui 142
Vaslui lasi 92
lasi Neamt 87
Hirsova Eforie 80
节点的评估值:
ARad 366
Mehadia 241
Bucharest 0
Neamt 234
Craiova 160
Oradea 380
Dobreta 242
Pitesti 100
Eforie 161
Rimnicu_Vilcea 193
Fagaras 176
Sibiu 253
Giurgiu 77
Timiisoara 329
Hirsova 151
Urziceni 80
lasi 226
Vaslui 199
Lugoj 244
Zerind 374
变量定义
bool mark[num]; //标记节点是否被访问
int edge[num][num]; //地图
int fat[num]; //暂存父节点
int fx[num]; //节点的评估值数组
ifstream input; //输入文件
map<string,int>city_id; //城市名到城市编号的转换
map<int,string>id_city; //城市编号到城市名的转换
string Start; //开始城市
string End; //结束城市
struct city_node{ //城市节点
int id; //节点编号
int g; //耗费值
int f; //f = g + h
int dep; //节点的深度
friend bool operator > (const city_node& c1, const city_node& c2){ //自定义优先级,f越小,优先级越高
return c1.f > c2.f;
}
};
宽度优先
int BFS(){ //宽度优先搜索
memset(mark,0,sizeof(mark));
city_node q[num*4];
for(int x=0;x<num;x++) fat[x]=x;
int l=0,r=1,sum=0;
q[l].id = city_id[Start];
q[l].g = 0;
while(l<r){
city_node temp = q[l];
sum++;
if(temp.id==city_id[End]){
print_path(temp.id);
cout<<" 总代价为:"<<q[l].g<<endl;
break;
}
mark[temp.id]=1;
for(int x=0;x<num;x++){
if(!mark[x]&&edge[temp.id][x]!=0){
q[r].id = x;
q[r].g = temp.g + edge[temp.id][x];
fat[q[r].id] = temp.id;
r++;
}
}
l++;
}
return sum;
}
深度优先
int DFS(){ //深度优先搜索
stack<city_node>s;
memset(mark,0,sizeof(mark));
for(int x=0;x<num;x++) fat[x]=x;
int sum=0;
city_node start;
start.id = city_id[Start];
start.g = 0;
s.push(start);
while(!s.empty()){
city_node temp = s.top();
sum++;
if(temp.id == city_id[End]){
print_path(temp.id);
cout<<" 总代价为:"<<temp.g<<endl;
break;
}
mark[temp.id] = 1;
int x=0;
for(;x<num;x++){
if(!mark[x]&&edge[temp.id][x]!=0){
city_node t;
t.id = x;
t.g = temp.g + edge[temp.id][x];
fat[t.id] = temp.id;
s.push(t);
break;
}
}
if(x==num)
s.pop();
}
return sum;
}
一致代价
int UCS(){ //一致代价搜索
memset(mark,0,sizeof(mark));
for(int x=0;x<num;x++) fat[x]=x;
int sum = 0;
city_node start;
start.g = 0;
start.f = 0;
start.id = city_id[Start];
priority_queue<city_node, vector<city_node>, greater<city_node> >p;
p.push(start);
while(!p.empty()){
sum++;
city_node temp = p.top();
if(temp.id==city_id[End]){
print_path(temp.id);
cout<<" 总代价为:"<<p.top().g<<endl;
break;
}
mark[temp.id]=1;
p.pop();
for(int x=0;x<num;x++){
if(!mark[x]&&edge[temp.id][x]!=0){
city_node t;
t.id = x;
t.g = temp.g + edge[temp.id][x];
t.f = t.g;
fat[t.id] = temp.id;
p.push(t);
}
}
}
return sum;
}
迭代加深的深度优先搜索
int IDS(){ //迭代加深的深度优先搜索
memset(mark,0,sizeof(mark));
for(int x=0;x<num;x++) fat[x] = x;
int sum = 0, cur_dep = 1, maxdep = 12;
city_node start;
start.id = city_id[Start];
start.g = 0;
start.dep = 0;
stack<city_node>s;
s.push(start);
while(!s.empty()){
city_node temp = s.top();
sum++;
if(cur_dep > maxdep) return sum;
if(temp.id == city_id[End]){
print_path(temp.id);
cout<<" 总代价为:"<<temp.g<<endl;
break;
}
mark[temp.id] = 1;
int x=0;
for(;x<num;x++){
if(!mark[x]&&edge[temp.id][x]!=0&&temp.dep <= cur_dep){
city_node t;
t.id = x;
t.g = temp.g + edge[temp.id][x];
fat[t.id] = temp.id;
t.dep = temp.dep + 1;
s.push(t);
break;
}
}
if(x==num)
s.pop();
if(s.empty()){
memset(mark,0,sizeof(mark));
s.push(start);
cur_dep++;
}
}
return sum;
}
贪婪最佳优先搜索
int GBFS(){ //贪婪最佳优先搜索
memset(mark,0,sizeof(mark));
for(int x=0;x<num;x++) fat[x]=x;
city_node start;
start.id = city_id[Start];
start.g = 0;
start.f = fx[start.id];
priority_queue<city_node, vector<city_node>, greater<city_node> >p;
p.push(start);
int sum=0;
while(!p.empty()){
sum++;
city_node temp = p.top();
if(temp.id==city_id[End]){
print_path(temp.id);
cout<<" 总代价为:"<<p.top().g<<endl;
break;
}
mark[temp.id]=1;
p.pop();
for(int x=0;x<num;x++){
if(!mark[x]&&edge[temp.id][x]!=0){
city_node t;
t.id = x;
t.g = temp.g + edge[temp.id][x];
fat[t.id]=temp.id;
t.f = fx[t.id];
p.push(t);
}
}
}
return sum;
}
A*搜索
int AS(){ //A*搜索
memset(mark,0,sizeof(mark));
for(int x=0;x<num;x++) fat[x]=x;
int sum=0;
city_node start;
start.id = city_id[Start];
start.g = 0;
start.f = start.g + fx[start.id];
priority_queue<city_node, vector<city_node>, greater<city_node> >p;
p.push(start);
while(!p.empty()){
sum++;
city_node temp = p.top();
if(temp.id==city_id[End]){
print_path(temp.id);
cout<<" 总代价为:"<<p.top().g<<endl;
break;
}
mark[temp.id]=1;
p.pop();
for(int x=0;x<num;x++){
if(!mark[x]&&edge[temp.id][x]!=0){
city_node t;
t.id = x;
t.g = temp.g + edge[temp.id][x];
fat[t.id]=temp.id;
t.f = t.g + fx[t.id];
p.push(t);
}
}
}
return sum;
}
实验结果:
先用宽度优先搜索求出最优解:
我们发现最优值为418,再用6种算法求解。
我们发现:
只有2种算法可以求解最优解。
最优的算法为A*搜索。