从具有多个结果的矩阵构建地图

时间:2017-06-24 04:14:54

标签: python algorithm numpy math

我有一个输入矩阵,其n x m维未知,由1和0填充

例如,5x4矩阵:

A = array(
  [[1, 0, 0, 0],
   [1, 0, 0, 0],
   [0, 1, 1, 0],
   [0, 1, 1, 0],
   [1, 0, 1, 1]])

目标

我需要在尽可能多的列和行之间创建一个1:1的映射,其中该位置的元素为1.

我对1:1地图的意思是每列和每行最多可以使用一次。

理想的解决方案具有最多的映射即。使用的行和列最多。它还应避免使用较大矩阵不能很好地扩展的详尽组合或操作(实际上,最大尺寸应为100x100,但没有声明的限制,因此它们可以更高)

以上是

的可能结果
array([[ 1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  1.]])

更多示例:

input:
0 1 1
0 1 0
0 1 1

output (one of several possible ones):
0 0 1
0 1 0
0 0 0 

另一个(这表明可能出现一个问题)

input:
0 1 1 1
0 1 0 0
1 1 0 0

a good output (again, one of several):
0 0 1 0
0 1 0 0
1 0 0 0

a bad output (still valid, but has fewer mappings)
0 1 0 0
0 0 0 0
1 0 0 0

更好地展示他们如何成为多重输出

input: 
0 1 1
1 1 0

one possible output:
0 1 0
1 0 0

a second possible output:
0 0 1
0 1 0

a third possible output
0 0 1
1 0 0

我做了什么?

我现在有一种非常愚蠢的处理方式,但根本无法保证工作。基本上我只是用单位矩阵构建一个滤波器矩阵(因为它是完美的映射,每一行和每一列都使用一次)然后我随机交换它的列(n次)并用它过滤原始矩阵,记录过滤器具有最佳结果的矩阵。

My [non] solution:

import random
import numpy as np

# this is a starting matrix with random values
A = np.array(
  [[1, 0, 0, 0],
   [1, 0, 0, 0],
   [0, 1, 1, 0],
   [0, 1, 1, 0],
   [1, 0, 1, 1]])

# add dummy row to make it square
new_col = np.zeros([5,1]) + 1
A = np.append(A, new_col, axis=1)

# make an identity matrix (the perfect map)
imatrix = np.diag([1]*5)

# randomly swap columns on the identity matrix until they match. 
n = 1000

# this will hold the map that works the best
best_map_so_far = np.zeros([1,1])

for i in range(n):
    a, b = random.sample(range(5), 2)
    t = imatrix[:,a].copy()
    imatrix[:,a] = imatrix[:,b]
    imatrix[:,b] = t

    # is this map better than the previous best?
    if sum(sum(imatrix * A)) > sum(sum(best_map_so_far)):
        best_map_so_far = imatrix

    # could it be? a perfect map??
    if sum(sum(imatrix * A)) == A.shape[0]:
        break
    # jk.

# did we still fail
if sum(sum(imatrix * A)) != 5:
    print('haha')

# drop the dummy row
output = imatrix * A
output[:,:-1]

#... wow. it actually kind of works.

2 个答案:

答案 0 :(得分:1)

这个怎么样?

module.exports.change=function(obj){
    obj.a=2;
}

这能为您提供足够的解决方案吗?如果是这样,它应该比你拥有的效率更高。

答案 1 :(得分:1)

让我试一试。我建议的算法并不总能给出最优解,但也许有人可以改进它。

  1. 您可以始终互换两列或两行而不更改问题。此外,通过跟踪变化,您可以始终回到原始问题。

  2. 我们打算用1s填充主对角线。通过交换列或行或两者来获取左上角的前1个。现在第一行和第一行是固定的,我们不再触摸它们了。我们现在尝试用1填充对角线上的第二个元素,然后修复第二行和第二列。等等。

  3. 如果右下子矩阵为零,我们应该尝试通过使用整个矩阵交换两列或两行但在对角线中保留现有的1来将1带到那里。 (这就是问题所在。如果一个交换可以提供帮助,很容易有效地检查。但可能需要至少两个交换,或者更多。)

  4. 当在对角线上不能再获得1时,我们停止。

  5. 所以,虽然算法并不总是最优的,但也许可以提出额外的规则来如何交换列和行,以便尽可能用1s填充对角线。