繁体   English   中英

用指针向量实现Dijkstra算法

[英]Implementing Dijkstra's algorithm with vector of pointers

我正在开发一个涉及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;
        }
};

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

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

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

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

这真的是您的代码吗?

作为作者,您应该不难理解错误消息。 这些都是简单的错误,一个陌生人花了5分钟才能理解。 您需要付出更多的努力来理解您编写的内容以及编译器告诉您的内容。 或睡个好觉来集中精力。

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

vector<Vertex*> sortedVertices = V;

sortedVertices[startNum]->setDV(0)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM