在给定约束的2D矩阵中寻找最佳选择

时间:2018-05-12 11:15:25

标签: algorithm performance search optimization

问题陈述

给定 m x n 矩阵,其中 m <= n ,您必须选择条目,使其总和最大。

  • 但是,您只能选择每行一个条目每列最多一个
  • 性能也是一个很大的因素,这意味着可以找到不是最优的选择以降低复杂性(只要它比选择随机条目更好)

实施例

  • 有效选择:

    valid valid empty col

  • 选择无效: (每行一个条目,每列最多一个)

    invalid empty row and row dublicate invalid dublicate col

我的方法

  1. 选择k个随机排列的最佳

    A = createRandomMatrix(m,n)
    selections = list()
    
    for try in range(k):
      cols = createRandomIndexPermutation(m) # with no dublicates
      for row in range(m):
        sum += A[row, cols[row]]
        selections.append(sum)
    
    result = max(selections)
    

    n 明显大于 m

  2. 时,此附录表现不佳
  3. 每行最佳(尚未采用)列

    A = createRandomMatrix(m,n)
    takenCols = set()
    
    result = 0
    for row in range(m):
      col = getMaxColPossible(row, takenCols, A)
      result += A[row, col]
      takenCols.add(col)
    

    此方法始终将先发现的行(或列)更高,这可能导致比平均结果更差

1 个答案:

答案 0 :(得分:2)

这听起来与矩形线性分配问题(RLAP)完全相同。这个问题可以有效地(在渐近复杂度方面;有点在立方时间内)解决(到全局最优)并且可以获得许多软件。

基本方法是LAP +虚拟变量,LAP修改或更常用的算法,如网络流量(最小成本最大流量)。

您可以从(pdf)开始:

  

Bijsterbosch,J。和A. Volgenant。 “解决矩形赋值问题和应用程序。”运筹学年刊181.1(2010):443-462。

使用python的常见科学堆栈的小python示例:

正如评论中所提到的那样

编辑,否定成本矩阵(我所做的,受LP描述的推动)并不是在Munkres /匈牙利方法文献中所做的。策略是从成本矩阵构建利润矩阵,现在反映在示例中。这种方法将导致非负成本矩阵(有时假设;如果重要,则取决于实施)。有关详细信息,请参阅this question

代码

import numpy as np
import scipy.optimize as sopt    # RLAP solver
import matplotlib.pyplot as plt  # visualizatiion
import seaborn as sns            # """
np.random.seed(1)

# Example data from
# https://matplotlib.org/gallery/images_contours_and_fields/image_annotated_heatmap.html
# removed a row; will be shuffled to make it more interesting!
harvest = np.array([[0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0],
                    [2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0],
                    [1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0],
                    [0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0],
                    [0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0],
                    [1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1]],)
harvest = harvest[:, np.random.permutation(harvest.shape[1])]

# scipy: linear_sum_assignment -> able to take rectangular-problem!
# assumption: minimize -> cost-matrix to profit-matrix:
#                         remove original cost from maximum-costs
#                         Kuhn, Harold W.:
#                         "Variants of the Hungarian method for assignment problems."
max_cost = np.amax(harvest)
harvest_profit = max_cost - harvest

row_ind, col_ind = sopt.linear_sum_assignment(harvest_profit)
sol_map = np.zeros(harvest.shape, dtype=bool)
sol_map[row_ind, col_ind] = True

# Visualize
f, ax = plt.subplots(2, figsize=(9, 6))
sns.heatmap(harvest, annot=True, linewidths=.5, ax=ax[0], cbar=False,
            linecolor='black', cmap="YlGnBu")
sns.heatmap(harvest, annot=True, mask=~sol_map, linewidths=.5, ax=ax[1],
            linecolor='black', cbar=False, cmap="YlGnBu")
plt.tight_layout()
plt.show()

输出

enter image description here