【问题标题】:Dijkstra algorithm implementation - Code not working for bigger inputsDijkstra 算法实现 - 代码不适用于更大的输入
【发布时间】:2016-09-20 13:11:13
【问题描述】:
#include <iostream>
#include <list>

using namespace std;

class edge
{
    public:
        int dest;
        int dist;
        edge(int a,int b)
        {
            dest=a;
            dist=b;
        }
};

class Graph
{
    public:
        int v;      
        list<edge> *adj;
        list<int> remEdges;
        int *dist;
        int *parent;
        int src;
        Graph(int);
        void addEdge(int,int,int);
        void printEdges(int);
        bool isPresent(int);
        int findMin();
        void dijkstra(int);
};

Graph::Graph(int v)
{
    adj = new list<edge>[v];
    this->v=v;
    dist=new int(v);
    parent=new int(v);
    for(int i=0;i<v;i++)
    {
        remEdges.push_back(i);
        dist[i]=INT_MAX;
    }   
}

bool Graph::isPresent(int num)
{
    list<int> :: iterator i;

    for(i=remEdges.begin();i!=remEdges.end();i++)
        if(num==*i)
            return true;

    return false;
}

int Graph::findMin()
{
    int min=INT_MAX;
    int index=-1;
    for(int i=0;i<v;i++)
        if(dist[i]<min && isPresent(i))
        {
            min=dist[i];
            index=i;
        }
    return index;
}

void Graph :: addEdge(int i,int j,int k)
{
    adj[i].push_back(edge(j,k));
    adj[j].push_back(edge(i,k));
}

void Graph :: printEdges(int src)
{
for(int i=0;i<v;i++)
if(i!=src)
cout<<dist[i]<<" ";


}

void Graph::dijkstra(int src)
{
    dist[src]=0;
    while(!remEdges.empty())
    {
        int min=findMin();
        list<edge> :: iterator i;

        for(i=adj[min].begin();i!=adj[min].end();i++)
        {
            if(isPresent((*i).dest))
            {
            if(dist[min]+(*i).dist<dist[(*i).dest])
                dist[(*i).dest] = dist[min]+(*i).dist;
            }
            parent[(*i).dest]=min;                  
        }
        remEdges.remove(min);
    }
}


int main()
{

    Graph g(9);
    g.addEdge(0, 1, 4);
    g.addEdge(0, 7, 8);
    g.addEdge(1, 2, 8);
    g.addEdge(1, 7, 11);
    g.addEdge(2, 3, 7);
    g.addEdge(2, 8, 2);
    g.addEdge(2, 5, 4);
    g.addEdge(3, 4, 9);
    g.addEdge(3, 5, 14);
    g.addEdge(4, 5, 10);
    g.addEdge(5, 6, 2);
    g.addEdge(6, 7, 1);
    g.addEdge(6, 8, 6);
    g.addEdge(7, 8, 7);
    g.dijkstra(0);
    g.printEdges(0);
    cout<<endl;

    return 0;
}

代码不适用于更大的输入。

我是算法的新手,我想通过 CPP 实现 dijkstra 算法。花了很多时间来修复代码。

它在调试模式下显示正确的输出,但直接从“运行”按钮执行时不起作用。

我正在使用 DEV C++ 运行代码,当驱动程序功能为时它执行良好

int main()
{
    Graph g(4);
    g.addEdge(0, 1, 24);
    g.addEdge(0, 3, 20);
    g.addEdge(2, 0, 3);
    g.addEdge(3, 2, 12);
    g.dijkstra(0);
    g.printEdges(0);
    cout<<endl; 
    return 0;
}

但是当我添加太多边时它不起作用。

请在这方面帮助我。

【问题讨论】:

  • 怎么不起作用? 如何“直接执行”?程序会崩溃吗?它是否给出了错误的输出(你得到什么输出,你期望什么)?也许您错过了在某处初始化指针(停止使用指针而不是 std::vector)?
  • 但是,一个好的开始可能是检查您的分配。您并不总是分配数组,而只是分配单个值。同样,使用 std::vector 而不是动态分配的数组。

标签: c++ algorithm dijkstra


【解决方案1】:
//You should use: 
dist=new int[v]; 
parent=new int[v];

//instead of 
//dist=new int(v);  means: dist = new int[1]; dist[0] = v;
//parent=new int(v);

使用未分配的内存会导致未定义的行为,所以这只是运气,您的代码没有因为几个顶点而崩溃。

您还应该仅在之前未访问过孩子的情况下设置孩子的父母,尽管它不会导致崩溃。 =)

if(isPresent((*i).dest))
{
   if(dist[min]+(*i).dist<dist[(*i).dest])
      dist[(*i).dest] = dist[min]+(*i).dist;

   parent[(*i).dest]=min;
}

【讨论】:

  • 节点之间的这种父子关系在任何地方都没有使用。我忘了删除那些在代码中造成歧义的行。问题是如果我添加了太多的顶点和边,程序就会崩溃。
  • 哦,我明白了!你应该使用:“dist=new int[v]; parent=new int[v];”而不是“dist=new int(v); parent=new int(v);” "new int(v)" 只分配一个 int,并将其初始化为 v。
  • 谢谢兄弟!!!它现在工作。非常感谢你。但是你能解释一下为什么它使用前面的语法 dist=new int(v); 对少数顶点有效吗?另请使用上述评论编辑您的答案。
猜你喜欢
  • 2022-01-05
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
  • 2023-01-19
  • 2021-09-17
  • 1970-01-01
相关资源
最近更新 更多