I try to implement the karger Minimum Cut algorithm (Karger wiki page)
So far, I have tried my algorithm on small examples (input of size 10) and it seems to work. But when I try to have a bigger input, let’s say 200. It just crashes.
To store the minimum cut data, I create a 2D array: GraphCut[SIZE_ARRAY][SIZE_ARRAY_2]
SIZE_ARRAY = 200 in this case, but I can’t find a good length for SIZE_ARRAY_2.
Issue is, SIZE_ARRAY_2 has to be big as I modify the initial array to merge the different vertices.
If I declare SIZE_ARRAY_2 = 200, the size won’t be enough, but if i put SIZE_ARRAY_2 = 1000, the program just crashes.
The thing is, I have to execute the algorithm 100000 times.
Here is parts of the code:
#define ARRAY_SIZE 200
#define ARRAY_SIZE_2 200
int main()
{
int minCut,minMinCut;
for (int k = 0; k < ARRAY_SIZE * ARRAY_SIZE * 4;k++) {
minCut = kargerMinCut(k);
if (k == 0)
minMinCut = minCut;
else if (minMinCut > minCut)
minMinCut = minCut;
}
printf("\n minMinCut = %d\n", minMinCut);
return 0;
}
int kargerMinCut(int k) {
// 1st dimension: each different node
// 2nd dimension: vertices
long graphCut[ARRAY_SIZE + 1][ARRAY_SIZE_2] = {0};
populateIntegerArray(graphCut); // import data from a file
int nodeToMain[ARRAY_SIZE + 1];
int sizeOfMainNode, indexToMerge,initialRand,i,j,m,nodeToMerge,nodeRemaining = ARRAY_SIZE;
for (m = 0;m<ARRAY_SIZE + 1;m++) // initialization of nodeToMain
nodeToMain[m] = m;
while (nodeRemaining > 2) {
i = 0;
j = 0;
srand(time(NULL) + nodeRemaining);// initialise rand
initialRand = nodeToMain[rand()%(ARRAY_SIZE) + 1]; // pick a random initial node, but not a merged one
sizeOfMainNode = sizeOfArray(graphCut[initialRand]); // size of the initial node
srand(time(NULL) + k); // initialise rand
indexToMerge = rand()%sizeOfMainNode;// pick another random node in the linked nodes (its index to be precise)
nodeToMerge = nodeToMain[graphCut[initialRand][indexToMerge]];
for (m = 0;m<ARRAY_SIZE + 1;m++) // update the nodeToMain array, initialRand is now the main node for nodeToMerge
if (nodeToMain[m] == nodeToMerge)
nodeToMain[m] = initialRand;
// remove the nodeToMerge numbers from the graphCut[initialRand] (as they are going to be merged)
while(graphCut[initialRand][j] > 0 && j < sizeOfMainNode) {
if (initialRand == nodeToMain[graphCut[initialRand][j]]) {
// if this is the last element, do nothing
while(nodeToMain[graphCut[initialRand][sizeOfMainNode - 1]] == initialRand && j < sizeOfMainNode - 1) {
graphCut[initialRand][sizeOfMainNode - 1] = 0;
sizeOfMainNode--;
}
graphCut[initialRand][j] = nodeToMain[graphCut[initialRand][sizeOfMainNode - 1]];
graphCut[initialRand][sizeOfMainNode - 1] = 0;
sizeOfMainNode--;
}
j++;
}
i = 0;
while (graphCut[nodeToMerge][i] > 0 && sizeOfMainNode < ARRAY_SIZE_2 && i < ARRAY_SIZE_2) { // add each vextex of the nodeTomerge to the merged nodes
if (nodeToMain[graphCut[nodeToMerge][i]] != initialRand) {
graphCut[initialRand][sizeOfMainNode] = nodeToMain[graphCut[nodeToMerge][i]];
sizeOfMainNode++;
}
i++;
}
nodeRemaining--;
}
return sizeOfArray(graphCut[nodeToMain[1]]);
}
I’m sure that the code is not really clean, maybe even really bad (beginner in C). So i Welcome any other advice.
The errors I get with the debugger seems really random.
Error is:
Impossible to divide by 0
it stops in time64.c at line 62
tim = (__time64_t)((nt_time.ft_scalar - EPOCH_BIAS) / 10000000i64);
The change in array size is probably causing a stack overflow. A common default size for the stack is 1MB (1048576 bytes). If you have:
and
4 == sizeof(long)thegraphCutarray is taking up200 * 1000 * 4 = 800000bytes, which leaves248576bytes which may not be enough for the stack variables inpopulateIntegerArray()function (I don’t see that function). If8 == sizeof(long)then the array would require1600000bytes, which is greater than 1MB.If an array of that size is required then allocate (all or part) on the heap instead of the stack. For example: