_seq<intT> setCover(Graph GS) { double epsilon = 0.01; intT m = maxElt(GS); cout << "m = " << m << endl; bucketTime.start(); pair<bucket*, int> B = putInBuckets(GS, epsilon); bucketTime.stop(); bucket* allBuckets = B.first; int numBuckets = B.second; set* S = newA(set, GS.n); // holds sets for current bucket set* ST = newA(set, GS.n); // temporarily S (pack is not inplace) int l = 0; // size of S bool* flag = newA(bool, GS.n); intT* inCover = newA(intT, GS.n); intT nInCover = 0; intT totalWork = 0; intT* elts = newA(intT,m); intT threshold = GS.n; for (int i = 0; i < m; i++) elts[i] = INT_MAX; // loop over all buckets, largest degree first for (int i = numBuckets-1; i >= 0; i--) { bucket currentB = allBuckets[i]; intT degreeThreshold = ceil(pow(1.0+epsilon,i)); if (degreeThreshold == threshold && currentB.n == 0) continue; else threshold = degreeThreshold; packTime.start(); // pack leftover sets that are below threshold down for the next round for (int j = 0; j < l; j++) flag[j] = (S[j].degree > 0 && S[j].degree < threshold); intT ln = sequence::pack(S, ST, flag, l); // pack leftover sets greater than threshold above for this round for (int j = 0; j < l; j++) flag[j] = (S[j].degree >= threshold); intT lb = sequence::pack(S, ST+ln, flag, l); // copy prebucketed bucket i to end, also for this round for (int j = 0; j < currentB.n; j++) ST[j+ln+lb] = currentB.S[j]; lb = lb + currentB.n; // total number in this round l = ln + lb; // total number including those for next round swap(ST,S); // since pack is not in place set* SB = S + ln; // pointer to bottom of sets for this round packTime.stop(); if (lb > 0) { // is there anything to do in this round? manisTime.start(); intT work = processBucket(SB, elts, lb, threshold); totalWork += work; manisTime.stop(); packTime.start(); // check which sets were selected by manis to be in the set cover for (int j = 0; j < lb; j++) flag[j] = SB[j].degree < 0; // add these to inCover and label by their original ID int nNew = sequence::packIndex(inCover+nInCover, flag, lb); for (int j = nInCover; j < nInCover + nNew; j++) inCover[j] = SB[inCover[j]].id; nInCover = nInCover + nNew; packTime.stop(); cout << "i = " << i << " bc = " << currentB.n << " l = " << l << " lb = " << lb << " work = " << work << " new = " << nNew << " threshold = " << threshold << endl; } } cout << "Set cover size = " << nInCover << endl; cout << "Total work = " << totalWork << endl; cout << "Bucket Time = " << bucketTime.total() << endl; cout << "Manis Time = " << manisTime.total() << endl; cout << "Pack Time = " << packTime.total() << endl; free(elts); free(S); free(ST); free(flag); freeBuckets(allBuckets); return _seq<intT>(inCover, nInCover); }