如果给定单个行和列的和,如何用随机数填充m x n矩阵?



我需要写一个Java程序来生成一个3行5列的矩阵,这样:(1)每一行的和为R。(2)列和为C1, C2, C3, C4, C5。

满足这些条件中的任何一个都非常简单,例如,为了满足条件(1),我将生成0到1之间的5个随机数,计算它们的和,然后将它们中的每一个按比例放大,使它们的和等于r。

或者我可以满足条件(2)通过生成3个随机数并将它们放大,使它们的和为C1(或C2, C3,等等)

但是我不知道如何同时满足这两个条件。

如果有关系,所有的数字都是正的。它们可以是整数,也可以不是整数。

R1, R2, R3是每一行的和。它们被定义为R

R1 = R2 = R3 = R

E是一切。所有行和所有列的和

E = 3*R;
E = C1 + C2 + C3 + C4 + C5;
3 * R = C1 + C2 + C3 + C4 + C5;
R = (C1 + C2 + C3 + C4 + C5) / 3;
R = C1/3 + C2/3 + C3/3 + C4/3 + C5/3

根据定义,您可以通过列和除以行数来填充每个单元格。

如果输入使得3 * R ≠ C1 + C2 + C3 + C4 + C5不存在解。

这是一个演示,为什么你总是可以一次平衡两对。

使用C值5、9、13、7、8:

|  A |  B | C  | D  | E  |
+----+----+----+----+----|
1|1.67|  3 |4.33|2.33|2.67|
2|1.67|  3 |4.33|2.33|2.67|
3|1.67|  3 |4.33|2.33|2.67|
-------------------------/

选择距离为1的对,向右移动一步,直到到达最后一列。注意,在E->A

AB,BC,CD,DE,EA;

则距离为2的所有对,

AC,BD,CE,DA,EB,

你会重复,只要你的对距离

然后,对于每个水平对,你需要一个相等和相反的对。在同样的过程中被发现。1:2, 2:3, 3:1 .

(对于任意无序对p,两列之间的距离总是等于或小于矩阵宽度的一半。我们从每一列开始选取每一对右手对并选取距离递增的一对

对于任何矩阵,你有(int)w/2 * (int)h/2唯一的无序对。(这是截断而不是舍入)

完整的代码如下:

import java.util.Random;
class MySolver{
public static double[][] initMatrix(int w, int h, double[] C) {
double[][] matrix = new double[w][h];
for (int i = 0; i < w; ++i)
for (int j = 0; j < h; ++j)
matrix[i][j] = C[i] / h;
return (matrix);    
}
public static void main(String[ ] args) {
int w = 5;
int h = 3;
double[] C = { 5, 9, 13, 7, 8 };
double[][] matrix = initMatrix(w, h, C);
Random rand = new Random();
double delta;
for (int i = 0; i < h; ++i) {
for (int j = 0; j < w; ++j)
System.out.printf("|%5.2f", matrix[j][i]);
System.out.printf("|%n");
}
System.out.printf("%n%n%n");
for (int i = 0; i < w; ++i) {
for (int j = 0; j < w / 2; ++j) {
for (int k = 0; k < h; ++k) {
for (int l = 0; l < h / 2; ++l) {
delta = rand.nextDouble()  * Math.min(matrix[i][k], matrix[(i+j+1) % w][(k+l+1) % h]);;
System.out.printf("%5.2f%n", delta);
matrix[i][k] -= delta;
matrix[(i+j+1) % w][(k+l+1) % h] -= delta;
matrix[i][(k+l+1) % h] += delta;
matrix[(i+j+1) % w][k] += delta;
}
}
}
}
System.out.printf("%n%n%n");

for (int i = 0; i < h; ++i) {
delta = 0;
for (int j = 0; j < w; ++j) {
delta += matrix[j][i];
System.out.printf("|%5.2f", matrix[j][i]);
}
System.out.printf("|  %.2f%n", delta);
}
System.out.printf("%n");
for (int i = 0; i < w; ++i) {
delta = 0;
for (int j = 0; j < h; ++j)
delta += matrix[i][j];
System.out.printf("|%5.2f", delta);
}
}
}

输出:

| 1.67| 3.00| 4.33| 2.33| 2.67|
| 1.67| 3.00| 4.33| 2.33| 2.67|
| 1.67| 3.00| 4.33| 2.33| 2.67|

1.59
2.47
<REDACTED for brevity>
0.09
0.51

| 0.16| 6.05| 2.76| 2.09| 2.94| 14.00
| 1.63| 2.36| 8.37| 0.08| 1.55| 14.00
| 3.21| 0.59| 1.87| 4.83| 3.51| 14.00
| 5.00| 9.00|13.00| 7.00| 8.00