生成具有随机边的图

时间:2017-05-17 19:25:03

标签: c algorithm math random

我正在尝试编写使用通过秩和路径压缩联合使用不相交集的ac / c ++程序。图算法然后在该图上应用Kruskal算法。我已经生成了number_of_vertices-1对(0,1),(1,2) )...(n-2,n-1)作为图中的边缘以使图形连接。我需要生成剩余的3 * number_Of_Vertices + 1个随机边缘作为(vertex1,vertex2)对而没有碰撞(相同的边缘不应生成两次)。我不必使用额外的内存就可以做到这一点。额外的记忆我的意思是一个额外的列表,矢量......你怎么知道如何做到这一点?

这是我迄今为止所做的,但肯定会发生碰撞:

edge** createRandomEdges(nodeG **nodeArray, int n) {
    edge **edgeArray = (edge**)malloc(sizeof(edge*)*n * 4);

    for (int i = 0; i < n; i++)
        edgeArray[i] = createEdge(nodeArray[0], nodeArray[i + 1], rand() % 100+1);
    for (int i = n; i < 4 * n; i++) {
       int nodeAindex = rand() % n;
       int nodeBindex = rand() % n;

       while (nodeAindex == nodeBindex) {
           nodeAindex = rand() % n;
           nodeBindex = rand() % n;
       }

       int weight = rand() % 100 + 1;
       edgeArray[i] = createEdge(nodeArray[nodeAindex], nodeArray[nodeBindex], weight);
   }

   return edgeArray;
}

1 个答案:

答案 0 :(得分:0)

所以你有N个边缘,想要标记它们的K来优化内存消耗。在这种情况下,您可以使用具有O(K)内存复杂度的Reservoir sampling

创建一个大小为K的整数数组,用0..K-1数字填充它,然后走一个循环并使用提供均匀性的规则随机替换一些数字

ReservoirSample(S[1..n], R[1..k])
  // fill the reservoir array
  for i = 1 to k
      R[i] := S[i]

  // replace elements with gradually decreasing probability
  for i = k+1 to n
    j := random(1, i)   // important: inclusive range
    if j <= k
        R[j] := S[i]