[英]Find a list of unique representatives (elements) from a list of arrays
我有一個由n
arrays 組成的列表(或數組)。 每個數組攜帶從0
到n-1
的任意整數子集(數組中不重復數字)。 n=3
的示例是:
l = [np.array([0, 1]), np.array([0]), np.array([1, 2])]
我想從每個數組中選擇一個數字作為其代表,這樣沒有兩個 arrays 具有相同的代表,並按照與 arrays 相同的順序列出它們。 換句話說,為 arrays 選擇的數字必須是唯一的,並且整個代表集將是數字0
到n-1
的排列。 對於上面的列表,它將是唯一的:
representatives = [1, 0, 2]
可以保證我們的名單中存在這樣的代表名單,但我們如何找到他們。 如果有多個可能的代表列表,則可以隨機選擇其中任何一個。
這是你要找的嗎?
def pick_one(a, index, buffer, visited):
if index == len(a):
return True
for item in a[index]:
if item not in visited:
buffer.append(item)
visited.add(item)
if pick_one(a, index + 1, buffer, visited):
return True
buffer.pop()
visited.remove(item)
return False
a = [[0, 1], [0], [1, 2]]
buffer = []
pick_one(a, 0, buffer, set())
print(buffer)
Output:
[1, 0, 2]
您要求的是二分圖的最大匹配,其左右集分別由您的 arrays 及其唯一元素索引。
networkx
模塊知道如何找到這樣的最大匹配:
import numpy as np
import networkx as nx
import operator as op
def make_example(n,density=0.1):
rng = np.random.default_rng()
M = np.unique(np.concatenate([rng.integers(0,n,(int(n*n*density),2)),
np.stack([np.arange(n),rng.permutation(n)],
axis=1)],axis=0),axis=0)
return np.split(M[:,1],(M[:-1,0] != M[1:,0]).nonzero()[0])
def find_matching(M):
G = nx.Graph()
m = len(M)
n = 1+max(map(max,M))
G.add_nodes_from(range(n,m+n), biparite=0)
G.add_nodes_from(range(n),biparite=1)
G.add_edges_from((i,j) for i,r in enumerate(M,n) for j in r)
return op.itemgetter(*range(n,m+n))(nx.bipartite.maximum_matching(G))
例子:
>>> M = make_example(10,0.4)
>>> M
[array([0, 4, 8]), array([9, 3, 5]), array([7, 1, 3, 4, 5, 7, 8]), array([9, 0, 4, 5]), array([9, 0, 1, 3, 5]), array([6, 0, 1, 2, 8]), array([9, 3, 5, 7]), array([8, 1, 2, 5]), array([6]), array([7, 0, 1, 4, 6])]
>>> find_matching(M)
(0, 9, 5, 4, 1, 2, 3, 8, 6, 7)
這可以在幾秒鍾內完成數千個元素:
>>> M = make_example(10000,0.01)
>>> t0,sol,t1 = [time.perf_counter(),find_matching(M),time.perf_counter()]
>>> print(t1-t0)
3.822795882006176
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.