R 求最大和最小矩阵边际总可变性
有没有一种更优雅的方法可以根据二元矩阵的填充和大小来计算其边缘列总数的最大或最小可变性水平(CV)?考虑到所有行和列合计必须为非零。e、 gR 求最大和最小矩阵边际总可变性,r,matrix,R,Matrix,有没有一种更优雅的方法可以根据二元矩阵的填充和大小来计算其边缘列总数的最大或最小可变性水平(CV)?考虑到所有行和列合计必须为非零。e、 g foo(n_col, n_row, fill){ get maximum possible CV } 假设我们有一个名为m的矩阵,其中所有列和行的总计都是>0,但矩阵的填充量最小 m <- matrix(rep(0,25), nrow = 5) diag(m) <- 1 # [,1] [,2] [,3] [,4] [,5] #[1,]
foo(n_col, n_row, fill){ get maximum possible CV }
假设我们有一个名为m
的矩阵,其中所有列和行的总计都是>0
,但矩阵的填充量最小
m <- matrix(rep(0,25), nrow = 5)
diag(m) <- 1
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 0 0 0 0
#[2,] 0 1 0 0 0
#[3,] 0 0 1 0 0
#[4,] 0 0 0 1 0
#[5,] 0 0 0 0 1
variability1 <- sd(colSums(m))/mean(colSums(m))
variability1
# [1] 0
# the maximum and minimum for this fill is zero
# considering that all column and row totals must be > 0
m以下提供了该问题的另一种表述,作为对二元矩阵列和向量选择的优化,该二元矩阵最大化了给定填充的可变性。非正式参数的有效性,这个公式和由此产生的算法来解决它提供。生成的算法与OP的断言一致
按此方式填充矩阵列可保持边缘列总数的最大可变性
首先,将fill
定义为n\u行中1
的个数n\u col
通过n\u col
二进制矩阵m
。根据问题陈述的约束条件,m
是一个所有行和列总和都大于零的二进制矩阵,fill
是一个范围[max(n行,n列),n行*n列]
内的整数
问题是,对于[max(n行,n列),n行*n列]
范围内的fill
给定值,找到最大值
sd(colSums(m))/mean(colSums(m))
总之,m
,使得m
是一个二进制矩阵,其填充数量为1
,且所有行和列总和大于零
我们注意到,最好根据m
的列和向量来指定该优化问题的域,而不是m
本身。这是因为存在不同的m
,它们具有相同的列和向量,因此具有相同的目标值。将列和向量表示为x
,上述优化问题可以重新表述为最大化:
sd(x)/mean(x)
使得x
的每个元素都是范围[1,n_行]
中的整数,sum(x)
是fill
此外,由于sum(x)
被限制为等于fill
,对于给定的fill
,分母项均值(x)
在所有x
上都是常数。因此,要最大化的等效目标函数只是sd(x)
,或者等效为x
的方差
为了使x
的方差最大化,我们需要选择x
,以便在满足x
约束的同时,使其值之间的差异最大化。在这里,我们可以根据fill
归纳地思考这个问题。让我们假设对于给定的填充
,我们有x
的解决方案,该解决方案在满足约束的同时最大化x
的方差。问题是:当我们将fill
增加到fill+1
时,最大化其方差的新x
是什么?因为我们有一个约束,即sum(x)=fill
,并且x
中的每个元素都是一个整数,所以增加fill
意味着我们必须增加x
中的一个且仅增加一个元素。暂时放松x
中每个元素的上限约束(即x[i]
sd(x)/mean(x)
var(x + dx) = var(x) + gradient(var(x)) %*% dx + 1/2 * t(dx) %*% Hessian(var(x)) %*% dx
gradient(var(x))[i] = 2*(x[i]-mean(x))/(n_col-1), for all i in [1,n_col]
Hessian(var(x))[i,i] = 2/n_col , for all i in [1,n_col]
var(x_1 + dx_1) > var(x + dx)
var(x_1 + dx_1) = var(x_1) + gradient(var(x_1)) %*% dx_1 + 1/2 * t(dx_1) %*% Hessian(var(x_1)) %*% dx_1
<= var(x_1) + 2*(max(x_1)-mean(x_1))/(n_col-1) + constant
<= var(x) + 2*(max(x)-mean(x))/(n_col-1) + constant
= var(x + dx)
foo <- function(n_col, n_row, fill) {
## preallocate the vector of column sums x and initialize to NA
x <- rep(NA, n_col)
for (i in seq_len(n_col)) {
x[i] <- pmin.int(n_row, fill-(n_col-i))
fill <- fill - x[i]
}
## compute the variability given the vector of column sums x
sd(x)/mean(x)
}
foo <- function(n_col, n_row, fill) {
x <- pmin.int(pmax.int(cumsum(c(fill-n_col+1,rep(-n_row+1,n_col-1))),1),n_row)
## compute the variability given the vector of column sums x
sd(x)/mean(x)
}
n_col=5
n_row=5
variability <- sapply(max(n_col,n_row):(n_col*n_row), function(fill) foo(n_col, n_row, fill))
print(variability)
## [1] 0.0000000 0.3726780 0.6388766 0.8385255 0.9938080 0.8660254 0.8131156 0.8122329 0.8426501
##[10] 0.7319251 0.6666667 0.6404344 0.6443795 0.5414886 0.4707512 0.4330127 0.4259177 0.3049184
##[19] 0.1944407 0.0931695 0.0000000