我正在尝试编写使用通过秩和路径压缩联合使用不相交集的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;
}
答案 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]