对于给定的元组,您可以将元组的元素映射到每组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 更简单。