Computando o Rank Factoradic de uma Permutação (N escolha K)

Eu aprendi recentemente sobreCNS eFNSe como eles parecem tão elegantes para mim, decidi tentar implementar métodos para gerar combinações e permutações usando essas técnicas. Eu terminei meu método para converter den escolha k combinações para uma classificação CSN e vice-versa, mas eu estou batendo minha cabeça contra a parede tentando fazer o mesmo comn escolha k permutas (únicas).

Graças a@Joshua Eu tenho odesorganizado (FNS para permutação) método de trabalho:

function Pr_Unrank($n, $k, $rank) { // rank starts at 1
    if ($n >= $k) {
        if (($rank > 0) && ($rank <= Pr($n, $k))) {
            $rank--;
            $result = array();
            $factoriadic = array();

            for ($i = 1; $i <= ($n - $k); ++$i) {
                $rank *= $i;
            }

            for ($j = 1; $j <= $n; ++$j) {
                $factoriadic[$n - $j] = ($rank % $j) + 1; $rank /= $j;
            }

            for ($i = $n - 1; $i >= 0; --$i) {
                $result[$i] = $factoriadic[$i];

                for ($j = $i + 1; $j < $n; ++$j) {
                    if ($result[$j] >= $result[$i]) {
                        ++$result[$j];
                    }
                }
            }

            return array_reverse(array_slice($result, 0 - $k));
        }
    }

    return false;
}

Esta é a minha tentativa atual declassificação (permutação ao FNS) método:

function Pr_Rank($n, $k, $permutation) {
    if ($n >= $k) {
        $result = range(1, $n);
        $factoriadic = array();

        foreach ($permutation as $key => $value) {
            $factoriadic[$k - $key - 1] = array_search($value, $result);
            array_splice($result, $factoriadic[$k - $key - 1], 1);
        }

        $result = 1;

        foreach (array_filter($factoriadic) as $key => $value) {
            $result += F($key) * $value;
        }

        return $result;
    }

    return false;
}

E estas são as funções auxiliares que estou usando:

function F($n) { // Factorial
    return array_product(range($n, 1));
}

function Pr($n, $k) { // Permutations (without Repetitions)
    return array_product(range($n - $k + 1, $n));
}

O problema é,aPr_Rank() método só retorna a classificação correta quandon = k (demonstração):

var_dump(Pr_Rank(5, 2, Pr_Unrank(5, 2, 10))); // 3, should be 10
var_dump(Pr_Rank(5, 3, Pr_Unrank(5, 3, 10))); // 4, should be 10
var_dump(Pr_Rank(5, 5, Pr_Unrank(5, 5, 10))); // 10, it's correct

Eu me guiei usando o artigo da Wikipedia que eu relacionei acima eeste artigo do MSDN, Eu sei que nenhum deles contempla subconjuntos de tamanho k, mas eu estou completamente no escuro como essa lógica seria ...

Eu também tentei pesquisando e pesquisando as perguntas / respostas existentes, mas nada relevante surgiu ainda.

questionAnswers(1)

yourAnswerToTheQuestion