Решение задачи назначения: методы и примеры кода для распределения K человек на каждую работу

Задача назначения — это хорошо известная задача оптимизации, которая предполагает распределение K человек на каждую работу наиболее эффективным способом. В этой статье мы рассмотрим несколько методов решения проблемы назначения и предоставим примеры кода для каждого метода.

  1. Подход линейного программирования.
    Один из популярных методов решения задачи назначения — формулировка ее как задачи линейного программирования. Идея состоит в том, чтобы назначить переменные, представляющие распределение каждого человека на работу, и определить целевые и ограничивающие функции для оптимизации распределения. Вот пример кода с использованием библиотеки PuLP на Python:
import pulp
def solve_assignment_linear_programming(cost_matrix, k):
    n = len(cost_matrix)
    m = len(cost_matrix[0])
    # Create a binary variable for each person-job pair
    variables = pulp.LpVariable.dicts("x", (range(n), range(m)), cat="Binary")
    # Create the linear programming problem
    problem = pulp.LpProblem("Assignment Problem", pulp.LpMinimize)
    # Set the objective function
    problem += pulp.lpSum([cost_matrix[i][j] * variables[i][j] for i in range(n) for j in range(m)])
    # Add constraints
    for i in range(n):
        problem += pulp.lpSum([variables[i][j] for j in range(m)]) == k
    for j in range(m):
        problem += pulp.lpSum([variables[i][j] for i in range(n)]) <= 1
    # Solve the problem
    problem.solve()
    # Extract the solution
    allocation = [[variables[i][j].varValue for j in range(m)] for i in range(n)]
    return allocation
  1. Венгерский алгоритм:
    Венгерский алгоритм — это хорошо известный метод эффективного решения задачи о назначениях. Он использует комбинацию сокращения строк и столбцов, а также метод увеличения пути для поиска оптимального назначения. Вот пример кода, использующего функцию scipy.optimize.linear_sum_assignmentв Python:
import numpy as np
from scipy.optimize import linear_sum_assignment
def solve_assignment_hungarian(cost_matrix, k):
    n = len(cost_matrix)
    m = len(cost_matrix[0])
    # Duplicate the cost matrix k times
    cost_matrix_extended = np.tile(cost_matrix, (k, 1, 1))
    # Solve the assignment using the Hungarian algorithm
    row_indices, col_indices = linear_sum_assignment(cost_matrix_extended)
    # Extract the solution
    allocation = np.zeros((n, m))
    for row, col in zip(row_indices, col_indices):
        allocation[row % n][col] = 1
    return allocation.tolist()
  1. Двустороннее сопоставление.
    Другой подход к решению проблемы назначения — ее моделирование как задачи двустороннего сопоставления. Этот метод включает в себя построение двудольного графа, где каждый человек и работа представлены в виде узла, а ребра представляют совместимость между людьми и должностями. Вот пример кода с использованием библиотеки NetworkX на Python:
import networkx as nx
def solve_assignment_bipartite(cost_matrix, k):
    n = len(cost_matrix)
    m = len(cost_matrix[0])
    # Create a bipartite graph
    graph = nx.Graph()
    # Add person nodes
    graph.add_nodes_from(range(n), bipartite=0)
    # Add job nodes
    graph.add_nodes_from(range(n, n + m), bipartite=1)
    # Add edges with costs
    for i in range(n):
        for j in range(m):
            graph.add_edge(i, n + j, weight=cost_matrix[i][j])
    # Solve the bipartite matching problem
    matching = nx.bipartite.maximum_matching(graph)
    # Extract the solution
    allocation = [[0] * m for _ in range(n)]
    for person, job in matching.items():
        if person < n:
            allocation[person][job - n] = 1
    return allocation

В этой статье мы исследовали три различных метода решения задачи назначения: линейное программирование, венгерский алгоритм и двустороннее сопоставление. Каждый метод предлагает уникальный подход к эффективному распределению K человек на каждую работу. Используя эти методы и предоставленные примеры кода, вы можете решать проблемы назначения в различных сценариях и эффективно оптимизировать распределение ресурсов.