G
B
H
A D
E
C I
F
1 2 3 (level)
假设上述结构中有一棵树 每个节点都与其父节点和子节点链接。此外,每个节点都与先前添加的一个节点链接,并且与当前节点有些相关。
现在假设每个节点都有五个属性:
node.name == 'B'
,则node.parent.name == 'A'
为True)node.name == 'G'
,则node.previous.name == 'H'
为True,但如果node.name == 'H'
,则node.previous.name == 'B'
为True)node.name == 'A'
,则[c.name for c in node.children] == ['B', 'D', 'C']
为True)现在,如果我想搜索树以查找具有给定数字n的一组相关节点的最大值,该数字表示组大小。 (例如,节点E涉及节点I和节点C,但节点F,但是,节点I与节点E无关,但确实与节点F和节点C有关)
我究竟如何设计此功能
答案 0 :(得分:0)
以下是我对您的问题的理解:您希望枚举大小为n的所有相关节点组,并找到此类组中节点值的最大总和。
这是一个算法: 对于每个节点,保留其子节点的排序列表,并根据子节点的值进行排序。迭代所有节点。对于每个节点, 计算以下四个数字的最大值:
当前节点+最大的n-1个孩子
当前节点+最大的n-2个孩子+父母
当前节点+最大的n-2个孩子+上一个
当前节点+最大的n-3个孩子+父母+上一个
请记住处理特殊情况,例如,如果某个节点的子节点很少,父节点=之前等。
(实际上,您可能只是将节点的所有相关节点放在一个排序列表中并选择最大的n-1)。
击>
由于一个节点显然可能与其子女的孩子有关,因此上述情况不起作用。
我又给了它一个:
对于每个节点,保留一个列表l
,其索引是使用节点+最多i-1个孩子获得的最大值。
对于每个叶节点,这只是[0, leaf.value, ...]
。
对于每个节点,假设有一个孩子。然后node.l
很容易计算,简单来说就是:
node.l[i] = child.l[i-1] + node.value
如果我们然后将另一个子节点添加到此节点,我们可以使用来自子节点的0到n-1个节点,并依赖于最佳节点。这是使用(种类,参见下面的代码)计算的
node.l[i] = max(node.l[i], node.l[i-k] + child.l[i])
这在下面实现。
由于node.previous
,很容易适应额外的连通性。当计算所有node.l
时,我们只是在结尾的节点列表中进行额外的传递。
for node in nodes:
# l[i] = maximum value obatined using node + up to i-1 children
node.l = [0 for i in xrange(n+1)]
node.visited = False
Q = [] # Queue
for leaf in nodes:
if len(leaf.children) > 0: continue
Q.append(leaf)
leaf.visited = True
while Q:
t = Q.pop(0)
l = [0]
for i in xrange(1, n+1):
l.append(t[i-1] + t.value)
t.l = l
if not t.parent: break
for l in xrange(0, n+1):
for i in xrange(l, n+1):
t.parent.l[i] = max(t.parent[i], t.parent[i-l] + t[l])
if not t.parent.visited:
t.parent.visited = True
Q.append(t.parent)
m = 0
for node in nodes:
m = max(m, node[n], node[n-1] \
+ (node.previous.value if node.previous else 0))
print m
运行时间为n*n*(number of nodes)
。