给定 m x n 矩阵,其中 m <= n ,您必须选择条目,使其总和最大。
选择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
每行最佳(尚未采用)列
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)
此方法始终将先发现的行(或列)更高,这可能导致比平均结果更差
答案 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()