我必须解决依赖问题。情况如下:
我有一个包含相应依赖关系的包列表:
pkg1: []
pkg2: [pkg1]
pkg3: [pkg1, pkg2]
pkg4: [pkg1 | pkg 3]
pkg5: [pkg1 | pkg2 | pkg3]
注意“|”两个或多个依赖关系之间相当于“OR”
我的目标是让每个程序包计算安装它所需的最小依赖项集。
例如:
minimum_set(pkg)
应该返回
pkg1, pkg2
答案 0 :(得分:1)
某种蛮力是不可避免的,因为这个问题的非常有限的形式是NP完全的。
具体来说,即使除了其中一个软件包之外的所有软件包的依赖关系列表只包含由OR连接的条款,我们也可以简单地将NP完全Hitting Set问题减少到它。假设我们有一个Hitting Set的实例,其中X是包含元素x_1,...,x_n和S的地面集合,是X的k个子集S_1,...,S_k的集合,每个i有S_i \ subseteq X,我们想要命中:然后对于地面集X中的每个元素x_i,创建一个没有依赖关系的包x_i,并且对于每个集合S_j \ subseteq X,创建一个包s_j,它具有作为其依赖关系的所有包x_k \ in S_j ,由OR运营商连接。最后再创建一个“root”包r,其中包含与s连接的k包s_1,...,s_k作为其依赖关系。现在,找到minimum_set(r)
将找到原始HS问题的最小尺寸命中集 - 这些是与选择安装的包x_i子集相对应的地面集元素。因此,如果你能以某种方式在多项式时间内实现minimum_set()
,那么你已经在多项式时间内解决了Hitting Set和其他所有NP完全问题。
答案 1 :(得分:0)
根据这些包的规模(即假设不存在会导致堆栈溢出的大量排列),您可以执行递归查找每个分支以获取每个依赖项的最小值。
伪代码[python-ish style]:
def minimum_set(pkg):
pkg_dependencies = pkg.dependencies()
if len(pkg_dependencies) < 1:
#Package has no dependencies
return dict(pkg, 0)
min_dps = []
for dp in pkg_dependencies:
if isOR(dp):
min_dp = min(minimum_set(dp).value()).key()
min_dps.extend(min_dp)
return min_dps
这应该有希望返回一个列表,就像您要求的特定包所需的最小依赖包数量一样。