使用指针向量实现 Dijkstra 算法

Implementing Dijkstra's algorithm with vector of pointers

本文关键字:Dijkstra 算法 实现 向量 指针      更新时间:2023-10-16

我正在开发一个涉及Dijkstra算法的程序。

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

试图在下面尽我所能将队列伪代码(来自我的教科书(转换为:

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'

我正在尝试减少这篇文章中的代码量,但如果需要,我的整个代码如下:

主.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);
};

边缘:

#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;
        }
};

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++) <-这是154。 sortedVertices不是指针。这是一些指针的std::vector

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

sortedVertices[1].getDV() <- 157 sortedVertices[1]是一个指针。看看operator[]

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

这真的是你的代码吗?

作为作者,您应该在理解错误消息时遇到困难。这些都是简单的错误,陌生人花了5分钟才理解。你需要花更多的精力来理解你写了什么,以及编译器告诉你什么。或者睡一会儿以获得一些注意力。

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

vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0)

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