这里记录几个源码,回去调试

  • 首先安利一个超重要的知识点:
  • edge-weighted-online-bipartite-matching
    • 简述
  • Improved Analysis of RANKING for Online Vertex-Weighted Bipartite Matching
  • Diverse Weighted Bipartite b-Matching
  • 唯一跑通的代码

首先安利一个超重要的知识点:

在md代码段里如果有注释符号,之前的时候都是一行一行敲回去
现在不需要了喂!1:is all you need
hhhh果不其然
其实就是在原先的代码段三点之前加一个小小的符号
[ ^ _ ^ ]就是把这个符号里面的空格去掉!完美了!!!!

edge-weighted-online-bipartite-matching

简述

这篇其实是老板他们组的系列文章之一
难得在网上有presentation视频和源码
我是在paperwithcode上面找到的
贴一下源码 顺便mark一下
Git的地址在这里:https://github.com/fahrbach/edge-weighted-online-bipartite-matching/blob/master/src/rounded-feasibility-1.py
paperwithcode这篇文章的link在这里
这篇文献实际出处在这里

from mpmath import mpmp.dps = 1000k_max = 8
kappa = mp.mpf(1.5)
gamma = mp.mpf(1)/mp.mpf(16)
Gamma = mp.mpf(0.50503484)a = [0.24748256,0.13684883,0.06415997,0.03009310,0.01413332,0.00666576,0.00318572,0.00158503,0.00088057
]
b = [0.25251744,0.12877617,0.06035174,0.02827176,0.01322521,0.00615855,0.00282566,0.00123280,0.00044028
]a = list(map(mp.mpf, a))
b = list(map(mp.mpf, b))def constraint_1():print('Constraint 1:')for k in range(k_max + 1):lhs = kappa*b[k]for l in range(k, k_max + 1):lhs += a[l]rhs = pow(2, -k)exponent = max(k - 1, 0)rhs *= pow(1 - gamma, exponent)print(' -', k, lhs, rhs, lhs <= rhs)if lhs > rhs:print('FAIL')print()def constraint_2():print('Constraint 2:')lhs = a[0] + b[0]rhs = 0.5print(' -', lhs, rhs, lhs <= rhs)if lhs > rhs:print('FAIL')print()  def constraint_3():print('Constraint 3:')for k in range(1, k_max + 1):lhs = a[k] + b[k]rhs = pow(mp.mpf(2), -k - 1) * pow(mp.mpf(1 - gamma), k-1) * (1 + gamma)print(' -', k, lhs, rhs, lhs <= rhs)if lhs > rhs:print('FAIL')print()def constraint_4():print('Constraint 4:')lhs = a[0]rhs = gamma/2print(' -', lhs, rhs, lhs >= rhs)if lhs < rhs:print('FAIL')print()def constraint_5():print('Constraint 5:')lhs = 0for l in range(k_max + 1):lhs += a[l]rhs = Gammaprint(' -', lhs, rhs, lhs >= rhs)if lhs < rhs:print('FAIL')print()def constraint_6():print('Constraint 6:')for k in range(1, k_max + 1):lhs = 0for l in range(k):lhs += a[l]lhs += 2*b[k]rhs = Gammaprint(' -', k, lhs, rhs, lhs >= rhs)if lhs < rhs:print('FAIL')print()def constraint_7():print('Constraint 7:')for k in range(1, k_max + 1):lhs = 0for l in range(k + 1):lhs += a[l]lhs += kappa*b[k]rhs = Gammaprint(' -', k, lhs, rhs, lhs >= rhs)if lhs < rhs:print('FAIL')print()def main():constraint_1()constraint_2()constraint_3()constraint_4()constraint_5()constraint_6()constraint_7()main()

Improved Analysis of RANKING for Online Vertex-Weighted Bipartite Matching

然后这篇好像是某一篇的延续 但具体不清楚了

from pulp import *
import numpy as np
import math
import time
import matplotlib.pyplot as plt
from collections import deque
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show
# Using the bound in lemma 4.1 in the paper
# NOT constraining g(x, y) = (1 + h(x) - h(y))/2# This is the discretization parameter
# Discretizes [0,1]^2 into an n-by-n grid
# Change this for finer/coarser discretizations
n = 50prob = LpProblem("problem", LpMaximize)t = LpVariable("t", lowBound=0, upBound=1)
prob += ta = [k/n for k in range(0, n+1)]# g(x, y) for x, y in discretized grid
g_vars = {(i,j): LpVariable(cat=LpContinuous, lowBound=0, upBound=1, name="g_{0}_{1}".format(i, j)) for i in range(0, n+1) for j in range(0, n+1)}## g(x, y) increasing in x
for j in range(0, n+1):for i in range(1, n+1):prob += g_vars[i, j] - g_vars[i-1, j] >= 0, "inceasing_constraint_{0}_{1}".format(i, j)## g(x, y) decreasing in y
for i in range(0, n+1):for j in range(1, n+1):prob += g_vars[i, j] - g_vars[i, j-1] <= 0, "decreasing_constraint_{0}_{1}".format(i,j)## dg(x, y)/dy >= g(x,y) - 1
for i in range(n):for j in range(n):prob += n*(g_vars[i, j+1] - g_vars[i, j]) >= g_vars[i+1, j]-1, "derivative_constraint_{0}_{1}".format(i, j)
# i=n;
for j in range(n):prob += n*(g_vars[n, j+1] - g_vars[n, j]) >= g_vars[n, j]-1, "derivative_constraint_{0}_{1}".format(n, j)## dg(x, y)/dx <= g(x,y)
for j in range(n):for i in range(n):prob += n*(g_vars[i+1, j] - g_vars[i, j]) <= g_vars[i,j+1], "derivative_constraint2_{0}_{1}".format(i,j)
# j = n
for i in range(n):prob += n*(g_vars[i+1, n] - g_vars[i, n]) <= g_vars[i,n], "derivative_constraint2_{0}_{1}".format(i,n)## g(1, y) - g(x, y) >= g(1, y') - g(x, y') for all x, y' > y
for i in range(0,n+1):for j in range(0, n+1):for k in range(j, n+1):prob += g_vars[n, j] - g_vars[i, j] >= g_vars[n, k] - g_vars[i, k]## s(gamma, tau, y) represents min_{theta <= gamma} (1-g(theta, y)) + int_0^theta g(x, y)dx + int_theta^gamma g(x, tau)dx
s_vars = {(i,j,k): LpVariable(cat=LpContinuous,lowBound=0,upBound=1,name="s_{0}_{1}_{2}".format(i,j,k))for i in range(0, n+1) for j in range(0, n+1) for k in range(0, j+1)}# approximate integrals by left sums so as to get a lower bound
for i in range(0, n+1):for j in range(0, n+1):for k in range(0, j+1):for l in range(0, i+1):prob += s_vars[i,j,k] <= (1 - g_vars[l, k]+ (1/n)*lpSum(g_vars[d,k] for d in range(0,l))+ (1/n)*lpSum(g_vars[d,j] for d in range(l,i)))# t = min{(1-a)(1-b) + (1-b)int_0^a g(x, b)dx + int_0^b min_c{g(x, c) + int_0^c g(y, x)dy + int_c^a g(y, b)dy}dx}
# where 0 <= a, b <= 1, c <= a, and g(x, y) = (1+h(x)-h(y))/2
# let s(a, b, x) = min_c{g(x, c) + int_0^c g(y, x)dy + int_c^a g(y, b)dy}
# so t = min{(1-a)(1-b) + (1-b)int_0^a g(x, b)dx + int_0^b s(a, b, x) dx}
for i in range(0, n+1):for j in range(0, n+1):prob += t <= ((1-a[i])*(1-a[j]) + (1-a[j])*(1/n)*lpSum(g_vars[l, j] for l in range(0, i))+ (1/n)*lpSum(s_vars[i,j,k] for k in range(0, j))) # unclear whether this is monotonic in x
# Solver can be changed
prob.solve(solver=GUROBI())
# Objective value
value(prob.objective)
g_values = np.zeros((n+1,n+1))
for i in range(n+1):for j in range(n+1):g_values[i,j] = value(g_vars[i,j])
np.savetxt("g_values_{0}.txt".format(n))

然后这一篇其实应该也是老板他们组的后续
然后对于这篇文还在那个的话好像还是给出了比较详细的代码过程,用的是Gurobi的包
这篇文章的link在这里

Diverse Weighted Bipartite b-Matching

这一篇也是讲二分图匹配
但应该是侧重点不同 我没细看 先屯着

这一篇是我今天需要跑通的

#!/usr/bin/env python
#
# Distutils setup script for Munkres
# ---------------------------------------------------------------------------from setuptools import setup
import re
import os
import sys
from distutils.cmd import Command
from abc import abstractmethodif sys.version_info[0:2] < (3, 5):columns = int(os.environ.get('COLUMNS', '80')) - 1msg = ('As of version 1.1.0, this munkres package no longer supports ' +'Python 2. Either upgrade to Python 3.5 or better, or use an ' +'older version of munkres (e.g., 1.0.12).')sys.stderr.write(msg + '\n')raise Exception(msg)# Load the module.here = os.path.dirname(os.path.abspath(sys.argv[0]))def import_from_file(file, name):# See https://stackoverflow.com/a/19011259/53495import importlib.machineryimport importlib.utilloader = importlib.machinery.SourceFileLoader(name, file)spec = importlib.util.spec_from_loader(loader.name, loader)mod = importlib.util.module_from_spec(spec)loader.exec_module(mod)return modmf = os.path.join(here, 'munkres.py')
munkres = import_from_file(mf, 'munkres')
long_description = munkres.__doc__
version = str(munkres.__version__)
(author, email) = re.match('^(.*),\s*(.*)$', munkres.__author__).groups()
url = munkres.__url__
license = munkres.__license__API_DOCS_BUILD = 'apidocs'class CommandHelper(Command):user_options = []def __init__(self, dist):Command.__init__(self, dist)def initialize_options(self):passdef finalize_options(self):pass@abstractmethoddef run(self):passclass Doc(CommandHelper):description = 'create the API docs'def run(self):os.environ['PYTHONPATH'] = '.'cmd = 'pdoc --html --html-dir {} --overwrite --html-no-source munkres'.format(API_DOCS_BUILD)print('+ {}'.format(cmd))rc = os.system(cmd)if rc != 0:raise Exception("Failed to run pdoc. rc={}".format(rc))class Test(CommandHelper):def run(self):import pytestos.environ['PYTHONPATH'] = '.'rc = pytest.main(['-W', 'ignore', '-ra', '--cache-clear', 'test', '.'])if rc != 0:raise Exception('*** Tests failed.')# Run setupsetup(name="munkres",version=version,description="Munkres (Hungarian) algorithm for the Assignment Problem",long_description=long_description,long_description_content_type='text/markdown',url=url,license=license,author=author,author_email=email,py_modules=["munkres"],cmdclass = {'doc': Doc,'docs': Doc,'apidoc': Doc,'apidocs': Doc,'test': Test},classifiers = ['Intended Audience :: Developers','Intended Audience :: Science/Research','License :: OSI Approved :: Apache Software License','Operating System :: OS Independent','Programming Language :: Python','Topic :: Scientific/Engineering :: Mathematics','Topic :: Software Development :: Libraries :: Python Modules']
)

然后其实他不是一篇文章的节选,而是本身就是一个implement的包或者库

唯一跑通的代码

"""
Implementation of the Hungarian (Munkres) Algorithm using Python and NumPy
References: http://www.ams.jhu.edu/~castello/362/Handouts/hungarian.pdfhttp://weber.ucsd.edu/~vcrawfor/hungar.pdfhttp://en.wikipedia.org/wiki/Hungarian_algorithmhttp://www.public.iastate.edu/~ddoty/HungarianAlgorithm.htmlhttp://www.clapper.org/software/python/munkres/
"""# Module Information.
__version__ = "1.1.1"
__author__ = "Thom Dedecko"
__url__ = "http://github.com/tdedecko/hungarian-algorithm"
__copyright__ = "(c) 2010 Thom Dedecko"
__license__ = "MIT License"class HungarianError(Exception):pass# Import numpy. Error if fails
try:import numpy as np
except ImportError:raise HungarianError("NumPy is not installed.")class Hungarian:"""Implementation of the Hungarian (Munkres) Algorithm using np.Usage:hungarian = Hungarian(cost_matrix)hungarian.calculate()orhungarian = Hungarian()hungarian.calculate(cost_matrix)Handle Profit matrix:hungarian = Hungarian(profit_matrix, is_profit_matrix=True)orcost_matrix = Hungarian.make_cost_matrix(profit_matrix)The matrix will be automatically padded if it is not square.For that numpy's resize function is used, which automatically adds 0's to any row/column that is addedGet results and total potential after calculation:hungarian.get_results()hungarian.get_total_potential()"""def __init__(self, input_matrix=None, is_profit_matrix=False):"""input_matrix is a List of Lists.input_matrix is assumed to be a cost matrix unless is_profit_matrix is True."""if input_matrix is not None:# Save inputmy_matrix = np.array(input_matrix)self._input_matrix = np.array(input_matrix)self._maxColumn = my_matrix.shape[1]self._maxRow = my_matrix.shape[0]# Adds 0s if any columns/rows are added. Otherwise stays unalteredmatrix_size = max(self._maxColumn, self._maxRow)pad_columns = matrix_size - self._maxRowpad_rows = matrix_size - self._maxColumnmy_matrix = np.pad(my_matrix, ((0,pad_columns),(0,pad_rows)), 'constant', constant_values=(0))# Convert matrix to profit matrix if necessaryif is_profit_matrix:my_matrix = self.make_cost_matrix(my_matrix)self._cost_matrix = my_matrixself._size = len(my_matrix)self._shape = my_matrix.shape# Results from algorithm.self._results = []self._totalPotential = 0else:self._cost_matrix = Nonedef get_results(self):"""Get results after calculation."""return self._resultsdef get_total_potential(self):"""Returns expected value after calculation."""return self._totalPotentialdef calculate(self, input_matrix=None, is_profit_matrix=False):"""Implementation of the Hungarian (Munkres) Algorithm.input_matrix is a List of Lists.input_matrix is assumed to be a cost matrix unless is_profit_matrix is True."""# Handle invalid and new matrix inputs.if input_matrix is None and self._cost_matrix is None:raise HungarianError("Invalid input")elif input_matrix is not None:self.__init__(input_matrix, is_profit_matrix)result_matrix = self._cost_matrix.copy()# Step 1: Subtract row mins from each row.for index, row in enumerate(result_matrix):result_matrix[index] -= row.min()# Step 2: Subtract column mins from each column.for index, column in enumerate(result_matrix.T):result_matrix[:, index] -= column.min()# Step 3: Use minimum number of lines to cover all zeros in the matrix.# If the total covered rows+columns is not equal to the matrix size then adjust matrix and repeat.total_covered = 0while total_covered < self._size:# Find minimum number of lines to cover all zeros in the matrix and find total covered rows and columns.cover_zeros = CoverZeros(result_matrix)covered_rows = cover_zeros.get_covered_rows()covered_columns = cover_zeros.get_covered_columns()total_covered = len(covered_rows) + len(covered_columns)# if the total covered rows+columns is not equal to the matrix size then adjust it by min uncovered num (m).if total_covered < self._size:result_matrix = self._adjust_matrix_by_min_uncovered_num(result_matrix, covered_rows, covered_columns)# Step 4: Starting with the top row, work your way downwards as you make assignments.# Find single zeros in rows or columns.# Add them to final result and remove them and their associated row/column from the matrix.expected_results = min(self._maxColumn, self._maxRow)zero_locations = (result_matrix == 0)while len(self._results) != expected_results:# If number of zeros in the matrix is zero before finding all the results then an error has occurred.if not zero_locations.any():raise HungarianError("Unable to find results. Algorithm has failed.")# Find results and mark rows and columns for deletionmatched_rows, matched_columns = self.__find_matches(zero_locations)# Make arbitrary selectiontotal_matched = len(matched_rows) + len(matched_columns)if total_matched == 0:matched_rows, matched_columns = self.select_arbitrary_match(zero_locations)# Delete rows and columnsfor row in matched_rows:zero_locations[row] = Falsefor column in matched_columns:zero_locations[:, column] = False# Save Resultsself.__set_results(zip(matched_rows, matched_columns))# Calculate total potentialvalue = 0for row, column in self._results:value += self._input_matrix[row, column]self._totalPotential = value@staticmethoddef make_cost_matrix(profit_matrix):"""Converts a profit matrix into a cost matrix.Expects NumPy objects as input."""# subtract profit matrix from a matrix made of the max value of the profit matrixmatrix_shape = profit_matrix.shapeoffset_matrix = np.ones(matrix_shape, dtype=int) * profit_matrix.max()cost_matrix = offset_matrix - profit_matrixreturn cost_matrixdef _adjust_matrix_by_min_uncovered_num(self, result_matrix, covered_rows, covered_columns):"""Subtract m from every uncovered number and add m to every element covered with two lines."""# Calculate minimum uncovered number (m)elements = []for row_index, row in enumerate(result_matrix):if row_index not in covered_rows:for index, element in enumerate(row):if index not in covered_columns:elements.append(element)min_uncovered_num = min(elements)# Add m to every covered elementadjusted_matrix = result_matrixfor row in covered_rows:adjusted_matrix[row] += min_uncovered_numfor column in covered_columns:adjusted_matrix[:, column] += min_uncovered_num# Subtract m from every elementm_matrix = np.ones(self._shape, dtype=int) * min_uncovered_numadjusted_matrix -= m_matrixreturn adjusted_matrixdef __find_matches(self, zero_locations):"""Returns rows and columns with matches in them."""marked_rows = np.array([], dtype=int)marked_columns = np.array([], dtype=int)# Mark rows and columns with matches# Iterate over rowsfor index, row in enumerate(zero_locations):row_index = np.array([index])if np.sum(row) == 1:column_index, = np.where(row)marked_rows, marked_columns = self.__mark_rows_and_columns(marked_rows, marked_columns, row_index,column_index)# Iterate over columnsfor index, column in enumerate(zero_locations.T):column_index = np.array([index])if np.sum(column) == 1:row_index, = np.where(column)marked_rows, marked_columns = self.__mark_rows_and_columns(marked_rows, marked_columns, row_index,column_index)return marked_rows, marked_columns@staticmethoddef __mark_rows_and_columns(marked_rows, marked_columns, row_index, column_index):"""Check if column or row is marked. If not marked then mark it."""new_marked_rows = marked_rowsnew_marked_columns = marked_columnsif not (marked_rows == row_index).any() and not (marked_columns == column_index).any():new_marked_rows = np.insert(marked_rows, len(marked_rows), row_index)new_marked_columns = np.insert(marked_columns, len(marked_columns), column_index)return new_marked_rows, new_marked_columns@staticmethoddef select_arbitrary_match(zero_locations):"""Selects row column combination with minimum number of zeros in it."""# Count number of zeros in row and column combinationsrows, columns = np.where(zero_locations)zero_count = []for index, row in enumerate(rows):total_zeros = np.sum(zero_locations[row]) + np.sum(zero_locations[:, columns[index]])zero_count.append(total_zeros)# Get the row column combination with the minimum number of zeros.indices = zero_count.index(min(zero_count))row = np.array([rows[indices]])column = np.array([columns[indices]])return row, columndef __set_results(self, result_lists):"""Set results during calculation."""# Check if results values are out of bound from input matrix (because of matrix being padded).# Add results to results list.for result in result_lists:row, column = resultif row < self._maxRow and column < self._maxColumn:new_result = (int(row), int(column))self._results.append(new_result)class CoverZeros:"""Use minimum number of lines to cover all zeros in the matrix.Algorithm based on: http://weber.ucsd.edu/~vcrawfor/hungar.pdf"""def __init__(self, matrix):"""Input a matrix and save it as a boolean matrix to designate zero locations.Run calculation procedure to generate results."""# Find zeros in matrixself._zero_locations = (matrix == 0)self._shape = matrix.shape# Choices starts without any choices made.self._choices = np.zeros(self._shape, dtype=bool)self._marked_rows = []self._marked_columns = []# marks rows and columnsself.__calculate()# Draw lines through all unmarked rows and all marked columns.self._covered_rows = list(set(range(self._shape[0])) - set(self._marked_rows))self._covered_columns = self._marked_columnsdef get_covered_rows(self):"""Return list of covered rows."""return self._covered_rowsdef get_covered_columns(self):"""Return list of covered columns."""return self._covered_columnsdef __calculate(self):"""Calculates minimum number of lines necessary to cover all zeros in a matrix.Algorithm based on: http://weber.ucsd.edu/~vcrawfor/hungar.pdf"""while True:# Erase all marks.self._marked_rows = []self._marked_columns = []# Mark all rows in which no choice has been made.for index, row in enumerate(self._choices):if not row.any():self._marked_rows.append(index)# If no marked rows then finish.if not self._marked_rows:return True# Mark all columns not already marked which have zeros in marked rows.num_marked_columns = self.__mark_new_columns_with_zeros_in_marked_rows()# If no new marked columns then finish.if num_marked_columns == 0:return True# While there is some choice in every marked column.while self.__choice_in_all_marked_columns():# Some Choice in every marked column.# Mark all rows not already marked which have choices in marked columns.num_marked_rows = self.__mark_new_rows_with_choices_in_marked_columns()# If no new marks then Finish.if num_marked_rows == 0:return True# Mark all columns not already marked which have zeros in marked rows.num_marked_columns = self.__mark_new_columns_with_zeros_in_marked_rows()# If no new marked columns then finish.if num_marked_columns == 0:return True# No choice in one or more marked columns.# Find a marked column that does not have a choice.choice_column_index = self.__find_marked_column_without_choice()while choice_column_index is not None:# Find a zero in the column indexed that does not have a row with a choice.choice_row_index = self.__find_row_without_choice(choice_column_index)# Check if an available row was found.new_choice_column_index = Noneif choice_row_index is None:# Find a good row to accomodate swap. Find its column pair.choice_row_index, new_choice_column_index = \self.__find_best_choice_row_and_new_column(choice_column_index)# Delete old choice.self._choices[choice_row_index, new_choice_column_index] = False# Set zero to choice.self._choices[choice_row_index, choice_column_index] = True# Loop again if choice is added to a row with a choice already in it.choice_column_index = new_choice_column_indexdef __mark_new_columns_with_zeros_in_marked_rows(self):"""Mark all columns not already marked which have zeros in marked rows."""num_marked_columns = 0for index, column in enumerate(self._zero_locations.T):if index not in self._marked_columns:if column.any():row_indices, = np.where(column)zeros_in_marked_rows = (set(self._marked_rows) & set(row_indices)) != set([])if zeros_in_marked_rows:self._marked_columns.append(index)num_marked_columns += 1return num_marked_columnsdef __mark_new_rows_with_choices_in_marked_columns(self):"""Mark all rows not already marked which have choices in marked columns."""num_marked_rows = 0for index, row in enumerate(self._choices):if index not in self._marked_rows:if row.any():column_index, = np.where(row)if column_index in self._marked_columns:self._marked_rows.append(index)num_marked_rows += 1return num_marked_rowsdef __choice_in_all_marked_columns(self):"""Return Boolean True if there is a choice in all marked columns. Returns boolean False otherwise."""for column_index in self._marked_columns:if not self._choices[:, column_index].any():return Falsereturn Truedef __find_marked_column_without_choice(self):"""Find a marked column that does not have a choice."""for column_index in self._marked_columns:if not self._choices[:, column_index].any():return column_indexraise HungarianError("Could not find a column without a choice. Failed to cover matrix zeros. Algorithm has failed.")def __find_row_without_choice(self, choice_column_index):"""Find a row without a choice in it for the column indexed. If a row does not exist then return None."""row_indices, = np.where(self._zero_locations[:, choice_column_index])for row_index in row_indices:if not self._choices[row_index].any():return row_index# All rows have choices. Return None.return Nonedef __find_best_choice_row_and_new_column(self, choice_column_index):"""Find a row index to use for the choice so that the column that needs to be changed is optimal.Return a random row and column if unable to find an optimal selection."""row_indices, = np.where(self._zero_locations[:, choice_column_index])for row_index in row_indices:column_indices, = np.where(self._choices[row_index])column_index = column_indices[0]if self.__find_row_without_choice(column_index) is not None:return row_index, column_index# Cannot find optimal row and column. Return a random row and column.from random import shuffleshuffle(row_indices)column_index, = np.where(self._choices[row_indices[0]])return row_indices[0], column_index[0]if __name__ == '__main__':profit_matrix = [[62, 75, 80, 93, 95, 97],[75, 80, 82, 85, 71, 97],[80, 75, 81, 98, 90, 97],[78, 82, 84, 80, 50, 98],[90, 85, 85, 80, 85, 99],[65, 75, 80, 75, 68, 96]]hungarian = Hungarian(profit_matrix, is_profit_matrix=True)hungarian.calculate()print("Expected value:\t\t543")print("Calculated value:\t", hungarian.get_total_potential())  # = 543print("Expected results:\n\t[(0, 4), (2, 3), (5, 5), (4, 0), (1, 1), (3, 2)]")print("Results:\n\t", hungarian.get_results())print("-" * 80)cost_matrix = [[4, 2, 8],[4, 3, 7],[3, 1, 6]]hungarian = Hungarian(cost_matrix)print('calculating...')hungarian.calculate()print("Expected value:\t\t12")print("Calculated value:\t", hungarian.get_total_potential())  # = 12print("Expected results:\n\t[(0, 1), (1, 0), (2, 2)]")print("Results:\n\t", hungarian.get_results())print("-" * 80)profit_matrix = [[62, 75, 80, 93, 0, 97],[75, 0, 82, 85, 71, 97],[80, 75, 81, 0, 90, 97],[78, 82, 0, 80, 50, 98],[0, 85, 85, 80, 85, 99],[65, 75, 80, 75, 68, 0]]hungarian = Hungarian()hungarian.calculate(profit_matrix, is_profit_matrix=True)print("Expected value:\t\t523")print("Calculated value:\t", hungarian.get_total_potential())  # = 523print("Expected results:\n\t[(0, 3), (2, 4), (3, 0), (5, 2), (1, 5), (4, 1)]")print("Results:\n\t", hungarian.get_results())print("-" * 80)
   README
Implementation of the Hungarian (Munkres) Algorithm using Python and NumPy.Usage:hungarian = Hungarian(costMatrix)hungarian.calculate()
orhungarian = Hungarian()hungarian.calculate(costMatrix)Handle Profit matrix:hungarian = Hungarian(profitMatrix, isProfitMatrix=True)
orcostMatrix = Hungarian.makeCostMatrix(profitMatrix)The matrix will be automatically padded if it is not square.
The matrix can be padded with:paddedMatrix = Hungarian.padMatrix(costMatrix)Get results and total potential after calculation:hungarian.getResults()hungarian.getTotalPotential()Released under MIT License.
Source repository: git://github.com/tdedecko/hungarian-algorithm.gitReferences: http://www.ams.jhu.edu/~castello/362/Handouts/hungarian.pdfhttp://weber.ucsd.edu/~vcrawfor/hungar.pdfhttp://en.wikipedia.org/wiki/Hungarian_algorithmhttp://www.public.iastate.edu/~ddoty/HungarianAlgorithm.htmlhttp://www.clapper.org/software/python/munkres/

这篇需要考虑的实际问题其实只有调整输入


  1. ↩︎

AP问题的一些源码,待调试1相关推荐

  1. visual MySQL 教程_MySql轻松入门系列——第二站 使用visual studio 对mysql进行源码级调试...

    一:背景 1. 讲故事 上一篇说了mysql的架构图,很多同学反馈说不过瘾,毕竟还是听我讲故事,那这篇就来说一说怎么利用visual studio 对 mysql进行源码级调试,毕竟源码面前,不谈隐私 ...

  2. Linux环境下用OpenJTAG实现Linux内核的源码级调试

    1.通过U-boot将uzImage格式的内核加载到内存中(可以从Flash中读取,也可以从U盘.SD卡读取,还可以通过网络): 2.登陆到OpenOCD上,在内核中__turn_mmu_on打上断点 ...

  3. idea调试源代码c语言,IDEA阅读spring源码并调试

    目标:搭建起Spring源码阅读和代码调试跟踪的环境,顺便建立一个简单的Demo,能够调试Spring的源代码 本节,主要介绍一下Spring源码阅读和调试的相关环境搭建,并使用MVN创建一个非常简单 ...

  4. ffmpeg编译gb28181_RTSP/GB28181协议/海康SDK/Ehome协议视频上云网关EasyCVR视频平台在linux环境下ffmpeg源码单步调试环境搭建...

    目前TSINGSEE青犀视频研发的视频上云服务平台EasyCVR已经可集成海康EHome私有协议,并且在前文中我也跟大家讲过EHome协议的配置和调用流程,有兴趣的可以阅读一下:配置及协议介绍.Eho ...

  5. 源码级调试的XNU内核

    i春秋翻译小组-FWorldCodeZ 源码级调试的XNU内核 无论你是在开发内核扩展,进行漏洞研究,还是还有其他需要进入macOS / iOS内核,XNU,有时你需要附加调试器.当你这样做时,使用源 ...

  6. SpringBoot 源码解析——如何进行源码环境调试?

    已经分析过 spring-boot-tests/spring-boot-smoke-tests 下的冒烟测试和很早之前版本的 sample 是一样的,所以我们想直接利用这些 sample code 来 ...

  7. Mycat源码篇 : 起步,Mycat源码阅读调试环境搭建

    在研究mycat源码之前必须先把环境搭建好.这篇文章的目标就是搭建mycat源码调试环境.环境主要包括: git jdk maven eclipse mysql 这里假设你知道上面的知识点.我们搭建的 ...

  8. 消息中间件RocketMQ源码解析-- --调试环境搭建

    1. 依赖工具 JDK :1.8+ Maven IntelliJ IDEA 2. 源码拉取 从官方仓库 [https://github.com/apache/rocketmq) Fork 出属于自己的 ...

  9. vue 源码 断点调试

    1.添加sourceMap sourceMap: true 2.npm run dev 会生成vue.js.map 3.断点调试 <!DOCTYPE html> <html>& ...

最新文章

  1. 北恒生物获德诚资本约1亿元A轮融资,德诚资本投资
  2. Java项目开发全程实录pdf
  3. 关于压缩工具 7z(7-zip) 的选项 -so(从标准输出流写入数据)的解读
  4. 使用javamail发信过程中的一些问题及解决方法
  5. 打印倍数_英语精读:3d打印的速度有望提高到100倍
  6. 想要更好的云基础设施管理!你检查IT工具集了吗?
  7. [HDU] 1533 Going Home
  8. 一种提升语音识别准确率的方法与流程
  9. 计算机软著研究生毕业,关于研究生推免工作科研成果和竞赛计分详细说明
  10. 使用ASP.NET WEB API构建基于REST风格的服务实战系列教程(一)——使用EF6构建数据库及模型...
  11. 肖特基二极管在防止电源反接的作用
  12. Leetcode13. 罗马数字转整数Leetcode14. 最长公共前缀Leetcode15. 三数之和Leetcode16. 最接近的三数之和Leetcode17. 电话号码的字母组合
  13. 37手游基于云平台的大数据建设实践
  14. rtx2060什么水平_RTX2060性能如何?NVIDIA新一代RTX2060显卡评测
  15. 移动应用广告对接:为什么SDK是最佳选择?
  16. 【松岩论道】浅谈四季度的操作策略!
  17. 删库了,除了跑路还能怎么办?在线等!
  18. abb程序加密加密软件cd-key,功能强大,可加密abb等机械手程序,傻瓜式操作
  19. pl_slam配置、运行过程
  20. Android ListView 设置分割线的设置

热门文章

  1. 嗖嗖嗖主题网外贸企业主题制作视频教程--第四讲 Wordpress首页模板文件index.php静态页面完善
  2. 【L2-026 小字辈】天梯赛L2系列详解
  3. C++实用案例:整数四则运算计算器
  4. 安卓学习笔记---Android仿美团加载数据、小人奔跑进度动画对话框(以及顺丰快递员奔跑效果)
  5. maxcms整合html5播放器,马克斯 maxcms 二合一模板 多播放多采集 PC手机一站式多功能模板...
  6. 电子病历结构化之实体识别(附完整项目代码)
  7. 罗斯蒙特3051SMV5M12G4R2E11A1AC22M5无线变送器
  8. PDF文件怎么合并分割
  9. 树莓派32位系统烧录及连接
  10. BlazeDS入门及配置