【问题标题】:greedy set cover algorithm贪心集覆盖算法
【发布时间】:2013-09-19 11:46:35
【问题描述】:

所以,我从

获取了这段代码

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

我正在尝试理解套装和套装封面,所以我对此进行了一些修改。

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

可以看出,U 的值是 1,2,3,4。没有一组中有 4 个。 我不懂权重,所以把它们设为 1。

预期输出:set([1,2])set([3])set([1,2,3]),或覆盖可用最大值的内容。

【问题讨论】:

  • 实际输出是多少?
  • 无输出,进入无限循环。

标签: python algorithm set


【解决方案1】:

你的代码的问题是没有没有覆盖,因为有一个额外的4。我的理解是,根据定义,集合覆盖问题指定S中所有集合的并集必须等于U。所以额外的 4 不应该在那里。

由于您的程序在找到完美覆盖之前不会停止(即只要len(R) != 0),因此它永远不会在此输入上停止。您将无效输入传递给算法。

在旁注中,我强烈建议不要使用 except 子句来测试零除法。这不是try/except 的好用法;我认为这是你应该在跳跃之前查看的情况。

【讨论】:

  • 谢谢!我想我明白了。想到的一件事是,如果我根据输入的其余部分在 S 中自动添加一个 set([4])。我应该很好。另外,请原谅我对代码的废话重用。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 2022-12-07
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多