gpt4 book ai didi

php - 计算排列的因子秩(N 选择 K)

转载 作者:搜寻专家 更新时间:2023-10-31 20:48:05 24 4
gpt4 key购买 nike

我最近了解到 CNSFNS ,因为它们对我来说看起来很优雅,所以我决定尝试并实现使用这些技术生成组合和排列的方法。我完成了从 n choose k 组合转换为 CSN 排名的方法,反之亦然,但我正在用头撞墙尝试用 n choose k(唯一)排列。

感谢@Joshua我得到了 unranking(FNS 到排列)方法工作:

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;
}

这是我目前对排名(FNS 的排列)方法的尝试:

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;
}

这些是我正在使用的辅助函数:

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));
}

问题是,Pr_Rank() 方法仅在 n = k ( demo ) 时返回正确的排名:

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

我使用上面链接的维基百科文章和 this MSDN article 指导自己,我知道他们都没有考虑 k 大小的子集,但我完全不知道这样的逻辑会是什么样子......

我也尝试使用谷歌搜索和搜索现有问题/答案,但还没有找到任何相关内容。

最佳答案

在睡了一夜好觉并借助纸笔的帮助后,我想通了。如果有人感兴趣:


例如,第 42 个 5 选择 3 排列是 4-2-5 ,但如果您查看 Pr_Unrank() , 其中array_slice()被调用时,您会注意到实际排列(按字典顺序)实际上是 4-2-5[-1-3] ,最后两个元素被丢弃,所以你最终只会得到 k元素。

这对于计算因子的十进制表示形式 (3-1-2[-0-0]) 非常重要:

  • 4-2-5 = (2! * 3) + (1! * 1) + (0! * 2) = 9
  • 4-2-5-1-3 = (4! * 3) + (3! * 1) + (2! * 2) + (1! * 0) + (0! * 0) = <强> 82

仍然,82不是正确答案。要得到它,我们必须将它除以以下结果:

  • Pr(5, 5) / Pr(5, 3) (=) (5 - 3)! = 120 / 60 = <强> 2

所以 82 / 241 ,我需要做的就是添加 1获得从 1 开始的排名。


Array // 5 choose 3 permutations
(
[1] => 1-2-3
[2] => 1-2-4
[3] => 1-2-5
[4] => 1-3-2
[5] => 1-3-4
[6] => 1-3-5
[7] => 1-4-2
[8] => 1-4-3
[9] => 1-4-5
[10] => 1-5-2
[11] => 1-5-3
[12] => 1-5-4
[13] => 2-1-3
[14] => 2-1-4
[15] => 2-1-5
[16] => 2-3-1
[17] => 2-3-4
[18] => 2-3-5
[19] => 2-4-1
[20] => 2-4-3
[21] => 2-4-5
[22] => 2-5-1
[23] => 2-5-3
[24] => 2-5-4
[25] => 3-1-2
[26] => 3-1-4
[27] => 3-1-5
[28] => 3-2-1
[29] => 3-2-4
[30] => 3-2-5
[31] => 3-4-1
[32] => 3-4-2
[33] => 3-4-5
[34] => 3-5-1
[35] => 3-5-2
[36] => 3-5-4
[37] => 4-1-2
[38] => 4-1-3
[39] => 4-1-5
[40] => 4-2-1
[41] => 4-2-3
[42] => 4-2-5
[43] => 4-3-1
[44] => 4-3-2
[45] => 4-3-5
[46] => 4-5-1
[47] => 4-5-2
[48] => 4-5-3
[49] => 5-1-2
[50] => 5-1-3
[51] => 5-1-4
[52] => 5-2-1
[53] => 5-2-3
[54] => 5-2-4
[55] => 5-3-1
[56] => 5-3-2
[57] => 5-3-4
[58] => 5-4-1
[59] => 5-4-2
[60] => 5-4-3
)

关于php - 计算排列的因子秩(N 选择 K),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11140505/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com