列出R中的所有整数组合
我所寻找的基本上是这个问题答案的R版本:。首先,答案使用java,我很难读懂它。其次,所有代码都使用“deque”,我想不出在R中实现它的方法。 我已经找到了几种算法来实现这一点,但它们都是用编程语言编写的,使用的是R中不可用的结构,如deques、heap或列表理解 我真正需要的是找到长度为N-1的所有向量列出R中的所有整数组合,r,R,我所寻找的基本上是这个问题答案的R版本:。首先,答案使用java,我很难读懂它。其次,所有代码都使用“deque”,我想不出在R中实现它的方法。 我已经找到了几种算法来实现这一点,但它们都是用编程语言编写的,使用的是R中不可用的结构,如deques、heap或列表理解 我真正需要的是找到长度为N-1的所有向量v,其中: sum(v*1:(N-1))==N 我认为只要我找到一种获得所有有序整数分区的方法,我自己就能做到这一点 以N=4为例,使用数字1到N-1的所有有序整数分区为: 1+1+1+1
v
,其中:
sum(v*1:(N-1))==N
我认为只要我找到一种获得所有有序整数分区的方法,我自己就能做到这一点
以N=4为例,使用数字1到N-1的所有有序整数分区为:
1+1+1+1
1+1+2
1+3
2+2
我实际上需要的是以下两种形式的输出:
c(1,1,1,1)
c(1,1,2)
c(1,3)
c(2,2)
或采用以下形式:
c(4,0,0)
c(2,1,0)
c(1,0,1)
c(0,2,0)
因为我应该能够自己将前一种格式转换为后一种格式。任何关于如何使用R解决此问题的提示都将不胜感激。后一种格式实际上是向量v
,使得和(v*1:3)
为4
编辑:
我自己的尝试:
rek = function(mat, id1, id2){
if(id1 + id2 != length(mat) + 1){ #If next state not absorbing
mat[id1] = mat[id1] - 1
mat[id2] = mat[id2] - 1
mat[id1+id2] = mat[id1+id2] + 1
out = mat
id = which(mat > 0)
for(i in id){
for(j in id[id>=i]){
if(j == i & mat[i] == 1){
next
}
out = rbind(out, rek(mat,i,j))
}
}
return(out)
}
}
start = c(n, rep(0, n-2))
states = rbind(start, rek(start, 1, 1))
states = states[!duplicated(states), ] #only unique states.
这是难以置信的低效。例如。当n
=11时,我的声明
在删除重复项之前有120000多行,只剩下55行
编辑2:
使用下面描述的parts()
函数,我想到了:
temp = partitions::parts(n)
temp = t(temp)
for(i in 1:length(temp[,1])){
row = temp[i,]
if(any(row>(n-1))){#if absorbing state
next
}
counts = plyr::count(row[row>0])
newrow = rep(0,n-1)
id = counts$x
numbs = counts$freq
newrow[id] = numbs
states = rbind(states, newrow)
}
states = states[-1,]#removing the first row, added manually
这正好给了我向量v
,这样和(v*1:(N-1))
就是N
如果有人感兴趣,这将在结合理论中使用,作为描述N个个体之间可能的关系的一种方法,当所有个体都相关时省略。以N=4为例:
(4,0,0)--没有个人是相关的
(2,1,0)--两个人是相关的,其余的不是
(0,2,0)——个体是成对相关的
(1,0,1)--三个人是相关的,另一个人不是。希望来自包
分区的部分可以有所帮助
library(partitions)
N <- 4
res <- unique(lapply(asplit(parts(N),2),function(x) sort(x[x>0])))[-1]
如果您想编写一个自定义的基R函数,下面是一个递归版本
f <- function(n, vhead = n, v = c()) {
if (n == 0) return(list(v))
unlist(lapply(seq_len(min(n, vhead)), function(k) f(n - k, k, c(k,v))), recursive = FALSE)
}
f您需要使用它来解决的真正问题有多大?我希望可以解决非常大的N,但我认为有一个限制。我实际上提出了一个非常低效的方法,它在N=13左右“消亡”。为此,我发现排列是:N=2:1,N=3:2,N=4:4,N=5:6,N=6:10,N=7:14,N=8:21,N=9:29,N=10:41,N=11:55,N=12:76,然而,我不是100%确定它是正确的,因为我没有检查我是否得到了所有的东西,因为算法太慢了。对于更复杂的数据结构,我推荐@polkas谢谢。这将是非常有用的,也在我的未来功能。谢谢你的回答。parts()
对于以您的答案的形式回答我的实际问题非常有用,它包含在其他函数中。但是wirtitingt(parts(N))
的格式实际上很容易满足我的基本需求。我不明白在问这个问题之前,我在谷歌搜索时怎么没有出现这个库。
f <- function(n, vhead = n, v = c()) {
if (n == 0) return(list(v))
unlist(lapply(seq_len(min(n, vhead)), function(k) f(n - k, k, c(k,v))), recursive = FALSE)
}
res <- Filter(function(x) length(x)>1,f(N))