c++ boost library astar search tree implementation

一世执手 提交于 2019-12-11 15:05:55

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!