用指针向量实现Dijkstra算法

时间:2014-04-28 20:38:53

标签: c++ algorithm vector dijkstra

我正在研究一个涉及Dijkstra算法的程序。

经过长时间的搜索,我只找到了有关使用队列或堆的Dijkstra算法的帮助,但是,我没有使用这些。我的任务是使用指向Vertex对象的指针向量(我定义的自定义类)。

我试图将Queue伪代码(来自我的教科书)转换为以下最佳能力:

void Dijkstra(vector<Vertex*> & V, int startNum)
{
    vector<Vertex*> sortedVertices = V;

    sortedVertices[startNum]->setDV(0);

    insertionSort(sortedVertices);

    while(sortedVertices.size() != 0)
    {
        sortedVertices[sortedVertices.size() - 1]->setKnown(true);
        sortedVertices.pop_back();
        insertionSort(sortedVertices);
        Vertex * v = V[1]; // Will always bring the first element off the list
        v->setKnown(true);

        for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)
        {
            int dist = getAdjacentVertices()[m].getWeight();
            if((sortedVertices[1].getDV() + dist) < sortedVertices[m+1]->getAdjacentVertices()[m].getDV())
            {
                //WE WILL DECREASE THE VALUE HERE by finding the distance between two vertices
                cout << "It works so far" << endl;
                // BOOK has this, somehow need to change it: w.path = v
            }
        }
    } 
}

但是,当我尝试编译时,我一直收到以下错误:

Main.cpp: In function 'void Dijkstra(std::vector<Vertex*>&, int)':
Main.cpp:154:42: error: base operand of '->' has non-pointer type 'std::vector<Vertex*>'
Main.cpp:156:44: error: 'getAdjacentVertices' was not declared in this scope
Main.cpp:157:35: error: request for member 'getDV' in 'sortedVertices.std::vector<_Tp, _Alloc>::operator[]<Vertex*, std::allocator<Vertex*> >(1ul)', which is of pointer type '__gnu_cxx::__alloc_traits<std::allocator<Vertex*> >::value_type {aka Vertex*}' (maybe you meant to use '->' ?)
Main.cpp:157:99: error: '__gnu_cxx::__alloc_traits<std::allocator<Edge> >::value_type' has no member named 'getDV'

我正在尝试减少此帖子中的代码量,但如果需要,我的整个代码如下:

Main.cpp的:

#include "Vertex.h"
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <fstream>

using namespace std;
void shortestPath(vector<Vertex> & v);

template <typename Comparable>
void insertionSort(vector<Comparable> & a);

template <typename Comparable>
void insertionSort( vector<Comparable> & a, int left, int right );


///overload the less than operator in order to use the stl sort for vector
///print out the path for each vertex

int main()
{

    /////READ ALL THE STUFF INTO THE GRAPH////
    ifstream file;
    file.open("graph.txt");
    cout << "Opening file..." << endl;
    if(!file)
    {
        cout << "System failed to open file.";
    }
    else
    {
        cout << "File successfully opened" << endl;
    }

    int numVertices;
    int numEdges;
    int num;
    int adjacentVertex;
    int weight;

    file >> numVertices;
    cout << "The number of vertices that are being read into the graph from the file: " << numVertices;
    cout << endl;
    vector<Vertex*> vertices;
    //vector<Vertex> vertices(numVertices + 1);

    Vertex * newVertex;

    vertices.push_back(NULL);

    cout << "SIZE: " << vertices.size() << endl;
    cout << "NUM VERTICES: " << numVertices << endl;
    for(int i=1;i < numVertices + 1; i++)
    {   
        file >> numEdges;
        cout << "At vertex " << i << " the number of edges is " << numEdges << endl;
        newVertex = new Vertex();

        //Using the i counter variable in the outer for loop to identify
        //the what vertex what are currently looking at in order to read in the correct adjacent vertex and weight
        cout << "LENGTH OF VERTICES[i]: " << vertices.size() << endl;
        newVertex->setVertexNum(i);
        //newVertex.setVertexNum(i);

        for(int j=1;j<=numEdges;j++)
        {
            file >> adjacentVertex;
            cout << "The adjacent vertex is: " << adjacentVertex << endl;


            file >> weight;
            cout << "The weight is: " <<  weight << endl;
            cout << endl;

            newVertex->setAdjacentVertex(adjacentVertex, weight);
        }
        //cout << "LENGTH OF VERTICES[i]: " << vertices.size() << endl;
        vertices.push_back(newVertex);
    }
    file.close();
    vector<Vertex*> sortedVertices = vertices;
    insertionSort(sortedVertices);


    cout << "SIZE: " << vertices.size() << endl;
    for(int i=0;i<vertices.size();i++)
    {
        cout << "V" << i << ":  ";
        cout << endl;
        if(vertices[i] != NULL)
        {
            cout << "DV Value: " << vertices[i]->getDV();
            cout << endl;
            cout << "Known Value: " << vertices[i]->getKnown();
            cout << endl;
        }
    }


    cout << "Sorted: " << endl;
    for(int i=0;i<sortedVertices.size();i++)
    {
        cout << "V" << i << ":  ";
        cout << endl;
        if(vertices[i] != NULL)
        {
            cout << "DV Value: " << sortedVertices[i]->getDV();
            cout << endl;
            cout << "Known Value: " << sortedVertices[i]->getKnown();
            cout << endl;
        }
    }    





    //CALL THE SHORTEST PATH FUNCTION ON THE GRAPH/////



}

/*
const bool myFunction(const Vertex & x, const Vertex & y)
{
    return (x.getDV() >= y.getDV());
}
*/

bool operator < (const Vertex & v1, const Vertex & v2)
{
    return v1.getDV() > v2.getDV();
}

void Dijkstra(vector<Vertex*> & V, int startNum)
{
    vector<Vertex*> sortedVertices = V;

    sortedVertices[startNum]->setDV(0);

    insertionSort(sortedVertices);

    while(sortedVertices.size() != 0)
    {
        sortedVertices[sortedVertices.size() - 1]->setKnown(true);
        sortedVertices.pop_back();
        insertionSort(sortedVertices);
        Vertex * v = V[1]; // Will always bring the first element off the list
        v->setKnown(true);

        for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)
        {
            int dist = getAdjacentVertices()[m].getWeight();
            if((sortedVertices[1].getDV() + dist) < sortedVertices[m+1]->getAdjacentVertices()[m].getDV())
            {
                //WE WILL DECREASE THE VALUE HERE by finding the distance between two vertices
                cout << "It works so far" << endl;
                // BOOK has this, somehow need to change it: w.path = v
            }
        }
    } 
}

////////INSERTION SORT////////////
template <typename Comparable>
void insertionSort( vector<Comparable> & a )
{
    for( int p = 1; p < a.size( ); ++p )
    {
        Comparable tmp = std::move( a[ p ] );

        int j;
        for( j = p; j > 0 && tmp < a[ j - 1 ]; --j )
            a[ j ] = std::move( a[ j - 1 ] );
        a[ j ] = std::move( tmp );
    }
}

template <typename Comparable>
void insertionSort( vector<Comparable> & a, int left, int right )
{
    for( int p = left + 1; p <= right; ++p )
    {
        Comparable tmp = std::move( a[ p ] );
        int j;

        for( j = p; j > left && tmp < a[ j - 1 ]; --j )
            a[ j ] = std::move( a[ j - 1 ] );
        a[ j ] = std::move( tmp );
    }
}

Vertex.h:

#include "Edge.h"
#include <vector>
#include <climits>
#include <fstream>
using namespace std;
class Vertex
{
    private:
        int vertexNum; //number of the vertex for identification purposes
        int degree;
        bool known;
        vector<Edge> adjacentVertices; //vector of vertices that are adjacent to the vertex we are currently looking at
        int dv; //distance 
        int pv; //previous vertex
        Vertex *vertex;
    public:
        Vertex()
        {
            dv = INT_MAX;
            known = false;
        }

        void setKnown(bool Known)
        {
            known = Known;
        }

        bool getKnown()
        {
            return known;
        }

        void setVertexNum(int VertexNum)
        {
            vertexNum = VertexNum;
        }

        void setDegree(int Degree)
        {
            degree = Degree;
        }

        vector<Edge> & getAdjacentVertices()
        {
            return adjacentVertices;
        }

        int getVertexNum()
        {
            return vertexNum;
        }

        int getDegree()
        {
            return degree;
        }

        int getDV() const 
        {
            return dv;
        }

        int setDV(int Dv)
        {
            dv = Dv;
        }

        void setAdjacentVertex(int AdjacentVertex, int Weight)
        {
            Edge newEdge;
            newEdge.setWeight(Weight);
            newEdge.setAdjVertex(AdjacentVertex);
            adjacentVertices.push_back(newEdge);
        }

        friend ostream & operator <<(ostream & outstream, Vertex *vertex)
        {
            outstream << vertex->getVertexNum() << endl;
            outstream << vertex->getDegree() << endl;
            outstream << vertex->getKnown() << endl;
            vector<Edge> E = vertex->getAdjacentVertices();
            for(int x=0;x<E.size();x++)
            {
                outstream << E[x].getAdjVertex() << endl;
                outstream << E[x].getWeight() << endl;
            }
            return outstream;
        }

        friend bool operator < (const Vertex & v1, const Vertex & v2);

};

Edge.h:

#include <cstdlib>
class Edge
{
    private:
        int adjVertex; //represents the vertex that the edge leads to
        int weight;
    public:
        Edge()
        {
            adjVertex = 0;
            weight = 0;
        }
        void setWeight(int Weight)
        {
            weight = Weight;
        }

        void setAdjVertex(int adjacent)
        {
            adjVertex = adjacent;
        }

        int getAdjVertex()
        {
            return adjVertex;
        }

        int getWeight()
        {
            return weight;
        }
};

2 个答案:

答案 0 :(得分:2)

g++到英语:

Main.cpp: In function 'void Dijkstra(std::vector<Vertex*>&, int)':
Main.cpp:154:42: error: base operand of '->' has non-pointer type 'std::vector<Vertex*>'
Main.cpp:156:44: error: 'getAdjacentVertices' was not declared in this scope
Main.cpp:157:35: error: request for member 'getDV' in 'sortedVertices.std::vector<_Tp, _Alloc>::operator[]<Vertex*, std::allocator<Vertex*> >(1ul)', which is of pointer type '__gnu_cxx::__alloc_traits<std::allocator<Vertex*> >::value_type {aka Vertex*}' (maybe you meant to use '->' ?)
Main.cpp:157:99: error: '__gnu_cxx::__alloc_traits<std::allocator<Edge> >::value_type' has no member named 'getDV'

说明:

for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)&lt; - 这是154. sortedVertices不是指针。这是一些std::vector指针。

int dist = getAdjacentVertices()[m].getWeight();&lt; - 156.什么是getAdjacentVertices

sortedVertices[1].getDV()&lt; - 157 sortedVertices[1] 指针。看operator[]

sortedVertices[m+1]->getAdjacentVertices()vector EdgeEdge没有定义getDV()方法。

这真的是你的代码吗?

作为作者,您不应该在理解错误消息时遇到问题。这些都是简单的错误,陌生人花了5分钟才能理解。您需要付出更多努力来理解您所编写的内容以及编译器告诉您的内容。或者得到一些睡眠以获得一些关注。

我还建议花一些时间来研究std::vector到底是什么以及如何理解std::vector<Vertex*> vector_of_vertices;对象。

答案 1 :(得分:0)

vector<Vertex*> sortedVertices = V;

sortedVertices[startNum]->setDV(0)

在这里,您可以在堆栈上创建类型为vector<Vertex*>的变量。这不是指针。这是一个包含Vertex*类型指针的容器,它们完全不同。您使用->运算符,该运算符仅用于指针。