【发布时间】:2021-12-07 18:11:45
【问题描述】:
假设我有一个如下所示的无向循环序列:
1 —— 2 —— 3
/ \
1 1
| |
3 2
\ /
3 —— 2 —— 3
假设我有以下 3 个序列,由数字列表表示:
seq1 = [1,1,3,3,2,3,2,1,3,2] # anticlockwise from top left
seq2 = [3,2,3,3,1,1,2,3,1,2] # clockwise from bottom right
seq3 = [3,1,2,3,2,3,3,1,1,2] # clockwise from top right
由于序列是无方向的,所有3个序列本质上是相同的,并且代表上面的循环序列。实际上,我有数千个这样的无向循环序列,因此不可能对每一对进行比较。因此,我想创建一个唯一标识符,可以代表每个唯一的无向循环序列。例如,上面 3 个序列的标识符应该相同。
我的想法是将这种类型的序列视为圆形图。然后我可以将边权重分配为两个连接节点之间的差异,并找到遍历所有节点的路径,同时最大化所有边权重的总和。下面是我的 Python 实现:
def identifier(seq):
delta_sum = float('-inf')
res_seq = []
for i in range(len(seq)):
new_seq = seq[i:] + seq[:i]
ds = sum([new_seq[j+1] - new_seq[j] for j in range(len(seq)-1)])
if ds > delta_sum:
delta_sum = ds
res_seq = new_seq
if -ds > delta_sum:
delta_sum = -ds
res_seq = new_seq[::-1]
return ','.join(map(str, res_seq))
print(identifier(seq1))
print(identifier(seq2))
print(identifier(seq3))
输出:
1,1,2,3,1,2,3,2,3,3
1,1,2,3,1,2,3,2,3,3
1,2,3,2,3,3,1,1,2,3
显然我的算法不起作用。它为前两个序列创建相同的标识符,但为第三个序列创建一个不同的标识符。谁能建议一种相对快速的算法(最好是 Python 代码)来为这种序列创建唯一标识符?
以下是一些相关的问题,但不完全是我想要实现的目标:
How to check whether two lists are circularly identical in Python
【问题讨论】:
-
您链接的第二个线程有什么问题,使用字典顺序最小的字符串旋转?如果问题只是你的字符串是可逆的,你可以只使用原始或反向字符串的最小旋转。
-
我认为这可能更属于cs.stackexchange.com/questions/tagged/algorithms,因为它基本上是圆形图的哈希方法,不是吗?
-
@kcsquared 它只适用于有向序列
-
是的,我在评论的第二部分中提到了这一点。您的“无向序列”只是普通字符串在反转和循环旋转下的等价类。以顺时针顺序在序列上运行一次 LMSR 算法,以逆时针顺序运行一次,并将两者中的最小值作为您的标识符,有什么问题?
-
@kcsquared 如果他们相等怎么办?
标签: python algorithm sorting sequence circular-list