【问题标题】:How to create a matrix of 0s and 1s such that rows and columns sum up to particular value?如何创建一个由 0 和 1 组成的矩阵,使行和列总和为特定值?
【发布时间】:2018-04-05 11:54:17
【问题描述】:

我需要生成一个包含n 列和m 行的矩阵,其中每个单元格可以是01,这样每列中的数字之和等于c 和中的数字之和每行等于r。如果不可能(大部分时间可能),它应该有列总和到c+/-d 和行到r+/-d 以便 max(d over all rows and columns) 尽可能小。换句话说,每一行的总和都应该接近r,每一列的总和都应该接近c

为了说明当不存在完美解决方案时我在寻找什么,这个解决方案:

1.1.1.......
1.1.1.......
...1..1...1.
...1.1..1...
....1...1..1

比这个解决方案更好:

1.1.1.......
1.1.1.......
...1..1...1.
...1.1..1...
....11..1...

因为最后一行的总和为 0(与 1 相比)与前一个解决方案的总和更远离所需的行总和 2。

创建一个仅包含行的矩阵很容易 - 对具有精确r 1s 的向量进行排列。 如何满足第二个条件?找到一个总和太高而另一列太低的列并交换一些数字?这会有帮助吗,需要多长时间,甚至会终止,如果不可能得到完美的结果,我什么时候停止?有没有更好的办法?

您可以使用伪代码或您选择的语言或只是随机的简介。

我找到了Finding if binary matrix exists given the row and column sums,它谈到了回答是否可能,甚至在可能的情况下构建解决方案。如果不可能,这样的解决方案将有非常大的 ds。

还有这篇论文https://www.sciencedirect.com/science/article/pii/S0012365X06003980,我不是很懂,但似乎也与构建完美解决方案有关

【问题讨论】:

    标签: javascript python r matrix random


    【解决方案1】:

    这可以通过整数线性规划来完成。

    library(lpSolve)
    
    # inputs
    nr <- 3  # no of rows
    nc <- 3  # no of cols
    r <- 2   # sum of each row equals r
    c <- 2   # sum of each col equals c
    
    obj <- rep(1, nr * nc)
    const.mat <- rbind(
     t(rep(1, nc) %x% diag(nr)),  # this matrix multiplied by c(m) is row sums
     (diag(nc) %x% t(rep(1, nr)))  # this matrix multiplied by c(m) is col sums
    )
    const.rhs <- c(rep(r, nr), rep(c, nc))
    out <- lp(obj = obj, const.mat = const.mat, const.dir = "=", const.rhs = const.rhs, 
      all.bin = TRUE)
    
    out
    ## Success: the objective function is 6 
    
    matrix(out$solution, nr, nc)
    ##      [,1] [,2] [,3]
    ## [1,]    0    1    1
    ## [2,]    1    0    1
    ## [3,]    1    1    0
    

    【讨论】:

    • 非常好的解决方案!
    • 如果存在这样的矩阵,它会很好用,我真的很喜欢它的简单性,LP 总是让我感到惊讶。但如果矩阵不可能,它将不会创建近似值。如何写出最小化方程? BTW,你和数学家有关系吗? :)
    • 不相关。假设您正在寻找附近的 r 和 c,我认为您将不得不尝试蛮力尝试在双循环中围绕所需的 r 和 c 范围。
    • 另请注意,nr * r = nc * c = 矩阵中没有一个。因此 c = nr * r / nc 因此可以搜索附近的 r(单个循环),而不是在 r 和 c 上循环。此外,如果该公式没有给出整数,那么我们可以立即拒绝该 r。
    【解决方案2】:

    您可以为此使用igraph 包中的sample_degseq 函数,该函数创建具有给定顶点度数的图形。该图的邻接矩阵将具有您想要的属性。

    library(igraph)
    row_col_sum = 3 
    dim = 8
    g = sample_degseq(rep(row_col_sum,dim), method = "simple.no.multiple")
    as_adj(g)
    

    输出:

    8 x 8 sparse Matrix of class "dgCMatrix"
    
    [1,] . . . . . 1 1 1
    [2,] . . 1 1 1 . . .
    [3,] . 1 . . 1 . 1 .
    [4,] . 1 . . . 1 . 1
    [5,] . 1 1 . . . 1 .
    [6,] 1 . . 1 . . . 1
    [7,] 1 . 1 . 1 . . .
    [8,] 1 . . 1 . 1 . .
    

    希望这会有所帮助!

    【讨论】:

    • 这很好,但是如果 r != c - 行的总和应该不同于列的总和呢?或者 n !=m - 它不是方阵?
    • 抱歉,我认为n!=m 不可能通过这个实现实现。 r!=c 是可能的,因为您可以在算法中指定入度和出度。但是,通常没有可行的解决方案。
    猜你喜欢
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 2019-05-25
    相关资源
    最近更新 更多