整数线性规划实现(lingo,python分枝界定法)

本文章为上篇建模学习打卡第二天的

文章目录

一、本次问题

 二、本题理解

三、问题求解

1.lingo实现

(1)先抛除整数约束条件对问题求解

 (2)加入整数约束条件求解

2.python实现求解

(1)先抛除整数约束条件对问题求解

 (2)加入整数约束条件求解实现   通过 pulp 库求解

 (3)加入整数约束条件求解实现  分枝界定法求解


一、本次问题

 二、本题理解

目标函数:

max = 40x1+90x2

一级约束条件:

9x1+7x2<=56
7x1+20x2<=70
x1,x2 >= 0

二级约束条件:

x1,x2全为整数

三、问题求解

1.lingo实现

lingo编写代码时,每行代码结束后必须以 ‘ ; ’ 结束,否则无法运行。

(1)先抛除整数约束条件对问题求解

基础线性规划实现(matlab,lingo)_菜菜笨小孩的博客-CSDN博客

        lingo代码实现:(l无其他条件下,ingo中默认变量大于等于0)

max = 40*x1+90*x2;
9*x1+7*x2<=56;
7*x1+20*x2<=70;

        结果:最优解 x1=4.80916 , x2 = 1.816794 ; 最优值为355.8779;显然不符合题意

 (2)加入整数约束条件求解

首先,需要引出lingo的变量界定函数 @gin(x) --- 将x限制为整数条件

       ingo代码实现:通过变量界定函数将x1,x2限制为整数约束

max = 40*x1+90*x2;
9*x1+7*x2<=56;
7*x1+20*x2<=70;
@gin(x1);
@gin(x2);

        结果:最优解 x1=4 , x2 = 2 ; 最优值为340;符合题意

 lingo实现求解到此结束。

2.python实现求解

(1)先抛除整数约束条件对问题求解

基础线性规划实现---python_菜菜笨小孩的博客-CSDN博客

        python代码实现如下:详解请看上方python基础线性规划的文章

#导入包
from scipy import optimize as opt
import numpy as np#确定c,A,b,Aeq,beq
c = np.array([40,90]) #目标函数变量系数
A = np.array([[9,7],[7,20]]) #不等式变量系数
b = np.array([56,70]) #不等式变量值
Aeq = np.array([[0,0]]) #等式变量系数
beq = np.array([0]) #等式变量值
#限制
lim1=(0,None)
lim2=(0,None)
#求解
res = opt.linprog(-c,A,b,Aeq,beq,bounds=(lim1,lim2))
#输出结果
print(res)

        结果:最优解 x1=4.80916 , x2 = 1.816794 ; 最优值为355.8779;显然不符合题意

 (2)加入整数约束条件求解实现   通过 pulp 库求解

安装库:我用python3.8安装成功了

pip install pulp

python代码实现:

1.导入库

import pulp as pulp

2.定义解决问题的函数

def solve_ilp(objective , constraints) :print(objective)print(constraints)prob = pulp.LpProblem('LP1' , pulp.LpMaximize)prob += objectivefor cons in constraints :prob += consprint(prob)status = prob.solve()if status != 1 :return Noneelse :return [v.varValue.real for v in prob.variables()]

3.设置目标函数和约束条件等

V_NUM = 2 #本题变量个数
# 变量,直接设置下限
variables = [pulp.LpVariable('X%d' % i, lowBound=0, cat=pulp.LpInteger) for i in range(0, V_NUM)]
# 目标函数
c = [40, 90]
objective = sum([c[i] * variables[i] for i in range(0, V_NUM)])
# 约束条件
constraints = []
a1 = [9, 7]
constraints.append(sum([a1[i] * variables[i] for i in range(0, V_NUM)]) <= 56)
a2 = [7, 20]
constraints.append(sum([a2[i] * variables[i] for i in range(0, V_NUM)]) <= 70)

4.求解:

res = solve_ilp(objective, constraints)
print(res) #输出结果

完整代码如下:

# -*- coding: utf-8 -*-
import pulp as pulpdef solve_ilp(objective, constraints):print(objective)print(constraints)prob = pulp.LpProblem('LP1', pulp.LpMaximize)prob += objectivefor cons in constraints:prob += consprint(prob)status = prob.solve()if status != 1:# print 'status'# print statusreturn Noneelse:# return [v.varValue.real for v in prob.variables()]return [v.varValue.real for v in prob.variables()]V_NUM = 2
# 变量,直接设置下限
variables = [pulp.LpVariable('X%d' % i, lowBound=0, cat=pulp.LpInteger) for i in range(0, V_NUM)]
# 目标函数
c = [40, 90]
objective = sum([c[i] * variables[i] for i in range(0, V_NUM)])
# 约束条件
constraints = []
a1 = [9, 7]
constraints.append(sum([a1[i] * variables[i] for i in range(0, V_NUM)]) <= 56)
a2 = [7, 20]
constraints.append(sum([a2[i] * variables[i] for i in range(0, V_NUM)]) <= 70)
# print (constraints)res = solve_ilp(objective, constraints)
print(res) #输出解

结果:最优解 x1=4 , x2 = 2 ; 最优值为340;符合题意

 (3)加入整数约束条件求解实现  分枝界定法求解

何为分枝界定法,请看详解https://blog.csdn.net/qq_25990967/article/details/121211474

python代码实现:

1.导入库

from scipy.optimize import linprog
import numpy as np
import math
import sys
from queue import Queue

2.定义整数线性规划类

class ILP()

3.定义分枝界定法函数

def __init__(self, c, A_ub, b_ub, A_eq, b_eq, bounds):# 全局参数self.LOWER_BOUND = -sys.maxsizeself.UPPER_BOUND = sys.maxsizeself.opt_val = Noneself.opt_x = Noneself.Q = Queue()# 这些参数在每轮计算中都不会改变self.c = -cself.A_eq = A_eqself.b_eq = b_eqself.bounds = bounds# 首先计算一下初始问题r = linprog(-c, A_ub, b_ub, A_eq, b_eq, bounds)# 若最初问题线性不可解if not r.success:raise ValueError('Not a feasible problem!')# 将解和约束参数放入队列self.Q.put((r, A_ub, b_ub))def solve(self):while not self.Q.empty():# 取出当前问题res, A_ub, b_ub = self.Q.get(block=False)# 当前最优值小于总下界,则排除此区域if -res.fun < self.LOWER_BOUND:continue# 若结果 x 中全为整数,则尝试更新全局下界、全局最优值和最优解if all(list(map(lambda f: f.is_integer(), res.x))):if self.LOWER_BOUND < -res.fun:self.LOWER_BOUND = -res.funif self.opt_val is None or self.opt_val < -res.fun:self.opt_val = -res.funself.opt_x = res.xcontinue# 进行分枝else:# 寻找 x 中第一个不是整数的,取其下标 idxidx = 0for i, x in enumerate(res.x):if not x.is_integer():breakidx += 1# 构建新的约束条件(分割new_con1 = np.zeros(A_ub.shape[1])new_con1[idx] = -1new_con2 = np.zeros(A_ub.shape[1])new_con2[idx] = 1new_A_ub1 = np.insert(A_ub, A_ub.shape[0], new_con1, axis=0)new_A_ub2 = np.insert(A_ub, A_ub.shape[0], new_con2, axis=0)new_b_ub1 = np.insert(b_ub, b_ub.shape[0], -math.ceil(res.x[idx]), axis=0)new_b_ub2 = np.insert(b_ub, b_ub.shape[0], math.floor(res.x[idx]), axis=0)# 将新约束条件加入队列,先加最优值大的那一支r1 = linprog(self.c, new_A_ub1, new_b_ub1, self.A_eq,self.b_eq, self.bounds)r2 = linprog(self.c, new_A_ub2, new_b_ub2, self.A_eq,self.b_eq, self.bounds)if not r1.success and r2.success:self.Q.put((r2, new_A_ub2, new_b_ub2))elif not r2.success and r1.success:self.Q.put((r1, new_A_ub1, new_b_ub1))elif r1.success and r2.success:if -r1.fun > -r2.fun:self.Q.put((r1, new_A_ub1, new_b_ub1))self.Q.put((r2, new_A_ub2, new_b_ub2))else:self.Q.put((r2, new_A_ub2, new_b_ub2))self.Q.put((r1, new_A_ub1, new_b_ub1))

4.定义求解问题中的变量级约束条件

def test():""" 此测试的真实最优解为 [4, 2] """c = np.array([40, 90])A = np.array([[9, 7], [7, 20]])b = np.array([56, 70])Aeq = Nonebeq = Nonebounds = [(0, None), (0, None)]solver = ILP(c, A, b, Aeq, beq, bounds)solver.solve()print("Test 's result:", solver.opt_val, solver.opt_x)print("Test 's true optimal x: [4, 2]\n")

5.求解并输出

if __name__ == '__main__':test()

完整代码如下:

from scipy.optimize import linprog
import numpy as np
import math
import sys
from queue import Queueclass ILP():def __init__(self, c, A_ub, b_ub, A_eq, b_eq, bounds):# 全局参数self.LOWER_BOUND = -sys.maxsizeself.UPPER_BOUND = sys.maxsizeself.opt_val = Noneself.opt_x = Noneself.Q = Queue()# 这些参数在每轮计算中都不会改变self.c = -cself.A_eq = A_eqself.b_eq = b_eqself.bounds = bounds# 首先计算一下初始问题r = linprog(-c, A_ub, b_ub, A_eq, b_eq, bounds)# 若最初问题线性不可解if not r.success:raise ValueError('Not a feasible problem!')# 将解和约束参数放入队列self.Q.put((r, A_ub, b_ub))def solve(self):while not self.Q.empty():# 取出当前问题res, A_ub, b_ub = self.Q.get(block=False)# 当前最优值小于总下界,则排除此区域if -res.fun < self.LOWER_BOUND:continue# 若结果 x 中全为整数,则尝试更新全局下界、全局最优值和最优解if all(list(map(lambda f: f.is_integer(), res.x))):if self.LOWER_BOUND < -res.fun:self.LOWER_BOUND = -res.funif self.opt_val is None or self.opt_val < -res.fun:self.opt_val = -res.funself.opt_x = res.xcontinue# 进行分枝else:# 寻找 x 中第一个不是整数的,取其下标 idxidx = 0for i, x in enumerate(res.x):if not x.is_integer():breakidx += 1# 构建新的约束条件(分割new_con1 = np.zeros(A_ub.shape[1])new_con1[idx] = -1new_con2 = np.zeros(A_ub.shape[1])new_con2[idx] = 1new_A_ub1 = np.insert(A_ub, A_ub.shape[0], new_con1, axis=0)new_A_ub2 = np.insert(A_ub, A_ub.shape[0], new_con2, axis=0)new_b_ub1 = np.insert(b_ub, b_ub.shape[0], -math.ceil(res.x[idx]), axis=0)new_b_ub2 = np.insert(b_ub, b_ub.shape[0], math.floor(res.x[idx]), axis=0)# 将新约束条件加入队列,先加最优值大的那一支r1 = linprog(self.c, new_A_ub1, new_b_ub1, self.A_eq,self.b_eq, self.bounds)r2 = linprog(self.c, new_A_ub2, new_b_ub2, self.A_eq,self.b_eq, self.bounds)if not r1.success and r2.success:self.Q.put((r2, new_A_ub2, new_b_ub2))elif not r2.success and r1.success:self.Q.put((r1, new_A_ub1, new_b_ub1))elif r1.success and r2.success:if -r1.fun > -r2.fun:self.Q.put((r1, new_A_ub1, new_b_ub1))self.Q.put((r2, new_A_ub2, new_b_ub2))else:self.Q.put((r2, new_A_ub2, new_b_ub2))self.Q.put((r1, new_A_ub1, new_b_ub1))def test():""" 此测试的真实最优解为 [4, 2] """c = np.array([40, 90])A = np.array([[9, 7], [7, 20]])b = np.array([56, 70])Aeq = Nonebeq = Nonebounds = [(0, None), (0, None)]solver = ILP(c, A, b, Aeq, beq, bounds)solver.solve()print("Test 's result:", solver.opt_val, solver.opt_x)print("Test 's true optimal x: [4, 2]\n")if __name__ == '__main__':test()

结果:最优解 x1=4 , x2 = 2 ; 最优值为340;符合题意

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Atmel跑Linux的arm芯片,Linux已被移植到Atmel的ATmega微控制器

Ubuntu Linux发行版已经被移植到最便宜、最便携的平台中&#xff1a;一个Atmel的ATmega微控制器。拥有一个20MHz的8位AVR处理器&#xff0c;128KB的闪存和整块16KB的SRAM&#xff0c;ATmega1284P并不是建立微型计算机最合乎逻辑的选择。它是在Arduino原型平台中找到的同样基础的…

Android Studio 详细安装教程

在我们的日常 Android 开发中&#xff0c;一个好的开发工具是必不可少的------Android Studio&#xff0c;是一个最重要的开发工具。 下面我将详细介绍Android Studio的下载安装。 一、安装环境及下载资源 1.1 安装环境 电脑系统 : Windows 10 JDK 版本 : 1.8 Android Stud…

零基础爬虫requests初阶教程,手把手教你爬数据

目录 一、环境与工具 二、学爬虫必备知识 三、简单体验 requests 四、get 请求 3.1 基础讲解一 3.3 基础讲解二 3.2 基础讲解三 3.4 获取cookie 3.5 获取请求头 3.6 添加请求头 3.5 知乎爬取反扒技术 3.6 抓取二进制数据 3.7 美女私房照爬取&#xff08; 准备发车…

vsftpd的主配置文件是什么linux,vsftpd.conf配置文件详解

vsftpd.conf配置文件详解# 是否允许匿名用户登录。默认值为YES。anonymousYES|NO# 是否允许匿名用户上传文件(如果设置为YES&#xff0c;则write_enable也必须设置为YES)。默认值为NO。anon_upload_enableYES|NO# 是否允许匿名用户创建目录(如果设置为YES&#xff0c;则write_e…

【youcans 的图像处理学习课】11. 形态学图像处理(上)

专栏地址&#xff1a;『youcans 的图像处理学习课』 文章目录&#xff1a;『youcans 的图像处理学习课 - 总目录』 【youcans 的图像处理学习课】11. 形态学图像处理&#xff08;上&#xff09; 【youcans 的图像处理学习课】11. 形态学图像处理&#xff08;中&#xff09; 【y…

Android Sdk 安装配置

在我们安装了Android Studio之后&#xff0c;我们发现不能使用&#xff0c;因为缺少一个Sdk的配置&#xff0c;下面就给大家详细介绍一下Sdk的配置。 打开我们的Android Studio。 选择Do not import settinge&#xff0c;然后点击OK。 点击 Cancel 退出即可&#xff0c;后面…

爬虫requests高阶篇详细教程

文章目录 一、前言 二、SSL验证 三、代理设置 四、超时设置 ​ 五、身份认证 1&#xff09;基本身份认证 2&#xff09;摘要式身份认证 六、总结 一、前言 本篇文高阶篇&#xff0c;上一篇为基础篇&#xff0c;希望你一定要学完基础再来看高阶篇内容 基础篇文章可以看大…

Android Studio 创建第一个项目应用

选择打开"Start a new Android Studio project"&#xff0c;新建一个Android项目。 选择一个空白的Activity&#xff0c;然后点击Next。 修改相应Android项目的名称、包名、项目位置等&#xff0c;以符合项目要求&#xff0c;点击Finish。 第一次创建项目可能会这样…

主成分分析(PCA)及其可视化——matlab

本文所用为matlab2016a matlab安装&#xff1a;待更新 matlab基础知识&#xff1a;待更新 如果本文内容已学会&#xff0c;可以看看python的哦 主成分分析&#xff08;PCA&#xff09;及其可视化——python_菜菜笨小孩的博客-CSDN博客 文章目录 一、主成分分析的原理 二…

Android studio真机调试

在我们进行Android开发的时候&#xff0c;调试这个环节是必不可少的也是至关重要的&#xff0c;使用真机调试可以更加准确清晰的显示效果。 真机调试Android应用 1.用数据线将手机连接到电脑&#xff0c;打开手机的开发者选项。 由于各个手机厂商的打开方式都不同&#xff0…

主成分分析(PCA)及其可视化——python

可以看看这个哦python入门&#xff1a;Anaconda和Jupyter notebook的安装与使用_菜菜笨小孩的博客-CSDN博客 如果你学会了python 可以看看matlab的哦 主成分分析&#xff08;PCA&#xff09;及其可视化——matlab_菜菜笨小孩的博客-CSDN博客 目录 一、主成分分析的原理 二…

Emulator: PANIC: Cannot find AVD system path. Please define ANDROID_SDK_ROOT

我们安装完毕Android Studio之后&#xff0c;创建第一个项目&#xff0c;我们想要使用模拟器进行运行&#xff0c;但是当我们启动模拟器的时候却发现无法启动&#xff0c;而且出现了错误信息。 首先我们要知道错误信息是什么&#xff1f; 提示信息的意思是说“avd系统路径找不…

多元线性回归模型-数学建模类-matlab详解

如果本文有点小难理解的话&#xff0c;可以看看我之前的基础线性规划啥的&#xff0c;有lingo&#xff0c;matlab还有python 就不给大家放链接了&#xff0c;想看的话&#xff0c;点击头像即可&#xff01;&#xff01; 文章目录 &#xff08;1&#xff09;一元线性回归之旧…

手把手教你爬虫requests实战演练——python篇

文章目录 一、前言 二、实战 1&#xff09;获取百度网页并打印 2&#xff09;获取帅哥图片并下载到本地 4) 获取美女视频并下载到本地 5&#xff09;搜狗关键词搜索爬取 6&#xff09;爬取百度翻译 7&#xff09;爬取豆瓣电影榜单 8&#xff09;JK妹子爬取 总结&#xff…

Android studio 3.x 安装genymotion插件

在日常的Android开发中&#xff0c;模拟器是必不可少的&#xff0c;下面就给大家讲解一下如何在Android studio 3.x 安装genymotion插件。 对于Android studio 3.x之前的版本&#xff0c;可以直接在插件那里在线安装genymotion插件。 Android studio 3.0版本之后就搜索不到了…

图片弹框

用js实现图片弹框的特效。 效果展示 代码展示 html内容 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title></title></head><body><img id"myImg" src"img/c_7…

最短路径和距离及可视化——matlab

文章目录 一、前言 二、最短路线 2.1 教程 2.1.1 sparse创建稀疏矩阵 2.1.2 有向图最短路径&#xff08;1&#xff09; 2.1.3 有向图最短路径&#xff08;2&#xff09; 2.1.4 无向图最短路径&#xff08;1&#xff09; 2.1.5无向图最短路径&#xff08;2&#xff09; …

没有bug队——加贝——Python 练习实例 1,2

目录 1.题目&#xff1a; 2.题目&#xff1a; 1.题目&#xff1a; 有四个数字&#xff1a;1、2、3、4&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;各是多少&#xff1f; 程序分析&#xff1a;可填在百位、十位、个位的数字都是1、2、3、4。组成所有的…

【OpenCV 例程300篇】250. 梯度算子的传递函数

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程300篇】250. 梯度算子的传递函数 1. 空间卷积与频域滤波 空间域图像滤波是图像与滤波器核的卷积&#xff0c;而空间卷积的傅里叶变换是频率域中相应变换的乘积&#xff0c;因此频率域图像滤波是频率域滤波器…

JS贪吃蛇

Js实现贪吃蛇小游戏。 程序解析&#xff1a; 画表格&#xff0c;画出相对应大小的表格速度的快慢调节随机生成事物的位置使用键盘的方向键控制移动位置当贪吃蛇碰到四周游戏结束&#xff0c;弹框显示效果演示 代码演示 html内容 <!DOCTYPE html> <html><he…