首页 > 编程语言 >运筹学练习Python精解——指派问题

运筹学练习Python精解——指派问题

时间:2024-06-09 11:32:41浏览次数:23  
标签:matrix Python assignment 任务 运筹学 time 精解 best row

练习8

分配甲、乙、丙、丁4个人去完成A、B、C、D、E 5项任务,每个人完成各项任务的时间见下表。由于任务数多于人数,故考虑:
(1) 任务E必须完成,其他4项中可任选3项完成;
(2) 其中有一人完成两项,其他每人完成一项。
试分别确定最优分配方案,使完成任务的总时间为最少。

人员\任务 A B C D E
25 29 31 42 37
39 38 26 20 33
34 27 28 40 32
24 42 36 23 45

8.1 (1)问题指派分析

为了确定最优分配方案,使完成任务的总时间最少,我们可以按照以下步骤进行求解:

  • 确定任务选择
    • 任务E必须完成,所以必须包含在选择的任务中。
    • 在A、B、C、D四项任务中任选三项,共有\(\binom{4}{3} = 4\)种选择。
      • 即选择组合为:{A, B, C, E}、{A, B, D, E}、{A, C, D, E}、{B, C, D, E}。
  • 任务分配方案
    • 每个任务选择组合确定后,分配4个人完成这4项任务,计算所有可能的分配情况,选择总时间最少的方案。
  • 计算最优方案
    • 对于每一种任务组合,使用计算机算法(如动态规划或组合搜索)来计算所有可能的分配方案,求出总时间最少的方案。

8.2 (1)问题的Python程序

import itertools
import numpy as np
from scipy.optimize import linear_sum_assignment

# 定义任务时间表
time_table = {
    'A': [25, 39, 34, 24],
    'B': [29, 38, 27, 42],
    'C': [31, 26, 28, 36],
    'D': [42, 20, 40, 23],
    'E': [37, 33, 32, 45]
}

tasks = ['A', 'B', 'C', 'D', 'E']
persons = [0, 1, 2, 3]  # 0: 甲, 1: 乙, 2: 丙, 3: 丁

# 任务组合
task_combinations = [
    ['A', 'B', 'C', 'E'],
    ['A', 'B', 'D', 'E'],
    ['A', 'C', 'D', 'E'],
    ['B', 'C', 'D', 'E']
]

def calculate_assignment_cost(cost_matrix):
    row_ind, col_ind = linear_sum_assignment(cost_matrix)
    return cost_matrix[row_ind, col_ind].sum(), list(zip(row_ind, col_ind))

best_time = float('inf')
best_combination = None
best_assignment = None

# 存储每个组合的最小总时间
combination_times = {}

for comb in task_combinations:
    # 构建成本矩阵
    cost_matrix = []
    for person in persons:
        cost_row = []
        for task in comb:
            cost_row.append(time_table[task][person])
        cost_matrix.append(cost_row)
    
    cost_matrix = np.array(cost_matrix)
    
    # 计算最优分配
    time, assignment = calculate_assignment_cost(cost_matrix)
    combination_times[tuple(comb)] = time
    
    if time < best_time:
        best_time = time
        best_combination = comb
        best_assignment = assignment

# 输出每个任务组合的最小总时间
print("各任务组合的最小总时间:")
for comb, time in combination_times.items():
    print(f"任务组合 {comb}: 最小总时间 {time}分钟")

# 输出最优方案
person_names = ['甲', '乙', '丙', '丁']
assignment_str = {best_combination[task]: person_names[person] for person, task in best_assignment}

print("\n最优方案:")
print(f"最优任务组合: {best_combination}")
print(f"最优分配方案: {assignment_str}")
print(f"最少总时间: {best_time}分钟")
各任务组合的最小总时间:
任务组合 ('A', 'B', 'C', 'E'): 最小总时间 111分钟
任务组合 ('A', 'B', 'D', 'E'): 最小总时间 105分钟
任务组合 ('A', 'C', 'D', 'E'): 最小总时间 106分钟
任务组合 ('B', 'C', 'D', 'E'): 最小总时间 110分钟

最优方案:
最优任务组合: ['A', 'B', 'D', 'E']
最优分配方案: {'B': '甲', 'D': '乙', 'E': '丙', 'A': '丁'}
最少总时间: 105分钟

8.3 (2)问题的指派分析

要解决这个问题,我们可以使用组合与排列的方法生成所有可能的任务分配方案,然后计算每个方案的总时间,选择最小的一个。具体步骤如下:

对4个人中的每一个考虑分配两个任务,其余三个人各分配一个任务,共有\(\binom{5}{2} = 10\)。
生成新的成本矩阵,对于每一个人承担两个任务的情况,计算出所有可能的任务分配组合。
对每个生成的成本矩阵,使用匈牙利算法(Hungarian Algorithm)来求解最优任务分配问题。
比较所有情况的最小总时间,找到最优分配方案。

8.4(2)问题的Python程序

import numpy as np
from scipy.optimize import linear_sum_assignment

# 给定的时间表
time_table = {
    'A': [25, 39, 34, 24],
    'B': [29, 38, 27, 42],
    'C': [31, 26, 28, 36],
    'D': [42, 20, 40, 23],
    'E': [37, 33, 32, 45]
}

tasks = ['A', 'B', 'C', 'D', 'E']
persons = ['甲', '乙', '丙', '丁']  # 0: 甲, 1: 乙, 2: 丙, 3: 丁

# 将time_table转换为二维数组
time_matrix = np.array([time_table[task] for task in tasks]).T

# 创建新矩阵并输出
new_matrices = []
for i in range(time_matrix.shape[0]):
    new_row = time_matrix[i, :]
    new_matrix = np.vstack([time_matrix, new_row])
    new_matrices.append((new_matrix, i))

# 对new_matrices进行指派问题求解并打印每个最优值
best_total_time = float('inf')
best_assignment = None
best_matrix = None
best_row_index = None

for idx, (matrix, row_index) in enumerate(new_matrices):
    row_ind, col_ind = linear_sum_assignment(matrix)
    total_time = matrix[row_ind, col_ind].sum()
    print(f"新矩阵 {idx + 1} 的最优值: {total_time} 分钟")
    
    if total_time < best_total_time:
        best_total_time = total_time
        best_assignment = list(zip(row_ind, col_ind))
        best_matrix = matrix
        best_row_index = row_index

# 输出最优指派方案和最小值
print("\n最优指派方案:")
for person, task in best_assignment:
    person_name = persons[person] if person < len(persons) else '完成两个任务的人员'
    task_name = tasks[task] if task < len(tasks) else '额外的任务'
    time_spent = best_matrix[person, task]
    print(f"{person_name} 负责任务 {task_name}, 所需时间: {time_spent} 分钟")

print(f"最小总时间: {best_total_time} 分钟")
print(f"添加的行: {best_row_index+1},即完成两个任务的人员: {persons[best_row_index]}")
新矩阵 1 的最优值: 135 分钟
新矩阵 2 的最优值: 131 分钟
新矩阵 3 的最优值: 133 分钟
新矩阵 4 的最优值: 134 分钟

最优指派方案:
甲 负责任务 B, 所需时间: 29 分钟
乙 负责任务 C, 所需时间: 26 分钟
丙 负责任务 E, 所需时间: 32 分钟
丁 负责任务 A, 所需时间: 24 分钟
完成两个任务的人员 负责任务 D, 所需时间: 20 分钟
最小总时间: 131 分钟
添加的行: 2,即完成两个任务的人员: 乙

标签:matrix,Python,assignment,任务,运筹学,time,精解,best,row
From: https://www.cnblogs.com/haohai9309/p/18239384

相关文章

  • 【四种语言一网打尽(C\C++\Python\Golang)】L1-005 考试座位号
    L1-005考试座位号每个PAT考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着......
  • 【机器学习基础】Python编程07:五个实用练习题的解析与总结
    Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面:简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些库提供了......
  • 【机器学习基础】Python编程08:五个实用练习题的解析与总结
    Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面:简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些库提供了......
  • Plotly : 超好用的Python可视化工具
    文章目录安装:开始你的Plotly之旅基本折线图:简单却强大的起点带颜色的散点图:数据的多彩世界三维曲面图:探索数据的深度气泡图:让世界看到你的数据小提琴图:数据分布的优雅展现旭日图:分层数据的直观展示热力图:变量之间关系的直观展示雷达图:多维数据的全面展示三维散点图:空间......
  • Python+pytest+jenkins 多插件 pdf电子书目录
    第1章pytest入门11.1资源获取 41.2运行Pytest 51.3运行单个测试用例 101.4使用命令行选项 10--collect-only选项 11-k选项 11-m选项 12-x选项 13--maxfail=num 15-s与--capture=method 16-lf(--lastfailed)选项 16--ff(--failed-first)选项 17......
  • Python 运算符重载
    在Python中,运算符重载是一种允许你定义或修改内置运算符(例如+,-,*,/等)在自定义类中的行为的技术。通过重载运算符,你可以使这些运算符对自定义对象执行特定的操作。运算符重载是通过在类中定义特殊方法(也称为魔法方法)来实现的,这些方法通常以双下划线开头和结尾。以下是一些常......
  • Python_编程基础
    Python_编程基础Python编程基础0、简单介绍解释型语言:一边编译一边运行,不需要进行编译,运行效率比较低解释器JavaScript-浏览器python.exephp.exe编译型语言:运行前需要进行编译,运行效率比较高C.c->.exe组合:anaconda+pycharm、python+pycharm/sublime/geany/vs......
  • python>tqdm实现git进度条效果
    注意1:这里是在python3环境下使用的git,安装要使用pipinstallGitpython来安装在python环境下的git注意2:这个方法可适用于windows环境和Linux环境importgitimporttqdmrepo_url='https://gitee.com/alichinese/oebuild-bin.git'local_path='F:\\test\\oebuild-b......
  • Python数据结构解析:从基本语法到实战应用,提升代码效率与性能
    基本语法Python提供了多种内置的数据结构,包括列表(List)、元组(Tuple)、集合(Set)、字典(Dictionary)等。这些数据结构具有不同的特点和用途,可以根据需求选择合适的数据结构。1.列表(List)列表是Python中最常用的数据结构之一,用于存储一系列元素,可以是不同类型的数据。列表使用......
  • 0004python金融量化初入门
    >Date:2024.04.24>Keywords:在量化投资(证券和比特币)开源项目里,全球star数排名前10位里面,有7个是Python实现的。从数据获取到策略回测再到交易,覆盖了整个业务链。而全球注册用户数最多的商业量化平台Uqer优矿,也同样是基于Python实现和提供服务的。国内后来的其他量化平台,例如ricequ......