我有以下矩阵:
([2, 5, 5, 10]
[7, 1, 4, 1]
[1, 3, 3, 9])
如果列总和,则结果为:
[10, 9, 12, 20]
我的目标是确定对不同行中的元素进行排序的最佳方法,以便最小化列总和中的最大元素.
例如,一种可能性是:
([2, 5, 5, 10]
[7, 1, 4, 1]
[1, 9, 3, 3])
如果列总和,则结果为:
[10, 15, 12, 14]
这是比第一个更好的解决方案.
最简单的方法是检查所有可能的排列,但随着矩阵的增长,这种方法在python中变得非常慢.
有没有想过以更快的方式做到这一点?
最佳答案 首先,请加强您的要求
"Can I produce a matrix that minimizes the difference between the max sum and the min sum of each column in my matrix"
这很好,因为:
>它将满足您的原始要求,因此解决这个问题可以解决您的问题
>有了这个要求,很容易在每次迭代中显示次优性,这样我们就可以说服自己贪婪的方法会起作用.
要实现一个贪婪的解决方案,只需保持垫子的运行总和,并为每一行将当前行中的最低值插入最高总和列.这可确保色谱柱尽可能均匀堆积.
这将为n行中的每一行和每行2mlogm排序采用m个插入,因此应在O(n * m n * 2 * mlogm)运行,因此O(nmlogm).
output_mat = []
input_mat = [
[2, 5, 5, 10],
[7, 1, 4, 1],
[1, 3, 3, 9],
]
row_size = len(input_mat[0])
running_sum = [0] * row_size
for row in input_mat:
sorted_idx = [
x[0] for x in
sorted(enumerate(row), key=lambda x: x[1])
]
sum_sorted_idx = [
x[0] for x in
sorted(enumerate(running_sum), key=lambda x: x[1], reverse=True)
]
new_val_row = [None] * row_size
for col_idx,val_idx in zip(sum_sorted_idx, sorted_idx):
new_val_row[col_idx] = row[val_idx]
running_sum[col_idx] += row[val_idx]
output_mat.append(new_val_row)
for x in output_mat:
print ">> %s" % x
print(running_sum)
输出:
>> [2, 5, 5, 10]
>> [7, 1, 4, 1]
>> [3, 9, 3, 1]
[12, 15, 12, 12]