python采用匈牙利算法实现分配问题

import itertools

import numpy as np

from numpy import random

from scipy.optimize import linear_sum_assignment


# 任务分配类

class TaskAssignment:

    # 类初始化,需要输入参数有任务矩阵以及分配方式,其中分配方式有两种,全排列方法all_permutation或匈牙利方法Hungary。

    def __init__(self, task_matrix, mode):

        self.task_matrix = task_matrix

        self.mode = mode

        if mode == 'all_permutation':
            self.min_cost, self.best_solution = self.all_permutation(task_matrix)

        if mode == 'Hungary':
            self.min_cost, self.best_solution = self.Hungary(task_matrix)

    # 全排列方法

    def all_permutation(self, task_matrix):

        number_of_choice = len(task_matrix)

        solutions = []

        values = []

        for each_solution in itertools.permutations(range(number_of_choice)):

            each_solution = list(each_solution)

            solution = []

            value = 0

            for i in range(len(task_matrix)):
                value += task_matrix[i][each_solution[i]]

                solution.append(task_matrix[i][each_solution[i]])

            values.append(value)

            solutions.append(solution)

        min_cost = np.min(values)

        best_solution = solutions[values.index(min_cost)]

        return min_cost, best_solution

    # 匈牙利方法

    def Hungary(self, task_matrix):

        b = task_matrix.copy()

        # 行和列减0

        for i in range(len(b)):

            row_min = np.min(b[i])

            for j in range(len(b[i])):
                b[i][j] -= row_min

        for i in range(len(b[0])):

            col_min = np.min(b[:, i])

            for j in range(len(b)):
                b[j][i] -= col_min

        line_count = 0

        # 线数目小于矩阵长度时,进行循环

        while (line_count < len(b)):

            line_count = 0

            row_zero_count = []

            col_zero_count = []

            for i in range(len(b)):
                row_zero_count.append(np.sum(b[i] == 0))

            for i in range(len(b[0])):
                col_zero_count.append((np.sum(b[:, i] == 0)))

            # 划线的顺序(分行或列)

            line_order = []

            row_or_col = []

            for i in range(len(b[0]), 0, -1):

                while (i in row_zero_count):
                    line_order.append(row_zero_count.index(i))

                    row_or_col.append(0)

                    row_zero_count[row_zero_count.index(i)] = 0

                while (i in col_zero_count):
                    line_order.append(col_zero_count.index(i))

                    row_or_col.append(1)

                    col_zero_count[col_zero_count.index(i)] = 0

            # 画线覆盖0,并得到行减最小值,列加最小值后的矩阵

            delete_count_of_row = []

            delete_count_of_rol = []

            row_and_col = [i for i in range(len(b))]

            for i in range(len(line_order)):

                if row_or_col[i] == 0:

                    delete_count_of_row.append(line_order[i])

                else:

                    delete_count_of_rol.append(line_order[i])

                c = np.delete(b, delete_count_of_row, axis=0)

                c = np.delete(c, delete_count_of_rol, axis=1)

                line_count = len(delete_count_of_row) + len(delete_count_of_rol)

                # 线数目等于矩阵长度时,跳出

                if line_count == len(b):
                    break

                # 判断是否画线覆盖所有0,若覆盖,进行加减操作

                if 0 not in c:

                    row_sub = list(set(row_and_col) - set(delete_count_of_row))

                    min_value = np.min(c)

                    for i in row_sub:
                        b[i] = b[i] - min_value

                    for i in delete_count_of_rol:
                        b[:, i] = b[:, i] + min_value

                    break

        row_ind, col_ind = linear_sum_assignment(b)

        min_cost = task_matrix[row_ind, col_ind].sum()

        best_solution = list(task_matrix[row_ind, col_ind])

        return min_cost, best_solution


# 生成开销矩阵

rd = random.RandomState(10000)

task_matrix = rd.randint(0, 100, size=(5, 5))

# 用全排列方法实现任务分配

ass_by_per = TaskAssignment(task_matrix, 'all_permutation')

# 用匈牙利方法实现任务分配

ass_by_Hun = TaskAssignment(task_matrix, 'Hungary')

print('cost matrix = ', '\n', task_matrix)

print('全排列方法任务分配:')

print('min cost = ', ass_by_per.min_cost)

print('best solution = ', ass_by_per.best_solution)

print('匈牙利方法任务分配:')

print('min cost = ', ass_by_Hun.min_cost)

print('best solution = ', ass_by_Hun.best_solution)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值