簡體   English   中英

有序列表的可逆組合生成器

[英]Invertible combination generator for ordered lists

我有代碼,其中給出了一個有序整數列表,我生成了幾個新列表,並且我需要能夠將這些列表與從 1 到 N 選擇 k(或 0 到(N 選擇 k)之間的整數一一對應)- 1)在python中)。

例如,如果我有一個 N=7,k=3,那么我可能會從列表 [0,1,2] 開始,我可能會枚舉 0。然后我生成列表 [0,1,3], [ 0,1,5] 和 [3,4,6],它們都需要由 0,...,34 范圍內的整數唯一標識。

我知道我可以使用 itertools 來生成有序列表,

itertools.combinations(range(7), 3)

但我需要一個反函數,它比簡單地搜索預先生成的列表更有效,因為我將使用大 N 並且每個列表引用大約 50 個新列表。

您可以在此處使用 itertools 配方中的配方:

def nth_combination(iterable, r, index):
    'Equivalent to list(combinations(iterable, r))[index]'
    pool = tuple(iterable)
    n = len(pool)
    if r < 0 or r > n:
        raise ValueError
    c = 1
    k = min(r, n-r)
    for i in range(1, k+1):
        c = c * (n - k + i) // i
    if index < 0:
        index += c
    if index < 0 or index >= c:
        raise IndexError
    result = []
    while r:
        c, n, r = c*r//n, n-1, r-1
        while index >= c:
            index -= c
            c, n = c*(n-r)//n, n-1
        result.append(pool[-1-n])
    return tuple(result)

用法示例:

>>> nth_combination(range(7), 3, 5)
(0, 2, 3)
>>> nth_combination(range(7), 3, 34)
(4, 5, 6)

扭轉:

from math import factorial
def get_comb_index(comb, n):
    k = len(comb)
    rv = 0
    curr_item = 0
    n -= 1
    for offset, item in enumerate(comb, 1):
        while curr_item < item:
            rv += factorial(n-curr_item)//factorial(k-offset)//factorial(n+offset-curr_item-k)
            curr_item += 1
        curr_item += 1
    return rv

示例用法:

>>> get_comb_index((4,5,6), 7)
34
>>> get_comb_index((0,1,2), 7)
0
>>> get_comb_index((0,2,4), 7)
6

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM