微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何计算大阶乘的比率而没有不必要的溢出?

如何解决如何计算大阶乘的比率而没有不必要的溢出?

我正在编写一个程序(如果需要的话,请用R编写),在该程序中,我需要计算元素向量的唯一排列数,该向量可以包含重复值。 mathematical formula很简单:元素总数的阶乘除以每个唯一元素计数的阶乘的乘积。但是,即使实际答案不是很大,天真地计算结果也很可能导致溢出。例如:

# x has 200 elements,but 199 of them are identical
x <- c(rep(1,199),2)
num_unique_permutations <- factorial(length(x)) / prod(factorial(table(x)))

如果没有溢出,则num_unique_permutations将为200!/(199!* 1!)=200。但是,两者均为200!和199!溢出两倍的最大值,因此实际结果为NaN。只要答案本身不溢出,是否有一个很好的方法可以始终避免溢出(或下溢)进行此计算? (或者也许,只要它不在length(x)溢出的范围之内?)


(请注意,R在大多数数值计算中都使用双精度数,但是问题并不特定于双精度数。任何具有范围的数值类型都存在相同的问题。而且,我也不关心对浮点数损失一点精度数学,因为我只是用它来获取某物的大致上限。

解决方法

在底数R中,使用numer <- lfactorial(length(x)) denom <- sum(lfactorial(table(x))) exp(numer - denom) #[1] 200 来计算分子和分母的对数。然后求出适当的差值。

num_unique_permutations <- function(x){
  numer <- lfactorial(length(x))
  denom <- sum(lfactorial(table(x)))
  exp(numer - denom)
}

num_unique_permutations(x)
#[1] 200

可以很容易地将其编写为函数。

useEffect
,

您可以使用gmp库。

library(gmp)
factorial(as.bigz(length(x))) / prod(factorial(as.bigz(table(x))))
#[1] 200

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。