我有一个n元组x = (x[0], .., x[n-1])
,其中元组的每个成员都来自一个不同的,有序的集S[i]
,而x[i] \in S[i]
。集合S[i]
都有不同的基数N[i]
。我想知道如何在集合S[i]
的情况下以词法顺序生成下一个元组。
示例:
S[0] = {0,1,2}
S[1] = {1,2,3,4}
S[2] = {8,9,7}
x = {2,2,7}
xnext = {2,3,8}
xnextnext = {2,3,9}
等
这不一定非常有效,只是根据当前元组元素和集合的封闭形式。如果它更容易,那就相当于将n元组视为集合中的索引。
答案 0 :(得分:0)
对于给定的元组,您可以将元组的元素映射到每组S
中的各自索引,然后尝试"递增"由此元组索引表示的mixed-radix数字。然后,取增加的"数字"并将其映射回元素元组。这是Python中的概念验证:
def next_tuple(x, S):
assert len(x) == len(S)
assert all(element in set_ for element, set_ in zip(x, S))
# compute the bases for our mixed-radix system
lengths = [len(set_) for set_ in S]
# convert tuple `x` to a mixed-radix number
indices = [set_.index(element) for element, set_ in zip(x, S)]
# try to increment, starting from the right
for k in reversed(range(len(indices))):
indices[k] += 1
if indices[k] == lengths[k]:
# case 1: we have a carry, rollover this index and continue
indices[k] = 0
else:
# case 2: no carry, map indices back to actual elements and return
return [set_[index] for index, set_ in zip(indices, S)]
# we have gone through each position and still have a carry.
# this means the "increment" operation overflowed, and there
# is no "next" tuple.
return None
S = [[0, 1, 2], [1, 2, 3, 4], [8, 9, 7]]
print("next tuple after {} is {}".format([2, 2, 7], next_tuple([2, 2, 7], S)))
print("all tuples in order:")
x = [0, 1, 8]
while x is not None:
print(x)
x = next_tuple(x, S)
最后请注意,如果您需要按顺序枚举整个笛卡尔积,则使用直接算法更简单,而不是重复使用next_tuple
,每次都必须重新计算索引。
答案 1 :(得分:0)
我使用这个伪代码让它工作:
# x = [2,2,7]
sets = [[0,1,2], [1,2,3,4], [8,9,7]]
def next_tuple(x):
for i, el in enumerate(x):
if(i < len(sets[i]) - 1):
x[i] = sets[i, sets[i].index(x[i])+1] // requires lists to have unique elements
return x
else :
x[i] = sets[i,0]
基本上你从元组中扫描一个字符,如果它可以递增,则递增它。如果没有,请将其设置为0并转到下一个字符。