我的问题与露天矿中矿石块的开采有关。如下所述,块具有pecedência的关系。 在这个表示中我们有6个块,其中:
在这种情况下,如果已经提取了1,2和3,我们只能“提取”块6,如果已经提取了2,3,4,则只提取块7,如果已经提取了3,4,5,则提取块8,块9如果已经提取了6,7,8。
UIPreviewInteraction
从这个直接的先例列表中,我想要一个方法,可以帮助获得大于9个块(1060到100000块之间的实例)的以下“完整的先例列表”。
color=blue;
答案 0 :(得分:0)
您可以在topological order中迭代块。这是一种可行的方法:
def precedents_transitive(blocks, precedents):
num_blocks = len(precedents)
# Mapping between block ids and indices
mapping = {b: i for i, b in enumerate(blocks)}
# Direct precedents as sets
ps = list(map(set, precedents))
# Transitive precedents as sets, starts with direct precedents
ps_transitive = list(map(set, precedents))
# Remaining blocks to visit
remaining = set(blocks)
# Visited blocks
visited = set()
while remaining:
# Find a non-visited block such that all its precedents have been visited
for block in remaining:
i_block = mapping[block]
if ps[i_block] <= visited:
break
else:
# If we get here the input was not valid
raise ValueError('Invalid precedents.')
# Add transitive precedents of direct predecessors
ps_transitive[i_block].update(*(ps_transitive[mapping[pred]] for pred in ps[i_block]))
remaining.remove(block)
visited.add(block)
return list(map(sorted, ps_transitive))
以下是您的数据测试:
# List of blocks
blocks = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# List of direct precedents
p = [[] for i in blocks]
p[0] = []
p[1] = []
p[2] = []
p[3] = []
p[4] = []
p[5] = [1, 2, 3]
p[6] = [2, 3, 4]
p[7] = [3, 4, 5]
p[8] = [6, 7, 8]
p_transitive = precedents_transitive(blocks, p)
print(p_transitive)
输出:
[[], [], [], [], [], [1, 2, 3], [2, 3, 4], [3, 4, 5], [1, 2, 3, 4, 5, 6, 7, 8]]
答案 1 :(得分:0)
首先让我们构建一个更有趣的例子:
pit = """
1 2 3 4 5 6 7 8 9 10 11
12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 32
33 34 35
36
"""
direct_predecessors = {}
row_below = []
for line in pit.strip().split( '\n' )[ ::-1 ]:
row_current = [ int( x ) for x in line.split() ]
for i, item in enumerate( row_below ):
direct_predecessors[ item ] = row_current[ i : i + 3 ]
row_below = row_current
(注意:与您的问题不同,前导查找键是从零开始的,但值是从一开始的,我选择使用字典,其中值条目可以直接用作键。事实上,如果我没有明确地将它们转换为int()
,则块标签可以是任意字符串。如果我们打印内容:
for key, value in sorted( direct_predecessors.items() ):
print( '%r : %r' % ( key, value ) )
然后我们得到以下输出:
12 : [1, 2, 3]
13 : [2, 3, 4]
14 : [3, 4, 5]
15 : [4, 5, 6]
16 : [5, 6, 7]
17 : [6, 7, 8]
18 : [7, 8, 9]
19 : [8, 9, 10]
20 : [9, 10, 11]
21 : [12, 13, 14]
22 : [13, 14, 15]
23 : [14, 15, 16]
24 : [15, 16, 17]
25 : [16, 17, 18]
26 : [17, 18, 19]
27 : [18, 19, 20]
28 : [21, 22, 23]
29 : [22, 23, 24]
30 : [23, 24, 25]
31 : [24, 25, 26]
32 : [25, 26, 27]
33 : [28, 29, 30]
34 : [29, 30, 31]
35 : [30, 31, 32]
36 : [33, 34, 35]
好的,现在回答你的问题:给定直接前辈,获得所有(直接和间接)前辈。递归方法是一种方法:
def Predecessors( n ):
result = set( direct_predecessors.get( n, [] ) )
result |= { indirect for direct in result for indirect in Predecessors( direct ) }
return result
如果我们尝试一个例子:
print( Predecessors( 31 ) )
输出如下:
set([4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 19, 24, 25, 26])