'Generate a 2d array with fixed sum of its rows and columns (Python)
I'm trying to generate a 2d array with random positive integers with a fixed sum of each column and row.
For example:
Sum of each column: [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]
Sum of each row: [48, 14, 24, 52, 30]
I'm trying to solve this issue by this code:
def restore_matrix(row, column):
rr = len(row)
cc = len(column)
matrix = [[0] * cc for i in range(rr)]
for i in range(rr):
for j in range(cc):
rr = min(row[i], column[j])
r = rr
matrix[i][j] = r
row[i] -= matrix[i][j]
column[j] -= matrix[i][j]
return matrix
columns = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]
rows = [48, 14, 24, 52, 30]
my_answer = restore_matrix(rows, columns)
print(my_answer)
li = [sum(x) for x in my_answer]
print(li)
This code gives me one solution, can I make this code generate random integers each time I run this code?
Solution 1:[1]
Can't leave comments, but the answer by Frank Yellin wouldn't work if as the question says, it's to work for positive numbers.
Imagine the following:
3 , 0 , - (12)
3 , 4 , - (12)
- , - , - (12)
(12), (12), (12)
You have to put 9 in cell(0,2).
3 , 0 , 9 (12) OK
3 , 4 , - (12)
- , - , - (12)
(12), (12), (12)
But now what to put in cell(1,2)?
- If we put cell(1,2)=5, then the second row would pass but the third column overshoots.
3 , 0 , 9 (12) OK
3 , 4 , 5 (12) OK
- , - , - (12)
(12), (12), (12)
NOK
- If we put cell(1,2)=3, then last column would pass but the second column falls short.
3 , 0 , 9 (12) OK
3 , 4 , 3 (12) NOK
- , - , - (12)
(12), (12), (12)
OK
But at any rate, here's the implementation of what they said (I was also working on it at the same time and post it in case it helps):
import random
def restore_matrix(row, column):
# making a duplicate of the passed list so as not to mutate the global lists.
row_sums = [*row]
col_sums = [*column]
len_rows = len(row_sums)
len_cols = len(col_sums)
matrix = [[0] * len_cols for i in range(len_rows)]
for i in range(len_rows-1):
for j in range(len_cols-1):
_min = min(row_sums[i], col_sums[j])
num = random.randint(0, _min)
matrix[i][j] = num
row_sums[i] -= num
col_sums[j] -= num
# last col
j = len_cols - 1
for i in range(len_rows-1):
num = row_sums[i]
matrix[i][j] = num
row_sums[i] -= num
col_sums[j] -= num
# last row
i = len_rows - 1
for j in range(len_cols):
num = col_sums[j]
matrix[i][j] = num
row_sums[i] -= num
col_sums[j] -= num
return matrix
columns = [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
rows = [48, 14, 24, 52, 30]
my_answer = restore_matrix(rows, columns)
print(my_answer)
sum_of_rows = [sum(r) for r in my_answer]
sum_of_cols = [sum([r[c] for r in my_answer]) for c in range(len(columns))]
print(sum_of_rows == rows)
print(sum_of_cols == columns)
Again, this doesn't guarantee that last row will be positive.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
