A *算法不能正确地停止或评估邻居

时间:2016-04-27 10:03:38

标签: c++ algorithm a-star

我正在尝试开发能够找到两点之间路径的A *算法。我们的想法是将地图表示为图形,其中边表示街道,顶点表示两个不同点之间的交点。

我使用以下格式从txt中提取数据:

4726;"";3293;3294;0.0268074;40;-8.6555719;41.1484438;-8.6556097;41.1486832

每个字段分别代表id,名称,来​​源,目标,距离,速度,x1,y1,x2,y2。

这是我的顶点类:

// VERTEX
template <class T>
class Vertex { //cruzamentos

    T intersect;
    vector<Edge<T> > adj;
    bool visited;
    float distance;
    float time;
    int indegree;       //numero arestas que apontam para este no
    bool processing, closed, inQueue;

public:

    Vertex(T in);

    T getIntersection() const;
    vector<Edge<T> > getAdj() const;

    bool getVisited() const;
    void setVisited(bool v);

    float getDistance() const;
    void setDistance(float d);

    float getTime() const;
    void setTime(float t);

    int getIndegree() const;
    void setIndegree(int i);

    bool addEdge(Edge<T> &edge);
    int findEdge(Vertex<T> &v);     //retorna posicao no vetor adj se existir, se nao -1
    int findEdgeByID(int id);

    Vertex *path;

    float fx;           //Astar

    int findSmallestAdj();          //retorna posicao no vetor adj da aresta mais pequena ligada a este nó
    friend class Graph<T>;
};

template <class T>
struct vertex_greater_than {
    bool operator()(Vertex<T> * a, Vertex<T> * b) const {
        return a->getDistance() > b->getDistance();
    }
};

template <class T>
struct vertex_greater_than_time {
    bool operator()(Vertex<T> * a, Vertex<T> * b) const {
        return a->getTime() > b->getTime();
    }
};

template <class T>
struct vertex_greater_than_fx {
    bool operator()(Vertex<T> * a, Vertex<T> * b) const {
        return a->fx > b->fx;
    }
};

这是我的边缘课程:

// EDGE
template <class T>
class Edge { // ruas

    Vertex<T> * dest;
    string name;
    float length;
    float vMax;
    static int ID;
    int thisID;

public:
    Edge(Vertex<T> *d, string n, float l, float vm);
    Edge();

    Vertex<T>* getDest() const;
    string getName() const;
    float getLength() const;
    float getVMax() const;
    int getID() const;

    friend class Graph<T>;
    friend class Vertex<T>;
};

和我的图表类:

// GRAPH
template <class T>
class Graph {

    vector<Vertex<T> *> vertexSet;

public:

    Graph();

    vector<Vertex<T> *> getVertexSet() const;
    unsigned int getNumVertex() const;

    int addVertex(const T &in);     //devolve posicao do vetor em que se encontra o vertice, push_back se nao existia e devolve vector.size();
    bool addEdge(const T &sourc, const T &dest, string name, float length, float vm);

    bool removeVertex(const T &in);                         //TODO
    bool removeEdge(const T &source, const T &dest);        //TODO

    void DijkstraShortestPath(const T &start);
    void DijkstraFastestPath(const T &start);

    void aStar(const T &start, const T &goal, bool dist);

    vector<T> getPath(const T &source, const T &dest);

    int findVertex(const T &f);         //pela interseccao
    int getVertexByID(int id);          //pelo id da interseccao

    int getFirstID(int id) {
        for(int i = 0; i < vertexSet.size(); i++) {
            if(vertexSet[i]->getIntersection().getID() == id && vertexSet[i]->getIntersection().getID() >= 0) {
                return vertexSet[i]->getIntersection().getID();
            }
        }
        return -1;
    }

    friend class Vertex<T>;

};

然后我尝试开发一个A星算法,但我得到了一个非常奇怪的输出:

47629
47629
2994
2994
2994
2994
2994
2994
2994
2994
2994
2994
2994
2994
1862
1862
1862
1862
1862
1862
3736
3736
3736
3736
3736
3736
3736
3736
3736
3736
3736
3736
2526
2526
2526
2526
2526
2526
2526
2526
2526
2526
2526
2526
4774
4774
4774
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
4924
2598
2598
2598
2598
2598
2598
2598
2598
2598
2598
2598
2598
6705
6705
6705
6705
6705
6705
6705
6705
6705
6705
6705
6705
746
746
4760
4696
4760
4696
4760
4696
47701
47701
47701
47701
47701
47701
4744
4744
47701
47701
47701
47701
47701
47701
4778
4778
4778
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744
4744

为什么一遍又一遍地验证相同的顶点,为什么不进入目标?我使用的是欧几里得启发式算法,它耗时很长,我不知道为什么。

我真的很感激任何帮助,因为我一直在努力解决这个问题。

祝你好运

我的AStar算法:

template <class T>
void Graph<T>::aStar(const T &start, const T &goal, bool dist){

    for(unsigned i = 0; i < vertexSet.size(); i++) {
        vertexSet[i]->path = NULL;
        vertexSet[i]->distance = INF;
        vertexSet[i]->fx = INF;
        vertexSet[i]->closed = false;
        vertexSet[i]->inQueue = false;
    }

    Vertex<T> *s = vertexSet[addVertex(start)];

    s->setDistance(0);
    s->fx = s->getDistance() + heuristic_aStar(s, vertexSet[addVertex(goal)], dist);

    //priority_queue< VertexPtr<T>, vector< VertexPtr<T> >, CompareVertex<T> > nextVertices;

    vector<Vertex<T>*> pq;      //nextVertices


    pq.push_back(s);
    s->inQueue = true;

    //cout << s->getIntersection().getID() << endl;

    make_heap(pq.begin(), pq.end());

    while (!pq.empty()) {
        Vertex<T> *current = pq.front();
        pop_heap(pq.begin(), pq.end());
        pq.pop_back();

        current->inQueue = false;

        if (current == vertexSet[addVertex(goal)]){
            current->path = vertexSet[addVertex(goal)];
            break;
        }

        current->closed = true;

        for(unsigned i = 0; i < current->adj.size(); i++) {
            Edge<T> edge = current->adj[i];
            Vertex<T> *neighbour = edge.dest;

            double weight = dist ? edge.length : neighbour->time;

            if (!neighbour->closed) {
                neighbour->distance = current->distance + weight;
                neighbour->path = current;
                neighbour->fx = neighbour->distance + heuristic_aStar(neighbour, vertexSet[addVertex(goal)], dist);

                if(neighbour->inQueue)
                    removeFromQueue(pq, neighbour->getIntersection());
                else neighbour->inQueue = true;

                pq.push_back(vertexSet[addVertex(neighbour->getIntersection())]);

            }

            else if (current->distance + weight + heuristic_aStar(neighbour, vertexSet[addVertex(goal)], dist) < neighbour->fx){
                neighbour->closed = false;
                neighbour->distance = current->distance + weight;
                neighbour->path = current;
                neighbour->fx = neighbour->distance + heuristic_aStar(neighbour, vertexSet[addVertex(goal)], dist);

                pq.push_back(vertexSet[addVertex(neighbour->getIntersection())]);

                neighbour->inQueue = true;

            }

            cout << neighbour->path->getIntersection().getID() << endl;

            make_heap(pq.begin(), pq.end(), vertex_greater_than_fx<T>());

        }
    }

    cout << "PQ size: " << endl;
    cout << pq.size() << endl;

    for(unsigned i=0; i< pq.size(); i++){
        cout << pq[i]->getIntersection().getID() << endl;
    }

    return;
}

AddVertex功能

template<class T>
inline int Graph<T>::addVertex(const T& in) {

    for(unsigned int i = 0; i < vertexSet.size(); i++){
        if(vertexSet[i]->getIntersection() == in)
            return i;
    }

    Vertex<T> *v = new Vertex<T>(in);
    vertexSet.push_back(v);

    return vertexSet.size();
}

交叉课程

class Intersection {
    int id;
    Coordenadas coord;
    bool IP;
public:
    Intersection();
    Intersection (int ident, float x, float y);
    int getID() const;
    Coordenadas getCoord() const;
    void setIP(bool p);
    bool getIP();
    bool operator == (const Intersection &p2) const;
    bool operator != (const Intersection &p2) const;
    friend ostream & operator << (ostream &os, Intersection &p);
};

0 个答案:

没有答案