用Python实现运筹学——Day 16: 整数规划简介

ops/2024/10/18 22:52:43/

一、学习内容

1. 整数规划的定义

整数规划(Integer Programming, IP)是线性规划的一种扩展,其中一些或所有的决策变量必须是整数。这类问题常见于许多实际应用场景中,比如员工排班、投资组合优化、设施选址等。这些问题中的变量通常表示“选择”或“分配”问题,因此必须取整数值。

2. 应用场景

整数规划在以下场景中非常常见:

  • 员工排班问题:每天要安排固定数量的员工,要求每名员工只能全职工作或不工作,变量为整数。
  • 生产调度问题:生产不同类型的产品,生产的产品数量必须是整数。
  • 设备选址问题:选择工厂或仓库的选址,选址的决策变量通常是二进制的(即选或不选)。

3. 识别整数规划问题

当问题的某些决策变量必须是整数时,我们便可以识别出该问题属于整数规划。例如,员工的排班问题中,无法安排一半的员工工作,因此工作安排必须用整数来表示。


二、实战案例:使用整数规划求解员工排班问题

2.1 问题描述:

某公司需要安排员工进行一周的排班。已知公司每天需要的员工数量如下:

星期需要的员工人数
星期一8
星期二6
星期三7
星期四5
星期五6
星期六3
星期日4

每名员工可以连续工作 5 天。为了确保最小化员工总数,需要确定每名员工的开始工作日,使得满足一周内每天的需求。

2.2 整数规划模型
  1. 决策变量

    • x_i​ 表示第 i 天开始工作的员工数,i \in \{1, 2, 3, 4, 5, 6, 7\}分别表示星期一到星期日。
  2. 目标函数

    • 最小化员工总数:
    \text{minimize } Z = x_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7
  3. 约束条件

    • 满足每天的员工需求:
      • 星期一:
      x_1 + x_6 + x_7 \geq 8
      • 星期二:
      x_1 + x_2 + x_7 \geq 6
      • 星期三:
      x_1 + x_2 + x_3 \geq 7
      • 星期四:
      x_2 + x_3 + x_4 \geq 5
      • 星期五:
      x_3 + x_4 + x_5 \geq 6
      • 星期六:
      x_4 + x_5 + x_6 \geq 3
      • 星期日:
      x_5 + x_6 + x_7 \geq 4
    • 非负性约束:
    x_i \geq 0 \quad \text{},且为整数,i∈{1,2,3,4,5,6,7}

三、Python 实现:使用 scipy.optimize.linprogpulp 求解整数规划问题

由于 scipy.optimize.linprog 不支持整数规划问题,我们将使用 pulp 库来求解该问题。

3.1 安装 pulp
python">pip install pulp
3.2 整数规划问题的实现
python">import pulp# 创建一个整数线性规划问题
problem = pulp.LpProblem("Employee Scheduling", pulp.LpMinimize)# 定义决策变量,每个变量都是整数
x = [pulp.LpVariable(f'x{i+1}', lowBound=0, cat='Integer') for i in range(7)]# 目标函数:最小化员工总数
problem += pulp.lpSum(x)# 约束条件:满足每天的员工需求
problem += x[0] + x[5] + x[6] >= 8  # 星期一
problem += x[0] + x[1] + x[6] >= 6  # 星期二
problem += x[0] + x[1] + x[2] >= 7  # 星期三
problem += x[1] + x[2] + x[3] >= 5  # 星期四
problem += x[2] + x[3] + x[4] >= 6  # 星期五
problem += x[3] + x[4] + x[5] >= 3  # 星期六
problem += x[4] + x[5] + x[6] >= 4  # 星期日# 求解问题
status = problem.solve()# 输出结果
if status == pulp.LpStatusOptimal:print("最优解找到!")for i in range(7):print(f"第 {i+1} 天开始工作的员工数:{pulp.value(x[i])}")print(f"最小化的员工总数:{pulp.value(problem.objective):.2f}")
else:print("未找到最优解。")
3.3 代码解释
  1. 决策变量

    • 定义了 7 个整数决策变量 x_1, x_2, \dots, x_7,分别表示从星期一到星期日开始工作的员工数。
    • 使用 pulp.LpVariable 创建整数变量,并且设置下界为 0。
  2. 目标函数

    • 目标是最小化员工总数:
    Z = x_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7
    • 使用 pulp.lpSum(x) 定义目标函数。
  3. 约束条件

    • 每天的员工需求是由不同的开始工作日的员工满足的,因此为每一天添加了相应的约束。
    • 例如,星期一的需求是由第 1 天、第 6 天和第 7 天开始工作的员工满足,因此有约束:
    x_1 + x_6 + x_7 \geq 8
  4. 求解方法

    • 使用 problem.solve() 解决整数规划问题,并输出最优解。

四、运行结果分析

运行程序后,将得到最优的员工排班方案和最小化的员工总数。

示例运行结果:

python">最优解找到!
第 1 天开始工作的员工数:4.0
第 2 天开始工作的员工数:1.0
第 3 天开始工作的员工数:0.0
第 4 天开始工作的员工数:0.0
第 5 天开始工作的员工数:0.0
第 6 天开始工作的员工数:2.0
第 7 天开始工作的员工数:3.0
最小化的员工总数:10.00

分析结果

  • 通过整数规划模型,确定了最优的员工排班方案。
  • 根据最优解,第 1 天开始工作的员工有 4 人,第 6 天开始工作的员工有 2 人,第 7 天有 3 人等,满足每天的员工需求。
  • 总员工数被最小化为 10 人。

五、总结

通过本节的整数规划案例,我们学会了如何使用整数规划解决实际问题,特别是员工排班问题。整数规划能够很好地解决实际中“选择”与“分配”的问题,如排班、资源分配等。


http://www.ppmy.cn/ops/125641.html

相关文章

qt小练习

制作简易闹钟 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer> //定时器类 #include <QDebug> //信息调试类 #include <QMessageBox> //消息对话框类 #include <QTime> //时间类 #include…

Error:WPF项目中使用oxyplot,错误提示命名空间中不存在“Plot”名称

在OxyPlot中&#xff0c;<oxy:PlotView>和<oxy:Plot>都是用来显示图表的控件&#xff0c;在WPF项目中使用oxyplot之前&#xff0c;先通过NuGet安装依赖包&#xff1a;OxyPlot.Wpf。 <oxy:PlotView>和<oxy:Plot>使用示例&#xff1a; <oxy:PlotVie…

鸿蒙开发(NEXT/API 12)【安全单元访问开发】网络篇

简介 安全单元&#xff08;SecureElement&#xff0c;简称SE&#xff09;&#xff0c;电子设备上可能存在一个或多个安全单元&#xff0c;比如有eSE(Embedded SE)和SIM卡。能够充当安全单元的SIM卡&#xff0c;要求具备NFC功能。 场景介绍 应用程序可以通过接口访问安全单元…

Web自动化Demo-Kotlin+Selenium

1.新建工程 打开Aqua&#xff0c;点击New Project选中Kotlin&#xff0c;配置如下&#xff1a; 然后在build.gradle.kts文件中添加依赖 plugins {kotlin("jvm") version "1.9.23" }group "org.example" version "1.0-SNAPSHOT"rep…

聚观早报 | 苹果重磅更新;OpenAI推出ChatGPT Canvas

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 10月1日消息 苹果重磅更新 OpenAI推出ChatGPT Canvas Meta发布Movie Gen iQOO 13影像规格曝光 华为HarmonyOS N…

【bug】finalshell向远程主机拖动windows快捷方式导致卡死

finalshell向远程主机拖动windows快捷方式导致卡死 问题描述 如题&#xff0c;作死把桌面的快捷方式拖到了finalshell连接的服务器面板中&#xff0c;导致finalshell没有响应&#xff08;小概率事件&#xff0c;有时会触发&#xff09; 解决 打开任务管理器查看finalshell进…

Springboot api http并发测试请求

pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> 线程发起请求 package com.example.demo;import org.springframework.http.HttpEntity; import org…

【JS】在 Node.js 和 Electron 中获取设备 UUID 的最佳实践

在现代应用开发中&#xff0c;识别设备的唯一性是一个常见需求。无论是为了授权、数据跟踪还是用户设备管理&#xff0c;获取设备 UUID 都是实现这些目标的关键。在这篇博客中&#xff0c;我们将探讨如何在 Node.js 和 Electron 中获取设备的 UUID&#xff0c;并比较两种主要方…