使用下面的函数我可以生成一些测试数据。你知道吗
import random, string
a = list(string.ascii_lowercase)
def gen_test_data():
s = []
for i in xrange(15):
p = random.randint(1,3)
xs = [random.choice(a) for i in xrange(p)]
s.append(xs)
return s
这是我的测试数据。你知道吗
[
['a', 's'],
['f', 'c'],
['w', 'z'],
['z', 'p'],
['z', 'u', 'g'],
['v', 'q', 'w'],
['y', 'w'],
['d', 'x', 'i'],
['l', 'f', 's'],
['z', 'g'],
['h', 'x', 'k'],
['b'],
['t'],
['s', 'd', 'c'],
['s', 'w', 'd']
]
如果一个字母与另一个字母共享列表,则它依赖于该字母,而该字母中的任何一个都依赖于其他字母。例如
x
依赖于['a','c','d','g','f','i','h','k','l','q','p','s','u','w','v','y', 'x','z']
这些依赖也是双向的。k
依赖于一切,包括x
但是x
并不依赖于b
或t
。这些可以放在不同的组中。你知道吗
我需要把名单分成尽可能多的非受抚养人群体。你知道吗
每个组将是组所依赖的所有字母的集合。非从属字母将是一组字母。你知道吗
上面的输出示例如下
[
['t'],
['b'],
['a','c','d','g','f','i','h','k','l','q','p','s','u','w','v','y', 'x','z']
]
我正试图编写一个函数来实现这一点,但无法找到正确的方法来正确地分组所有内容。你知道吗
这是一个典型的connected components问题。有许多有效的线性时间或近似线性时间算法来解决它,例如使用深度优先搜索之类的图搜索算法或联合查找数据结构。你知道吗
对于基于搜索的算法,您可以根据输入设置一个图,并连接输入子列表中的节点,然后对该图进行搜索,以找出哪些节点可以彼此访问。像NetworkX这样的图形库可以为您处理大多数实现,也可以自己编写。例如
这将使输入的大小呈线性。你知道吗
您也可以使用union-find data structure。联合查找数据结构将项与集相关联,每个集由一个代表性元素表示。它们支持两种操作:find,用于查找元素的代表;和union,用于获取两个元素并将其集合合并为一个集合。你知道吗
可以设置union find数据结构,对于输入中的每个子列表,将子列表的每个元素与子列表的第一个元素进行union。这将有效地将所有依赖元素分组,而不将任何独立元素连接在一起。你知道吗
对于union-find数据结构的标准实现,它是一个具有按秩合并和路径压缩的不相交集林,运行时的输入大小基本上是线性的。它会慢一点,慢一点的是输入的inverse Ackermann function,这对于所有实际的输入大小基本上都是不变的。你知道吗
下面是一种方法(使用递归算法):
这些是图的connected components,您可以使用
networkx
来生成它们:相关问题 更多 >
编程相关推荐