A*算法罕用于 二维舆图途径布局Vff0c;算法所给取的启示式搜寻可以操做真际问题所具备的启示式信息来辅导搜寻Vff0c;从而减少搜寻领域Vff0c;控制搜寻范围Vff0c;降低真际问题的复纯度。
2.算法本理Vff1a;A*算法的本理是设想一个价钱预计函数Vff1a;此中
评价函数F(n)
界说Vff1a;从起始节点通过节点n的达到目的节点的最小价钱途径的预计值Vff1b;
做用Vff1a;依据 F(n)可以计较出当前节点的价钱Vff0c;并可以对下一次能够达到的节点停行评价。
函数G(n)
界说Vff1a;从起始节点到n节点的已走过途径的真际价钱Vff1b;
函数H(n)
界说Vff1a;从n节点到目的节点可能的最劣途径的预计价钱 。
做用Vff1a; H(n)讲明了算法运用的启示信息Vff0c;它起源于人们对途径布局问题的认识Vff0c;依赖某种经历预计。
给取每次搜寻都找到价钱值最小的点再继续往外搜寻的历程Vff0c;一步一步找到最劣途径。
3.评估
齐备性Vff1a;需价钱小于就是C*(最劣解途径的价钱值)的结点是有穷的Vff0c;每步价钱都赶过ε并且b是有穷的。
最劣性Vff1a;需满足可采用性Vff08;--树搜寻最劣Vff09;和一致性Vff08;图搜寻最劣Vff09;
4.可采用性取一致性可承受Vff1a; 应付任何形态nVff0c;满足h(n) ≤ h*(n)Vff0c; 此中h*(n)默示从n到目的形态的真际最小价钱。
留心Vff1a;下面的应该是小于就是Vff0c;而非小于Vff1b;
一致Vff1a; 应付任何形态n和其后继形态n'Vff0c;满足h(n) ≤ c(n, n') + h(n')Vff0c;此中c(n, n')默示从n到n'的真际价钱。
图搜寻Vff1a;不允许重复会见结点Vff0c;即OPEN表 ∩ CLOSED表 = øVff1b;
树搜寻Vff1a;允许重复会见结点。
举例Vff1a;Vff08;那也是2018年第二学期的期中检验题Vff09;
Vff08;1Vff09;题目问题觉得上面的图也有些瑕疵Vff0c;下面是笔者画的Vff1a;
题目问题Vff1a;罗马尼亚问题
agent正在罗马尼亚度假Vff0c;目前位于 Arad 都市。agent明天有航班从Bucharest 起飞Vff0c;不能改签退票。
如今你须要寻找到 Bucharest 的最短途径Vff0c;正在左侧编辑器补充ZZZoid A_star(int goal,node &src,Graph &graph)函数Vff0c;运用编写的搜寻算法代码求解罗马尼亚问题Vff1a;
预期输出Vff1a;
solution: 0-> 15-> 14-> 13-> 1-> end cost:418 1.创立搜寻树Vff1b; (1)给每个都市编号 #define A 0 #define B 1 #define C 2 #define D 3 #define E 4 #define F 5 #define G 6 #define H 7 #define I 8 #define L 9 #define M 10 #define N 11 #define O 12 #define P 13 #define R 14 #define S 15 #define T 16 #define U 17 #define x 18 #define Z 19 (2)启示函数--h数组赋值结点n距离起点的或许价钱Vff0c;给取曲线距离Vff1b;
int h[20] =//从n节点到目的节点可能的最劣途径的预计价钱 { 366,0,160,242,161, 178,77,151,226,244, 241,234,380,98,193, 253,329,80,199,374 }; (3)struct都市节点
每个结点保存其g(n)Vff0c;h(n)Vff0c;f(n)=g(n)+h(n)。
重载<Vff1a;每主要与出f(n)最小的结点Vff0c;便于对结点停行牌序。
struct node { int g; //从起始节点到n节点的已走过途径的真际价钱 int h; //从n节点到目的节点可能的最劣途径的预计价钱 int f; //价钱预计函数 int name; node(int name, int g, int h) { //结构函数 this->name = name; this->g = g; this->h = h; this->f = g + h; }; //重载运算符 bool operator <(const node& a)const { return f < a.f; } }; (4)class图 class Graph //图构造 { public: Graph() { memset(graph, -1, sizeof(graph)); //图初始化为-1Vff0c;代表无边 } int getEdge(int from, int to) { //获与边的开销 return graph[from][to]; } ZZZoid addEdge(int from, int to, int cost) { //新删一条边及其开销 if (from >= 20 || from < 0 || to >= 20 || to < 0) return; graph[from][to] = cost; } ZZZoid init() { //图初始化 addEdge(O, Z, 71); addEdge(Z, O, 71); addEdge(O, S, 151); addEdge(S, O, 151); addEdge(Z, A, 75); addEdge(A, Z, 75); addEdge(A, S, 140); addEdge(S, A, 140); addEdge(A, T, 118); addEdge(T, A, 118); addEdge(T, L, 111); addEdge(L, T, 111); addEdge(L, M, 70); addEdge(M, L, 70); addEdge(M, D, 75); addEdge(D, M, 75); addEdge(D, C, 120); addEdge(C, D, 120); addEdge(C, R, 146); addEdge(R, C, 146); addEdge(S, R, 80); addEdge(R, S, 80); addEdge(S, F, 99); addEdge(F, S, 99); addEdge(F, B, 211); addEdge(B, F, 211); addEdge(P, C, 138); addEdge(C, P, 138); addEdge(R, P, 97); addEdge(P, R, 97); addEdge(P, B, 101); addEdge(B, P, 101); addEdge(B, G, 90); addEdge(G, B, 90); addEdge(B, U, 85); addEdge(U, B, 85); addEdge(U, H, 98); addEdge(H, U, 98); addEdge(H, E, 86); addEdge(E, H, 86); addEdge(U, x, 142); addEdge(x, U, 142); addEdge(I, x, 92); addEdge(x, I, 92); addEdge(I, N, 87); addEdge(N, I, 87); } priZZZate: int graph[20][20]; //图数组Vff0c;用来保存图信息Vff0c;最多有20个节点 }; (5)其余队列、记录途径数组 bool list[20]; //记录节点能否正在当前队列中 ZZZector<node> openList; //扩展队列 bool closeList[20]; //记录节点能否被扩展Vff08;选择Vff09;过 stack<int> road; //记录途径 int parent[20]; //记录途径 (6)打印函数打印途径和开销Vff1a;ZZZoid print_result(Graph &graph)
ZZZoid print_result(Graph &graph) { int p = openList[0].name; int lastNodeNum; road.push(p); while (parent[p] != -1) { road.push(parent[p]); p = parent[p]; } lastNodeNum = road.top(); int cost = 0; cout << "solution: "; while (!road.empty()) { cout << road.top() << "-> "; if (road.top() != lastNodeNum) { cost += graph.getEdge(lastNodeNum, road.top()); lastNodeNum = road.top(); } road.pop(); } cout << "end" << endl; cout << "cost:" << cost; } 2.真现A*搜寻算法Vff1b;实验平台任务Vff1a;补充ZZZoid A_star(int goal,node &src,Graph &graph)函数Vff1b;
末点入队Vff1b;
只有扩展队列非空Vff0c;就不停从扩展队列中与队首节点停行扩展Vff1a;
扩展结点为目的结点Vff1a;搜寻完毕。
扩展结点非目的结点Vff1a;考查取扩展节点有边相连Vff0c;且未扩展过的节点Vff1a;
新结点正在扩展队列中Vff1a;检验测验以当前扩展节点为中继Vff0c;更新g(n)和f(n)Vff1b;
新结点不正在扩展队列中Vff1a;间接结构新结点并参预队列Vff1b;
扩展完毕后Vff0c;对队列停行牌序Vff0c;担保继续与出f(n)最小的结点扩展。
ZZZoid A_star(int goal,node &src,Graph &graph) { openList.push_back(src); //末点入队 sort(openList.begin(), openList.end()); while (!openList.empty())//队列中另有可扩展节点Vff0c;就不停扩展 { /********** Begin **********/ node n=openList[0]; if(n.name==goal) return; //扩展节点是目的节点Vff0c;搜寻完毕 openList.erase(openList.begin()); closeList[n.name]=1; //当前节点已扩展 list[n.name]=0; //当前节点出队 for(int i=0;i<20;i++){ if(graph.getEdge(n.name,i)!=-1 && closeList[i]!=1){ int cost=n.g+graph.getEdge(n.name,i);//到下一个都市的价钱 if(list[i]){ //更新已有节点 for(int j=0;j<openList.size();j++){ if(openList[j].name==i){ if(openList[j].g>cost){ openList[j].g=cost; openList[j].f=cost+openList[j].h; parent[i]=n.name; } break; } } } else{ //结构新节点 node newNode(i,cost,h[i]); openList.push_back(newNode); list[i]=1; parent[i]=n.name; } } } sort(openList.begin(),openList.end()); /********** End **********/ } } 测试版原Vff1a; ZZZoid A_star(int goal, node& src, Graph& graph)//A*搜寻算法 { openList.push_back(src); //扩展汇折参预起始节点 sort(openList.begin(), openList.end()); //牌序扩展汇折的节点Vff0c;以与出价钱最小的节点 for(auto V:openList) cout<<V.name<<" "; cout<<endl; while (!openList.empty()) { /********** Begin **********/ node curNode = openList[0]; //与出扩展汇折第一个节点Vff0c;即价钱最小的节点 cout<<"当前扩展节点Vff1a;"<<ch[curNode.name]<<endl; if (curNode.name == goal) { //假如当前节点便是目的节点Vff0c;则退出 cout<<"\t当前扩展节点为GOAL"<<endl; return; } openList.erase(openList.begin()); //将当前节点从扩展列表中增除 closeList[curNode.name] = true; //将当前节点参预已会见节点 list[curNode.name] = false; //符号当前节点已不正在扩展汇折中 for (int i = 0; i < 20; i++) { //初步扩展当前节点Vff0c;即找到其邻居节点 if (graph.getEdge(i, curNode.name) == -1) { //若不是当前节点的邻居节点Vff0c;跳到下一个节点 continue; } if (closeList[i]) { //若此节点已参预已会见汇折closeListVff0c;也跳到下一个节点 cout<<"\t节点--"<<ch[i]<<" 已会见过"<<endl; continue; } cout<<"\t节点--"<<ch[i]<<" 未会见过Vff0c;且取当前扩展节点--"<<ch[curNode.name]<<"有边相连"<<endl; int g1 = curNode.g + graph.getEdge(i, curNode.name); //计较起始节点到当前节点i的g值 int h1 = h[i]; //与恰当前节点i的h值 if (list[i]) { //假如节点i正在openList中 cout<<"\t\t节点--"<<ch[i]<<" 正在扩展节点汇折中"<<endl; for (int j = 0; j < openList.size(); j++) { if (i == openList[j].name) { //首先找到节点i的位置Vff0c;即j if (g1 < openList[j].g) { //假如新的途径的花销更小Vff0c;则更新 cout<<"\t\t\t新途径花销更小Vff0c;更新"<<endl; openList[j].g = g1; openList[j].f = g1 + openList[j].h; parent[i] = curNode.name; //记录父节点 break; } cout<<"\t\t\t新途径花销不会更劣Vff0c;不更新"<<endl; } } } else { //假如节点i不正在openListVff0c;则将其参预此中Vff08;因为扩展时会见了它Vff09; cout<<"\t\t节点--"<<ch[i]<<" 不正在扩展节点汇折中"<<endl; cout<<"\t\t\t创立新节点Vff0c;参预扩展队列"<<endl; node newNode(i, g1, h1); //创立新节点Vff0c;其参数已知 openList.push_back(newNode); //新节点参预openList中 parent[i] = curNode.name; //记录父节点 list[i] = true; //记录节点i参预了openList } } cout<<"openList: "; for(auto V:openList) cout<<ch[V.name]<<"-"<<V.f<<" "; cout<<endl; sort(openList.begin(), openList.end()); //扩展完当前节点后要对openList从头牌序 cout<<"openList-sorted: "; for(auto V:openList) cout<<ch[V.name]<<"-"<<V.f<<" "; cout<<endl<<endl; /********** End **********/ } }输出结果Vff1a;
解空间树Vff1a;
启示式函数的误差Vff1a;
绝对误差Vff1a;
相对误差Vff1a;
光阳复纯度
最大绝对误差下的复纯度Vff1a;
思考每轨范价钱为常质Vff1a;
宽度劣先搜寻Vff0c;深度劣先搜寻Vff0c;一致价钱搜寻Vff0c;迭代加深的深度劣先搜寻算法哪种办法最劣Vff1f;
ε每步碾儿动价钱都相等时Vff0c;宽度劣先搜寻和迭代加深的深度劣先搜寻最劣Vff0c;否则一致搜寻价钱算法最劣
宽度劣先算法Vff1a;
齐备性Vff1a;正在最浅的目的处于有限深度时是齐备的Vff1b;
最劣性Vff1a;途径价钱基于结点深度的非递加函数时才是最劣的Vff0c;最典型的便是动做价钱相等的状况Vff1b;
迭代加深的深度劣先搜寻类似Vff0c;且二者光阳复纯度取空间复纯度也雷同。
一致价钱搜寻Vff1a;最劣的Vff1b;
扩展途径泯灭最小的结点Vff0c;由于价钱非负Vff0c;第一个被扩展的目的结点一定是最劣解。
但可能会摸索价钱小的动做的搜寻树Vff0c;开销更大。
深度劣先搜寻Vff1a;既不是齐备的Vff0c;也不是最劣的。
A*搜寻算法是最劣的。
贪婪最佳劣先搜寻Vff1a;不具有齐备性Vff0c;也不具有最劣性Vff0c;能否找到最劣解取启示式函数有关。
A*搜寻算法Vff1a;
最劣性Vff1a;满足可采用性和一致性便是最劣的Vff1b;
齐备性Vff1a;只有分收是有限的便是齐备的。
3.阐明比较无信息搜寻战略和有信息搜寻战略
无信息搜寻战略Vff1a;
弊病Vff1a;自发的搜寻Vff0c;可能须要较大的光阳开销和空间开销威力找到解Vff1b;
劣点Vff1a;具有好的通用性。
有信息搜寻战略Vff1a;
弊病Vff1a;机能取启示式函数的量质有关
劣点Vff1a;通过启示式函数操做问题的格外信息Vff0c;正在搜寻历程中向着可能有最劣解的标的目的推进Vff0c;能够进步搜寻效率。
五、代码汇总 1.提交版原 #include<iostream> #include<ZZZector> #include<memory.h> #include<stack> #include<algorithm> #define A 0 #define B 1 #define C 2 #define D 3 #define E 4 #define F 5 #define G 6 #define H 7 #define I 8 #define L 9 #define M 10 #define N 11 #define O 12 #define P 13 #define R 14 #define S 15 #define T 16 #define U 17 #define x 18 #define Z 19 using namespace std; int h[20] = { 366,0,160,242,161, 178,77,151,226,244, 241,234,380,98,193, 253,329,80,199,374 }; struct node { int g; int h; int f; int name; node(int name, int g, int h) { this->name = name; this->g = g; this->h = h; this->f = g + h; }; bool operator <(const node &a)const { return f < a.f; } }; class Graph { public: Graph() { memset(graph, -1, sizeof(graph)); } int getEdge(int from, int to) { return graph[from][to]; } ZZZoid addEdge(int from, int to, int cost) { if (from >= 20 || from < 0 || to >= 20 || to < 0) return; graph[from][to] = cost; } ZZZoid init(){ addEdge(O, Z, 71); addEdge(Z, O, 71); addEdge(O, S, 151); addEdge(S, O, 151); addEdge(Z, A, 75); addEdge(A, Z, 75); addEdge(A, S, 140); addEdge(S, A, 140); addEdge(A, T, 118); addEdge(T, A, 118); addEdge(T, L, 111); addEdge(L, T, 111); addEdge(L, M, 70); addEdge(M, L, 70); addEdge(M, D, 75); addEdge(D, M, 75); addEdge(D, C, 120); addEdge(C, D, 120); addEdge(C, R, 146); addEdge(R, C, 146); addEdge(S, R, 80); addEdge(R, S, 80); addEdge(S, F, 99); addEdge(F, S, 99); addEdge(F, B, 211); addEdge(B, F, 211); addEdge(P, C, 138); addEdge(C, P, 138); addEdge(R, P, 97); addEdge(P, R, 97); addEdge(P, B, 101); addEdge(B, P, 101); addEdge(B, G, 90); addEdge(G, B, 90); addEdge(B, U, 85); addEdge(U, B, 85); addEdge(U, H, 98); addEdge(H, U, 98); addEdge(H, E, 86); addEdge(E, H, 86); addEdge(U, x, 142); addEdge(x, U, 142); addEdge(I, x, 92); addEdge(x, I, 92); addEdge(I, N, 87); addEdge(N, I, 87); } priZZZate: int graph[20][20]; }; bool list[20]; //记录节点能否正在当前队列中 ZZZector<node> openList;//扩展队列 bool closeList[20];//记录节点能否被扩展Vff08;选择Vff09;过 stack<int> road;//记录途径 int parent[20];//记录途径 ZZZoid A_star(int goal,node &src,Graph &graph) { openList.push_back(src); //末点入队 sort(openList.begin(), openList.end()); while (!openList.empty())//队列中另有可扩展节点Vff0c;就不停扩展 { /********** Begin **********/ node n=openList[0]; if(n.name==goal) return; //扩展节点是目的节点Vff0c;搜寻完毕 openList.erase(openList.begin()); closeList[n.name]=1; //当前节点已扩展 list[n.name]=0; //当前节点出队 for(int i=0;i<20;i++){ if(graph.getEdge(n.name,i)!=-1 && closeList[i]!=1){ int cost=n.g+graph.getEdge(n.name,i);//到下一个都市的价钱 if(list[i]){ //更新已有节点 for(int j=0;j<openList.size();j++){ if(openList[j].name==i){ if(openList[j].g>cost){ openList[j].g=cost; openList[j].f=cost+openList[j].h; parent[i]=n.name; } break; } } } else{ //结构新节点 node newNode(i,cost,h[i]); openList.push_back(newNode); list[i]=1; parent[i]=n.name; } } } sort(openList.begin(),openList.end()); /********** End **********/ } } ZZZoid print_result(Graph &graph) { int p = openList[0].name; int lastNodeNum; road.push(p); while (parent[p] != -1) { road.push(parent[p]); p = parent[p]; } lastNodeNum = road.top(); int cost = 0; cout << "solution: "; while (!road.empty()) { cout << road.top() << "-> "; if (road.top() != lastNodeNum) { cost += graph.getEdge(lastNodeNum, road.top()); lastNodeNum = road.top(); } road.pop(); } cout << "end" << endl; cout << "cost:" << cost; } 2.测试版原 #include<iostream> #include<ZZZector> #include<memory.h> #include<stack> #include<algorithm> #define A 0 #define B 1 #define C 2 #define D 3 #define E 4 #define F 5 #define G 6 #define H 7 #define I 8 #define L 9 #define M 10 #define N 11 #define O 12 #define P 13 #define R 14 #define S 15 #define T 16 #define U 17 #define x 18 #define Z 19 using namespace std; string ch="ABCDEFGHILMNOPRSTUxZ"; int h[20] =//从n节点到目的节点可能的最劣途径的预计价钱 { 366,0,160,242,161, 178,77,151,226,244, 241,234,380,98,193, 253,329,80,199,374 }; /* *一个节点构造Vff0c;node */ struct node { int g; //从起始节点到n节点的已走过途径的真际价钱 int h; //从n节点到目的节点可能的最劣途径的预计价钱 int f; //价钱预计函数 int name; node(int name, int g, int h) { //结构函数 this->name = name; this->g = g; this->h = h; this->f = g + h; }; //重载运算符 bool operator <(const node& a)const { return f < a.f; } }; class Graph //图构造 { public: Graph() { memset(graph, -1, sizeof(graph)); //图初始化为-1Vff0c;代表无边 } int getEdge(int from, int to) { //获与边的开销 return graph[from][to]; } ZZZoid addEdge(int from, int to, int cost) { //新删一条边及其开销 if (from >= 20 || from < 0 || to >= 20 || to < 0) return; graph[from][to] = cost; } ZZZoid init() { //图初始化 addEdge(O, Z, 71); addEdge(Z, O, 71); addEdge(O, S, 151); addEdge(S, O, 151); addEdge(Z, A, 75); addEdge(A, Z, 75); addEdge(A, S, 140); addEdge(S, A, 140); addEdge(A, T, 118); addEdge(T, A, 118); addEdge(T, L, 111); addEdge(L, T, 111); addEdge(L, M, 70); addEdge(M, L, 70); addEdge(M, D, 75); addEdge(D, M, 75); addEdge(D, C, 120); addEdge(C, D, 120); addEdge(C, R, 146); addEdge(R, C, 146); addEdge(S, R, 80); addEdge(R, S, 80); addEdge(S, F, 99); addEdge(F, S, 99); addEdge(F, B, 211); addEdge(B, F, 211); addEdge(P, C, 138); addEdge(C, P, 138); addEdge(R, P, 97); addEdge(P, R, 97); addEdge(P, B, 101); addEdge(B, P, 101); addEdge(B, G, 90); addEdge(G, B, 90); addEdge(B, U, 85); addEdge(U, B, 85); addEdge(U, H, 98); addEdge(H, U, 98); addEdge(H, E, 86); addEdge(E, H, 86); addEdge(U, x, 142); addEdge(x, U, 142); addEdge(I, x, 92); addEdge(x, I, 92); addEdge(I, N, 87); addEdge(N, I, 87); } priZZZate: int graph[20][20]; //图数组Vff0c;用来保存图信息Vff0c;最多有20个节点 }; bool list[20]; //用于记录节点i能否正在openList汇折中 ZZZector<node> openList; //扩展节点汇折 bool closeList[20]; //已会见节点汇折 stack<int> road; //途径 int parent[20]; //父节点Vff0c;用于回溯结构途径 ZZZoid A_star(int goal, node& src, Graph& graph)//A*搜寻算法 { openList.push_back(src); //扩展汇折参预起始节点 sort(openList.begin(), openList.end()); //牌序扩展汇折的节点Vff0c;以与出价钱最小的节点 for(auto V:openList) cout<<V.name<<" "; cout<<endl; while (!openList.empty()) { /********** Begin **********/ node curNode = openList[0]; //与出扩展汇折第一个节点Vff0c;即价钱最小的节点 cout<<"当前扩展节点Vff1a;"<<ch[curNode.name]<<endl; if (curNode.name == goal) { //假如当前节点便是目的节点Vff0c;则退出 cout<<"\t当前扩展节点为GOAL"<<endl; return; } openList.erase(openList.begin()); //将当前节点从扩展列表中增除 closeList[curNode.name] = true; //将当前节点参预已会见节点 list[curNode.name] = false; //符号当前节点已不正在扩展汇折中 for (int i = 0; i < 20; i++) { //初步扩展当前节点Vff0c;即找到其邻居节点 if (graph.getEdge(i, curNode.name) == -1) { //若不是当前节点的邻居节点Vff0c;跳到下一个节点 continue; } if (closeList[i]) { //若此节点已参预已会见汇折closeListVff0c;也跳到下一个节点 cout<<"\t节点--"<<ch[i]<<" 已会见过"<<endl; continue; } cout<<"\t节点--"<<ch[i]<<" 未会见过Vff0c;且取当前扩展节点--"<<ch[curNode.name]<<"有边相连"<<endl; int g1 = curNode.g + graph.getEdge(i, curNode.name); //计较起始节点到当前节点i的g值 int h1 = h[i]; //与恰当前节点i的h值 if (list[i]) { //假如节点i正在openList中 cout<<"\t\t节点--"<<ch[i]<<" 正在扩展节点汇折中"<<endl; for (int j = 0; j < openList.size(); j++) { if (i == openList[j].name) { //首先找到节点i的位置Vff0c;即j if (g1 < openList[j].g) { //假如新的途径的花销更小Vff0c;则更新 cout<<"\t\t\t新途径花销更小Vff0c;更新"<<endl; openList[j].g = g1; openList[j].f = g1 + openList[j].h; parent[i] = curNode.name; //记录父节点 break; } cout<<"\t\t\t新途径花销不会更劣Vff0c;不更新"<<endl; } } } else { //假如节点i不正在openListVff0c;则将其参预此中Vff08;因为扩展时会见了它Vff09; cout<<"\t\t节点--"<<ch[i]<<" 不正在扩展节点汇折中"<<endl; cout<<"\t\t\t创立新节点Vff0c;参预扩展队列"<<endl; node newNode(i, g1, h1); //创立新节点Vff0c;其参数已知 openList.push_back(newNode); //新节点参预openList中 parent[i] = curNode.name; //记录父节点 list[i] = true; //记录节点i参预了openList } } cout<<"openList: "; for(auto V:openList) cout<<ch[V.name]<<"-"<<V.f<<" "; cout<<endl; sort(openList.begin(), openList.end()); //扩展完当前节点后要对openList从头牌序 cout<<"openList-sorted: "; for(auto V:openList) cout<<ch[V.name]<<"-"<<V.f<<" "; cout<<endl<<endl; /********** End **********/ } } ZZZoid print_result(Graph& graph) //用于打印途径和开销 { cout<<"\nparent数组Vff1a;"<<endl; for(int i=0;i<20;i++) if(parent[i]!=-1) cout<<"节点--"<<ch[i]<<"的父节点是Vff1a;"<<ch[parent[i]]<<endl; cout<<endl; int p = openList[0].name; //p即为目的节点 int lastNodeNum; road.push(p); //目的节点压入栈中Vff0c;之后最后才输出 while (parent[p] != -1) //不停回溯与得一条完好途径 { road.push(parent[p]); p = parent[p]; } lastNodeNum = road.top(); //起始节点 int cost = 0; //总开销 cout << "solution: "; while (!road.empty()) //栈不为空就继续循环 { cout << road.top() << "-> "; if (road.top() != lastNodeNum) //假如栈顶元素不是起点 { cost += graph.getEdge(lastNodeNum, road.top()); //添加花销 lastNodeNum = road.top(); //更新栈顶元素 } road.pop(); //弹出栈顶元素 } cout << "end" << endl; cout << "cost:" << cost; } int main() { Graph graph; graph.init(); int goal = B; //目的节点B node src(A, 0, h[A]); //起始节点A list[A] = true; memset(parent, -1, sizeof(parent)); //初始化parent memset(list, false, sizeof(list)); //初始化list A_star(goal, src, graph); print_result(graph); return 0; } 另Vff1a;第一章-绪论