[英]Finding the most similar list out of a collection of lists, online
我有一组列表,每个列表都代表图表上的一条路径:
list1 = [1,2,3,6] # directed edge from 1->2, 2->3, 3->6
list2 = [8,3,5,6]
list3 = [9,1,3,4]
list4 = [7,8,1,4]
我也有图的邻接矩阵。
在每个时间步我都有一个优势:例如时间步 0: [1,2]
,时间步 1: [3,6]
,并且在每个时间步我必须找到最相似的列表,考虑到以前的时间脚步。 意思是,最完整的列表。
什么是有效的方法?
我尝试使用一种简单的方法,将传入边缘与每个列表中的每个边缘进行比较,但考虑到我有大量列表,每个列表都有大量边缘,这太慢了。
更新:在每个时间步写一个示例输入和 output。
时间步 0: 输入[1,2]
, output: list1
time step 1: input [8,3]
, output: list1, list2 #equally complete
时间步 2: 输入[3,6]
, output: list1
更新 2:感谢@Nuclearman,我编写了解决方案(也许是天真?)
list1 = [1,2,3,6] # directed edge from 1->2, 2->3, 3->6
list2 = [8,3,5,6]
list3 = [9,1,3,4]
list4 = [7,8,1,4]
lists_dict = {
'list1' : list1,
'list2' : list2,
'list3' : list3,
'list4' : list4
}
edges = {
'list1' : len(list1) - 1,
'list2' : len(list2) - 1,
'list3' : len(list3) - 1,
'list4' : len(list4) - 1
}
covered_edges = {
'list1' : 0,
'list2' : 0,
'list3' : 0,
'list4' : 0
}
completeness = {
'list1' : covered_edges['list1']/edges['list1'],
'list2' : covered_edges['list2']/edges['list2'],
'list3' : covered_edges['list3']/edges['list3'],
'list4' : covered_edges['list4']/edges['list4']
}
graph = {}
for list_name in lists_dict.keys():
idx = 0
while idx < len(lists_dict[list_name])-1:
node1 = lists_dict[list_name][idx]
node2 = lists_dict[list_name][idx+1]
if node1 in graph.keys(): #if exist
graph[node1][node2] = list_name
else: #if doesnt exist
graph[node1] = {node2: list_name}
idx+=1
times= [[1,2],[3,5],[5,6],[8,1],[7,8]]
for time in times:
edge_in_list = graph[time[0]][time[1]] #list name
covered_edges[edge_in_list] +=1
print(covered_edges)
completeness = {
'list1' : covered_edges['list1']/edges['list1'],
'list2' : covered_edges['list2']/edges['list2'],
'list3' : covered_edges['list3']/edges['list3'],
'list4' : covered_edges['list4']/edges['list4']
}
mx = max(completeness.values())
max_list = [k for k, v in completeness.items() if v == mx]
print(max_list)
print('')
尝试使用邻接列表设置作为嵌套 hash 来表示图形
IE:您可以通过这种方式设置整个示例(不记得这是否是有效的 python):
graph = {
1: {2: [1], 3: [3], 4: [4] },
2: {3: [1] },
3: {6: [1], 5: [2], 4: [3] },
5: {6: [2] },
7: {8: [4] },
8: {3: [2], 1: [4] },
9: {1: [3] },
}
然后,您只需记录每个列表中剩余的数量,并将其存储到具有O(log N)
或更好的 find-min(或 find-max 只需调整键)的数据结构中,查找、添加项目和删除项目。 根据您如何定义完整性,您可能需要做一些数学运算。 IE:您可能需要存储总边和覆盖边,然后使用[(total - covered) / total, list #]
或作为数据结构的键。 这样,即使有多个具有相同完整性的列表,您也可以快速找到该列表。 对于您想要的结果,返回所有具有最高完整性的列表。
上图让您快速确定每条边进入哪个列表,然后在剩余计数中查找该边,并将每个列表的计数减一。 IE:您可以看到graph[1][2]
是列表 1, graph[8][3]
是列表 2, graph[3][6]
也是列表 1。
为了性能,您可能还希望保留一组已经看到的边缘并跳过任何已经看到的边缘,尽管这可能需要也可能不需要,并且可能会或可能不会是您想要处理它的方式。
性能与您需要更改的列表数量成正比,使其对 output 敏感。 如果提供的示例是 go 上的任何内容,那么与列表数量相比,您需要为每个传入边更新的列表计数数量可能非常小。 如果在所有L
个列表中总共有E
个边并且您需要在线处理K
个边并且这些K
边导致处理总共A
个列表( A
是一个 output 敏感变量,并且取决于列表之间有多少重叠,例如您给出的重叠为零,因为每个边缘都有一个与之关联的列表,但不清楚是否会保留更多列表和边缘)。 那么性能是O(E + K + AlogL)
我相信,因为那些A
处理的列表每个都需要一个log L
查找来查找 + 更新列表计数。 E
是构建图所需的预处理。 这似乎基本上是最优的,除非有别的东西。 可能比您目前拥有的O(K*E)
好得多,除非您有极高的重叠 ( A
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.