在C ++中创建随机无向图

时间:2013-06-08 13:52:36

标签: c++ random graph dijkstra creation

问题是我需要创建一个随机无向图来测试Dijkstra's algorithm的基准测试,使用数组和堆来存储顶点。在稀疏和平均图上运行时,AFAIK堆实现应该比数组更快,但是当涉及到密集图时,堆的效率应该低于数组。

我尝试编写将根据输入生成图形的代码 - 顶点数和边数总数(无向图中的最大边数为n(n-1)/ 2)。

在入口处,我将边的总数除以顶点的数量,这样我就有从每个顶点出来的const数量的边。该图由邻接列表表示。以下是我提出的建议:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <list>
#include <set>

#define MAX 1000
#define MIN 1

class Vertex
{
public:
    int Number;
    int Distance;
    Vertex(void);
    Vertex(int, int);
    ~Vertex(void);
};

Vertex::Vertex(void)
{
    Number = 0;
    Distance = 0;
}

Vertex::Vertex(int C, int D)
{
    Number = C;
    Distance = D;
}

Vertex::~Vertex(void)
{
}


int main()
{
    int VertexNumber, EdgeNumber;

    while(scanf("%d %d", &VertexNumber, &EdgeNumber) > 0)
    {
        int EdgesFromVertex = (EdgeNumber/VertexNumber);

        std::list<Vertex>* Graph = new std::list<Vertex> [VertexNumber];

        srand(time(NULL));

        int Distance, Neighbour;
        bool Exist, First;

        std::set<std::pair<int, int>> Added;

        for(int i = 0; i < VertexNumber; i++)
        {
            for(int j = 0; j < EdgesFromVertex; j++)
            {
                First = true;
                Exist = true;

                while(First || Exist)
                {
                    Neighbour = rand() % (VertexNumber - 1) + 0;

                    if(!Added.count(std::pair<int, int>(i, Neighbour)))
                    {
                        Added.insert(std::pair<int, int>(i, Neighbour));
                        Exist = false;
                    }
                    First = false;
                }
            }

            First = true;
            std::set<std::pair<int, int>>::iterator next = Added.begin();

            for(std::set<std::pair<int, int>>::iterator it = Added.begin(); it != Added.end();)
            {
                if(!First)
                    Added.erase(next);

                Distance = rand() % MAX + MIN;

                Graph[it->first].push_back(Vertex(it->second, Distance));
                Graph[it->second].push_back(Vertex(it->first, Distance));

                std::set<std::pair<int, int>>::iterator next = it;
                First = false;
            }
        }

        // Dijkstra's implementation
    }

    return 0;
}

我收到错误:

  尝试从设置数据创建图时,

设置迭代器不可解除引用。

我知道它与动态删除设置元素有关,但我需要尽可能地删除它们以减少内存使用。

也许有更好的方法来创建一些非定向图?我很生,但这是我想出的最好的。我正在考虑制作一个更容易完成任务的有向图,但它并不能确保每两个顶点都能连接起来。

我会很感激任何提示和解决方案!

2 个答案:

答案 0 :(得分:0)

查看std::set::erase的{​​{3}}:

迭代器有效期

  • 引用删除的元素的迭代器,指针和引用 该功能无效。
  • 所有其他迭代器,指针和 引用保持其有效性。

在您的代码中,如果next等于it,并且您std::set删除了next的元素,则无法使用it。在这种情况下,您必须(至少)更改it并且仅在此之后继续使用it

答案 1 :(得分:0)

Piotry和我的想法基本相同,但他离开了一步。

只读取矩阵的一半,并忽略对角线写入值。如果您总是希望节点有自己的边缘,请在对角线上添加一个节点。如果您始终不希望节点有自己的边缘,请将其保留为零。

您可以阅读矩阵的另一半,以获取第二个图表来测试您的实现。