Algorithm 打印安装软件包所需的最小软件包集
我必须创建一个表示包之间依赖关系的数据结构 我想我可以简单地使用一个图表,但问题是一些软件包可能依赖于其中一个“可选”软件包,我们必须选择其中哪一个最适合安装(基本上,从这些可选选择中,我们需要安装最好的) 例如,假设我有以下情况:Algorithm 打印安装软件包所需的最小软件包集,algorithm,data-structures,graph,dependencies,packages,Algorithm,Data Structures,Graph,Dependencies,Packages,我必须创建一个表示包之间依赖关系的数据结构 我想我可以简单地使用一个图表,但问题是一些软件包可能依赖于其中一个“可选”软件包,我们必须选择其中哪一个最适合安装(基本上,从这些可选选择中,我们需要安装最好的) 例如,假设我有以下情况: 包装1: 包装2:包装1 包装3:包装1,包装2 包装4:包装1 |包装3 包装5:包装1,包装2 |包装3 这种情况意味着: 包1没有依赖项 包2依赖于包1(我们需要安装包1) 包3依赖于包1和包2(我们需要同时安装这两个) 软件包4依赖于软件包1或3(我们可以安
这种试图选择哪个更好安装的方法似乎导致了某种递归算法,这已经让我大吃一惊。我们可以将其建模为伪布尔优化问题
假设有
k个
包。定义k个布尔变量x_i
,其中x_i
为真,当且仅当最终选择安装软件包时。因此,目标是最小化x_i
的总和,其中1可以创建具有两种类型节点的有向图:
节点,其子节点使用AND逻辑组合包
节点,其子节点使用OR逻辑组合或
- 当您访问一个
节点时,您要计算其子节点的依赖项的总数包
#/usr/bin/env蟒蛇3
课程包:
#建造师
定义初始化(自身、名称、依赖项):
self.name=名称
self.dependencies=set(依赖项)
#需要打印包裹吗
定义(自我):
返回self.name
#此方法返回此包的最佳依赖项集
def getOptimalDependencies(自):
optimalDependencies=set()
对于self.dependencies中的依赖项:
optimalDependencies=optimalDependencies.union(dependency.getOptimalDependencies())
添加(自我)
返回最优性依赖项
类别或名称:
#建造师
定义初始化(自,依赖项):
self.dependencies=set(依赖项)
#此方法返回最佳的依赖项集
#与此“或”组合的包的
def getOptimalDependencies(自):
optimalDependencies=set()
对于self.dependencies中的依赖项:
alternativeDependencies=dependency.getOptimalDependencies()
如果len(最佳依赖项)=0或len(可选依赖项)
然后,您可以创建示例的包,如下所示:
package1 = Package("package1", [])
package2 = Package("package2", [package1])
package3 = Package("package3", [package1, package2])
package4 = Package("package4", [Or([package1, package3])])
package5 = Package("package5", [package1, Or([package2, package3])])
要获取包5的最佳依赖项列表,您可以调用包5.getOptimalDependencies()
如果我们将其打印为:
print(','.join(map(str, package5.getOptimalDependencies())))
我们得到:
package2,package1,package5
如果你有依赖循环,你必须为它插入一些控件。我已经用python添加了一些代码来说明这个想法。然后,您可以用自己选择的语言重新实现。该算法可以通过避免每次访问包的节点时重新计算包的依赖关系来改进,但我选择保持代码的简单性,以便更易于阅读为什么
getoptimerationdependencies
方法应该找到最短路径?为什么我不明白为什么…你可以用归纳法来证明。您知道每个叶节点的最佳依赖项集(那些没有传出弧的节点,因此没有依赖项)。如果您知道给定节点的每个子节点的最佳依赖关系,那么您就知道该节点的最佳依赖关系:对于包
节点,它将是其子节点依赖关系的并集;对于或节点,它将是其子节点依赖关系中最小的一组。我们基本上是从图的叶子开始访问图,然后一直访问我们想要查找其依赖关系的节点。您的函数有一个问题(通常的解决方案)。假设我们有以下情况:A:B | C,D | E
<代码>B:G,H,M
<代码>C:K,N
<代码>D:G,H,M<代码>E:L,J。如果我们运行您的算法,它将为pa返回错误的答案
(1 - x_5) + x_2 + x_3 >= 1
x_k
x_k = 1
package1 = Package("package1", [])
package2 = Package("package2", [package1])
package3 = Package("package3", [package1, package2])
package4 = Package("package4", [Or([package1, package3])])
package5 = Package("package5", [package1, Or([package2, package3])])
print(','.join(map(str, package5.getOptimalDependencies())))
package2,package1,package5