Энная комбинация

Короткий ответ - Вы, не может.:) (кроме возможно как корень, когда это было бы больше с точностью до, говорят, Вы не были должны.)

Unixes только позволяют количество набора ссылок на каталоги - ".." из всех его детей и"." из себя. Что-либо еще - потенциально рецепт для очень запутанного дерева каталогов. Это - по-видимому, проектное решение Ken Thompson.

(Однако по-видимому, Машина времени Apple действительно делает это:))

14
задан Sami 21 November 2009 в 19:18
поделиться

3 ответа

Note you can generate the sequence by recursively generating all combinations with the first element, then all combinations without. In both recursive cases, you drop the first element to get all combinations from n-1 elements. In Python:

def combination(l, r):
    if r == 0:
        yield []
    elif len(l) == r:
        yield l
    else:
        for c in (combination(l[1:], r-1)):
            yield l[0:1]+c
        for c in (combination(l[1:], r)):
            yield c

Any time you're generating a sequence by making a choice like this, you can recursively generate the kth element by counting how many elements a choice generates and comparing the count to k. If k is less than the count, you make that choice. Otherwise, subtract the count and repeat for the other possible choices you could make at that point. If there are always b choices, you can view this as generating a number in base b. The technique still works if the number of choices varies. In pseudocode (when all choices are always available):

kth(k, choicePoints)
    if choicePoints is empty
        return empty list
    for each choice in head of choicePoints:
        if k < size of choice
            return choice and kth(k, tail of choicePoints)
        else
            k -= size of choice
    signal exception: k is out-of-bounds

This gives you a 0-based index. If you want 1-based, change the comparison to k <= size of choice.

The tricky part (and what is unspecified in the pseudocode) is that the size of a choice depends on previous choices. Note the pseudocode can be used to solve a more general case than the problem.

For this specific problem, there are two choices (b= 2) and the size of the 1st choice (i.e. including the 1st element) is given by n-1Cr-1. Here's one implementation (which requires a suitable nCr):

def kthCombination(k, l, r):
    if r == 0:
        return []
    elif len(l) == r:
        return l
    else:
        i=nCr(len(l)-1, r-1)
        if k < i:
            return l[0:1] + kthCombination(k, l[1:], r-1)
        else:
            return kthCombination(k-i, l[1:], r)

If you reverse the order of the choices, you reverse the order of the sequence.

def reverseKthCombination(k, l, r):
    if r == 0:
        return []
    elif len(l) == r:
        return l
    else:
        i=nCr(len(l)-1, r)
        if k < i:
            return reverseKthCombination(k, l[1:], r)
        else:
            return l[0:1] + reverseKthCombination(k-i, l[1:], r-1)

Putting it to use:

>>> l = [6, 4, 2, 1]
>>> [kthCombination(k, [6, 4, 2, 1], 3) for k in range(nCr(len(l), 3)) ]
[[6, 4, 2], [6, 4, 1], [6, 2, 1], [4, 2, 1]]
>>> powOf2s=[2**i for i in range(4,-1,-1)]
>>> [sum(kthCombination(k, powOf2s, 3)) for k in range(nCr(len(powOf2s), 3))]
[28, 26, 25, 22, 21, 19, 14, 13, 11, 7]
>>> [sum(reverseKthCombination(k, powOf2s, 3)) for k in range(nCr(len(powOf2s), 3))]
[7, 11, 13, 14, 19, 21, 22, 25, 26, 28]
16
ответ дан 1 December 2019 в 07:19
поделиться

только набросок: расположите свои числа в верхней треугольной матрице кортежей:

A(n-1,n-1)   
Aij = [i+1, j-1]

если вы сначала пройдете строку матрицы, вы получите комбинации в порядке возрастания для двух элементов. Если обобщить до трех элементов, представьте, что строки вашей матрицы - это еще одна треугольная матрица, а не вектор. Это как бы создает угол куба.

По крайней мере, так я подошел к проблеме

позвольте мне уточнить это, вам не нужно хранить матрицу, вам нужно будет вычислить индекс. Позвольте мне разобраться с размерным примером, который вы в принципе могли бы расширить до 20 измерений (бухгалтерский учет может быть ужасным).

ij = (i*i + i)/2 + j // ij is also the combination number
(i,j) = decompose(ij) // from ij one can recover i,j components
I = i // actual first index
J = j + 1 // actual second index

этот двухмерный пример работает для любого числа n, и вам не нужно сводить в таблицу перестановки.

1
ответ дан 1 December 2019 в 07:19
поделиться

Один из способов сделать это - использовать свойства битов. Это все еще требует некоторого перечисления, но вам не нужно перечислять каждый набор.

Для вашего примера у вас есть 4 числа в вашем наборе. Итак, если вы генерируете все возможные комбинации из 4 чисел, вы можете перечислить их следующим образом:

{6, 4, 2, 1}

0000 - {(no numbers in set)}
0001 - {1}
0010 - {2}
0011 - {2, 1}
...
1111 - {6, 4, 2, 1}

Посмотрите, как каждый «бит» соответствует тому, «входит ли это число в ваш набор»? Здесь мы видим, что существует 16 возможностей (2 ^ 4).

Итак, теперь мы можем пройти и найти все возможности, у которых включены только 3 бита. Это расскажет нам обо всех существующих комбинациях «3»:

0111 - {4, 2, 1}
1011 - {6, 2, 1}
1101 - {6, 4, 1}
1110 - {6, 4, 2}

И давайте переписываем каждое из наших двоичных значений как десятичные:

0111 = 7
1011 = 11
1101 = 13
1110 = 14

Теперь, когда мы это сделали - ну, вы сказали, что хотите «3-е» "перечисление. Итак, давайте посмотрим на третье по величине число: 11. Который имеет битовый шаблон 1011. Что соответствует ... {6, 2, 1}

Круто!

В принципе, вы можете использовать ту же концепцию для любого набора. Итак, теперь все, что мы сделали, - это перевели задачу с «перечисления всех наборов» на «перечисление всех целых чисел». Это может быть намного проще для вашей проблемы.

7
ответ дан 1 December 2019 в 07:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: