我开发了一个函数,可以从向量
vec
生成排列,并可以选择限制输出数量。我想确保同一位置上的值不会出现超过 3 次。
此函数generate_permutations从
vec
生成长度longitud_permutaciones的排列。然后,它会过滤这些排列,以确保没有元素在同一位置重复超过 3 次。如果结果排列的数量超过 cantidad_resultados,则仅返回指定数量的排列。
library(combinat)
library(gtools)
generate_permutations <- function(vec, permutation_length, result_count) {
# Get all unique permutations of the specified length
permutations <- permutations(length(vec), permutation_length, vec)
# Filter permutations to ensure no element repeats more than 3 times in the same position
filtered_permutations <- permutations[rowSums(matrix(permutations, ncol = permutation_length) == rep(vec, each = permutation_length)) <= 3, ]
# Show only the specified number of results if it's less than the total
if (result_count < nrow(filtered_permutations)) {
filtered_permutations <- filtered_permutations[1: result_count, ]
}
return(filtered_permutations)
}
# Example usage
vec <- c(1, 2, 3, 4)
permutation_length <- 3
result_count <- 5 # Change this value as needed
result <- generate_permutations(vec, permutation_length, result_count)
print(result)
这是细分:
输入参数:
vec
:生成排列的向量。
longitud_permutaciones
:每个排列的长度。
cantidad_resultados
:所需的结果排列数量。
生成排列:
它使用
gtools
包中的排列函数从 longitud_permutaciones
生成长度为 vec
的所有唯一排列。
过滤排列:
然后过滤这些排列以确保没有元素在同一位置重复超过 3 次。这是通过检查排列的每个位置中每个元素的计数来完成的。 限制结果:
如果结果排列总数超过
cantidad_resultados
,则仅返回前 cantidad_resultados
排列。
输出:
它返回过滤后的排列作为结果。 此函数提供了一种根据特定约束生成和过滤排列的方法,确保生成的排列满足指定的标准。
我做了以下事情
# Filter the permutations to ensure that no element repeats more than 3 times in the same position
filtered_permutations <- permutations[rowSums(apply(permutations, 1, function(row) {
table(row) <= 3
})) == permutation_length, ]
我们想要过滤排列以确保没有元素在同一位置重复超过 3 次。
我们使用
apply()
函数将函数应用于排列矩阵的每一行。
在函数内部,table(row) <= 3
计算行中每个元素的出现次数,并检查是否有任何元素出现超过 3 次。
rowSums()
然后对每行的结果求和,指示有多少元素违反约束。
我们将此总和与 permutation_length 进行比较,以确保所有元素都满足每个排列的约束。
满足约束的排列将被保留,而那些不满足约束的排列将被过滤掉。
[,1] [,2] [,3]
\[1,\] 1 2 3
\[2,\] 1 2 4
\[3,\] 1 3 2
\[4,\] 1 3 4
\[5,\] 1 4 2
我需要获得的输出如下,例如,同一位置没有数字重复超过3次。
1 2 3
1 3 2
1 4 2
2 1 4
2 3 4
要求输出中任何值的出现次数不得超过 3 次。澄清一下,这对于设计联合场景很有用。
您可以将
split
!x
按 x
、replace
第一个 n
值与 TRUE
、unsplit
沿原始 x
进行排列矩阵的子集化。
> sub_prmt <- \(v, len, n) {
+ prmt <- RcppAlgos::permuteGeneral(v, len)
+ slc <- \(x, n) {
+ split(!x, x) |>
+ lapply(replace, seq_len(n), TRUE) |>
+ unsplit(x)
+ }
+ matrix(prmt[apply(prmt, 2, slc, n=n)], ncol=ncol(prmt))
+ }
>
> (res <- sub_prmt(vec, perm_len, res_count))
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 4
[3,] 1 3 2
[4,] 2 3 4
[5,] 2 4 2
[6,] 2 4 3
[7,] 3 1 3
[8,] 3 1 4
[9,] 3 3 1
[10,] 4 4 1
[11,] 4 1 2
[12,] 4 2 1
检查结果:
> apply(res, 2, tabulate)
[,1] [,2] [,3]
[1,] 3 3 3
[2,] 3 3 3
[3,] 3 3 3
[4,] 3 3 3
使用
RcppAlgos::permuteGeneral
,觉得更快。
数据:
vec <- c(1, 2, 3, 4)
perm_len <- 3
res_count <- 3