问题
I am trying to implement an A* search tree into a project but I am not understanding how to create my Heuristic class. I have successfully implemented Dijkstra's and Prim's functions on my graph, But I am at a loss on how to create the Heuristic Class and call the astar function. Any help would be greatly appreciated, here is my full code up to this point:
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include "/Boost/boost_1_65_1/boost_1_65_1/boost/graph/adjacency_list.hpp"
#include "/Boost/boost_1_65_1/boost_1_65_1/boost/graph/graph_utility.hpp"
#include "/Boost/boost_1_65_1/boost_1_65_1/boost/graph/visitors.hpp"
#include "/Boost/boost_1_65_1/boost_1_65_1/boost/graph/breadth_first_search.hpp"
#include "/Boost/boost_1_65_1/boost_1_65_1/boost/graph/dijkstra_shortest_paths.hpp"
#include "/Boost/boost_1_65_1/boost_1_65_1/boost/graph/prim_minimum_spanning_tree.hpp"
#include "/Boost/boost_1_65_1/boost_1_65_1/boost/property_map/property_map.hpp"
#include "/Boost/boost_1_65_1/boost_1_65_1/boost/graph/astar_search.hpp"
using namespace boost;
using namespace std;
typedef boost::adjacency_list_traits<vecS, vecS, undirectedS> GraphTraits;
typedef GraphTraits::vertex_descriptor Vertex;
struct VertexProperty {
string name;
Vertex predecessor;
double distance;
default_color_type color;
VertexProperty(const string& aName = "") : name(aName) { };
};
struct EdgeProperty {
double weight; // distance to travel along this edge.
EdgeProperty(double aWeight = 0.0) : weight(aWeight) { };
};
typedef adjacency_list<vecS, vecS, undirectedS, VertexProperty, EdgeProperty> Graph;
Graph g;
struct do_nothing_dijkstra_visitor : default_dijkstra_visitor{};
int main() {
string tempName1, tempName2, tempString, data2;
int weight;
string inputFile;
int choice;
Vertex cur_v, start_v, goal_v;
map<string, Vertex> name2v, name1v;
double totalDist, tempDist;
int numVert = 0;
while (1) {
cout << "\n-------------------------" << endl;
cout << " Graph Implementation";
cout << "\n-------------------------" << endl << endl;
cout << "1. Insert File into Graph" << endl;
cout << "2. Shortest Paths in a Network" << endl;
cout << "3. Minimum Spanning Tree" << endl;
cout << "4. Travelling Salesman" << endl;
cout << "5. Exit" << endl << endl;
cout << "Selection: ";
cin >> choice;
cout << endl;
switch (choice) {
case 1:
{
cout << "Please enter name of file you would like to input: ";
cin >> inputFile;
cout << endl;
ifstream fin;
fin.open(inputFile);
if (!fin) {
cerr << "Cant open data file, goodbye..." << endl;
system("Pause");
return EXIT_FAILURE;
}
else {
cout << "File loaded." << endl << endl;
}
//build graph based on file loaded
getline(fin, tempString);
getline(fin, tempString);
stringstream tempSS(tempString);
while (getline(tempSS, tempName1, ',')) {
name2v[tempName1] = add_vertex(VertexProperty(tempName1), g);
numVert++;
}
getline(fin, tempString);
while (getline(fin, tempString)) {
tempString.erase(tempString.begin(), tempString.begin() + tempString.find('(') + 1);
tempString.erase(tempString.begin() + tempString.find(')'), tempString.end());
stringstream temp_ss(tempString);
getline(temp_ss, tempName1, ',');
getline(temp_ss, tempName2, ',');
temp_ss >> weight;
add_edge(name2v[tempName1], name2v[tempName2], EdgeProperty(weight), g);
}
name1v = name2v;
cout << "Graph Created" << endl;
print_graph(g, get(&VertexProperty::name, g));
break;
}
case 2:
{
totalDist = 0;
cout << endl << "Please enter the location name to start from: ";
cin >> tempName1;
transform(tempName1.begin(), tempName1.end(), tempName1.begin(), ::toupper);
cout << endl << "Please enter the location name for the destination: ";
cin >> tempName2;
transform(tempName2.begin(), tempName2.end(), tempName2.begin(), ::toupper);
start_v = name2v[tempName1];
goal_v = name2v[tempName2];
dijkstra_shortest_paths(
g, goal_v,
get(&VertexProperty::predecessor, g),
get(&VertexProperty::distance, g),
get(&EdgeProperty::weight, g),
identity_property_map(),
less<double>(),
plus<double>(),
numeric_limits<double>::infinity(),
0.0,
do_nothing_dijkstra_visitor(),
get(&VertexProperty::color, g));
cout << endl;
cout << "Shortest Path From " << tempName1 << " to " << tempName2 << ": "<< endl;
cur_v = start_v;
while (cur_v != goal_v) {
cout << "(" << g[cur_v].name << ", ";
totalDist += g[cur_v].distance;
tempDist = g[cur_v].distance;
cur_v = g[cur_v].predecessor;
cout << g[cur_v].name << ")" << endl;
totalDist -= g[cur_v].distance;
};
cout << "Total Weight: " << totalDist << endl;
name2v = name1v;
break;
}
case 3:
{
totalDist = 0;
Graph::vertex_descriptor start_w;
cout << "Please enter the Vertex you would like to start at: ";
{
string startName;
cin >> startName;
transform(startName.begin(), startName.end(), startName.begin(), ::toupper);
start_w = name2v.at(startName);
}
prim_minimum_spanning_tree(g, start_w,
get(&VertexProperty::predecessor, g),
get(&VertexProperty::distance, g),
get(&EdgeProperty::weight, g),
identity_property_map(),
do_nothing_dijkstra_visitor());
cout << endl;
cout << "Minimum Spanning Tree: " << endl;
for (auto vd : make_iterator_range(vertices(g))) {
auto p = g[vd].predecessor;
if (g[vd].name != g[p].name) {
cout << "(" << g[vd].name << ", " << g[p].name << ")" << endl;
totalDist += g[vd].distance;
}
}
cout << "Total Weight: " << totalDist;
name2v = name1v;
break;
}
case 4:
Graph::vertex_descriptor start_x;
cout << "Please enter the Vertex you would like to start at: ";
{
string startName;
cin >> startName;
transform(startName.begin(), startName.end(), startName.begin(), ::toupper);
start_x = name2v.at(startName);
}
break;
case 5:
{
cout << "Goodbye" << endl;
exit(1);
break;
}
default:
cout << "Make a correct choice" << endl;
}
}
system("Pause");
return EXIT_SUCCESS;
}
This is a sample input file I will be presented:
Vertices:
S,H,R,C,L
Edges
(S,C,39)
(R,S,86)
(L,S,74)
(C,H,55)
(R,C,126)
(L,C,68)
(R,H,111)
(L,R,56)
(H,L,97)
(S,H,27)
my attempt at a Heuristic class:
class distance_heuristic : public astar_heuristic<Graph, double> {
public:
distance_heuristic(string goal)
: m_goal(goal) {}
double operator()(string u) {
return tempMap[m_goal].distance;
}
private:
string m_goal;
map<string, Vertex> tempMap;
};
来源:https://stackoverflow.com/questions/47705162/c-boost-library-astar-search-tree-implementation