简体   繁体   中英

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.

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 (ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM