Omair .
Omair .

Reputation: 344

greedy set cover algorithm

So, I picked up this code from

How do I make my implementation of greedy set cover faster?

I am trying to understand sets and set cover so, I modify this a bit.

U = set([1,2,3,4])
R = U
S = [set([1,2]), 
     set([1]), 
     set([1,2,3]), 
     set([1]), 
     set([3]), 
     set([1,2]), 
     set([3]), 
     set([1,2,3])]
w = [1, 1, 1, 1, 1, 1, 1, 1]

C = []
costs = []

def findMin(S, R):
    minCost = 99999.0
    minElement = -1
    for i, s in enumerate(S):
        try:
            cost = w[i]/(len(s.intersection(R)))
            if cost < minCost:
                minCost = cost
                minElement = i
        except:
            # Division by zero, ignore
            pass
    return S[minElement], w[minElement]

while len(R) != 0:
    S_i, cost = findMin(S, R)
    C.append(S_i)
    R = R.difference(S_i)
    costs.append(cost)

print "Cover: ", C
#print "Total Cost: ", sum(costs), costs

As can be seen U has values 1,2,3,4. None of the sets have 4 in them. I don't understands weights, so have put them as 1.

Expected output: set([1,2]), set([3]), set([1,2,3]), or Something which covers the maximum available.

Upvotes: 1

Views: 2815

Answers (1)

senderle
senderle

Reputation: 150987

The problem with your code is that there is no cover, because there's an extra 4. My understanding is that by definition, the set cover problem specifies that the union of all sets in S must be equal to U. So that extra 4 shouldn't be there.

Since your program doesn't halt until it finds a perfect cover (i.e. as long as len(R) != 0) it will never halt on this input. You're passing invalid input to the algorithm.

On a side note, I would strongly recommend against a blanket except clause to test for zero division. That's not a good use of try/except; I think this is a case where you should look before you leap.

Upvotes: 1

Related Questions