幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

万字教你如何用Python实现线性规划

  线性规划说明什么是线性规划?
  想象一下,您有一个线性方程组和不等式系统。这样的系统通常有许多可能的解决方案。线性规划是一组数学和计算工具,可让您找到该系统的特定解,该解对应于某些其他线性函数的最大值或最小值。什么是混合整数线性规划?
  混合整数线性规划是线性规划的扩展。它处理至少一个变量采用离散整数而不是连续值的问题。尽管乍一看混合整数问题与连续变量问题相似,但它们在灵活性和精度方面具有显着优势。
  整数变量对于正确表示自然用整数表示的数量很重要,例如生产的飞机数量或服务的客户数量。
  一种特别重要的整数变量是二进制变量。它只能取零或一的值,在做出是或否的决定时很有用,例如是否应该建造工厂或者是否应该打开或关闭机器。您还可以使用它们来模拟逻辑约束。为什么线性规划很重要?
  线性规划是一种基本的优化技术,已在科学和数学密集型领域使用了数十年。它精确、相对快速,适用于一系列实际应用。
  混合整数线性规划允许您克服线性规划的许多限制。您可以使用分段线性函数近似非线性函数、使用半连续变量、模型逻辑约束等。它是一种计算密集型工具,但计算机硬件和软件的进步使其每天都更加适用。
  通常,当人们试图制定和解决优化问题时,第一个问题是他们是否可以应用线性规划或混合整数线性规划。
  以下文章说明了线性规划和混合整数线性规划的一些用例:Gurobi优化案例研究线性规划技术的五个应用领域
  随着计算机能力的增强、算法的改进以及更多用户友好的软件解决方案的出现,线性规划,尤其是混合整数线性规划的重要性随着时间的推移而增加。使用Python进行线性规划
  解决线性规划问题的基本方法称为,它有多种变体。另一种流行的方法是。
  混合整数线性规划问题可以通过更复杂且计算量更大的方法来解决,例如,它在幕后使用线性规划。这种方法的一些变体是,它涉及使用切割平面,以及。
  有几种适用于线性规划和混合整数线性规划的合适且众所周知的Python工具。其中一些是开源的,而另一些是专有的。您是否需要免费或付费工具取决于问题的规模和复杂性,以及对速度和灵活性的需求。
  值得一提的是,几乎所有广泛使用的线性规划和混合整数线性规划库都是以Fortran或C或C原生和编写的。这是因为线性规划需要对(通常很大)矩阵进行计算密集型工作。此类库称为求解器。Python工具只是求解器的包装器。
  Python适合围绕本机库构建包装器,因为它可以很好地与CC配合使用。对于本教程,您不需要任何CC(或Fortran),但如果您想了解有关此酷功能的更多信息,请查看以下资源:构建PythonC扩展模块CPython内部用C或C扩展Python
  基本上,当您定义和求解模型时,您使用Python函数或方法调用低级库,该库执行实际优化工作并将解决方案返回给您的Python对象。
  几个免费的Python库专门用于与线性或混合整数线性规划求解器交互:SciPyOptimizationandRootFindingPuLPPyomoCVXOPT
  在本教程中,您将使用SciPy和PuLP来定义和解决线性规划问题。线性规划示例
  在本节中,您将看到线性规划问题的两个示例:一个说明什么是线性规划的小问题一个与资源分配相关的实际问题,它说明了现实世界场景中的线性规划概念
  您将在下一节中使用Python来解决这两个问题。小型线性规划问题
  考虑以下线性规划问题:
  你需要找到X和使得红色,蓝色和黄色的不平等,以及不平等X0和0,是满意的。同时,您的解决方案必须对应于z的最大可能值。
  您需要找到的自变量(在本例中为x和y)称为决策变量。要最大化或最小化的决策变量的函数(在本例中为z)称为目标函数、成本函数或仅称为目标。您需要满足的不等式称为不等式约束。您还可以在称为等式约束的约束中使用方程。
  这是您如何可视化问题的方法:
  红线代表的功能2X20,和它上面的红色区域示出了红色不等式不满足。同样,蓝线是函数4x5y10,蓝色区域被禁止,因为它违反了蓝色不等式。黄线是x2y2,其下方的黄色区域是黄色不等式无效的地方。
  如果您忽略红色、蓝色和黄色区域,则仅保留灰色区域。灰色区域的每个点都满足所有约束,是问题的潜在解决方案。该区域称为可行域,其点为可行解。在这种情况下,有无数可行的解决方案。
  您想最大化z。对应于最大z的可行解是最优解。如果您尝试最小化目标函数,那么最佳解决方案将对应于其可行的最小值。
  请注意,z是线性的。你可以把它想象成一个三维空间中的平面。这就是为什么最优解必须在可行区域的顶点或角上的原因。在这种情况下,最佳解决方案是红线和蓝线相交的点,稍后您将看到。
  有时,可行区域的整个边缘,甚至整个区域,都可以对应相同的z值。在这种情况下,您有许多最佳解决方案。
  您现在已准备好使用绿色显示的附加等式约束来扩展问题:
  方程式x5y15,以绿色书写,是新的。这是一个等式约束。您可以通过向上一张图像添加相应的绿线来将其可视化:
  现在的解决方案必须满足绿色等式,因此可行区域不再是整个灰色区域。它是绿线从与蓝线的交点到与红线的交点穿过灰色区域的部分。后一点是解决方案。
  如果插入x的所有值都必须是整数的要求,那么就会得到一个混合整数线性规划问题,可行解的集合又会发生变化:
  您不再有绿线,只有沿线的x值为整数的点。可行解是灰色背景上的绿点,此时最优解离红线最近。
  这三个例子说明了可行的线性规划问题,因为它们具有有界可行区域和有限解。不可行的线性规划问题
  如果没有解,线性规划问题是不可行的。当没有解决方案可以同时满足所有约束时,通常会发生这种情况。
  例如,考虑如果添加约束xy1会发生什么。那么至少有一个决策变量(x或y)必须是负数。这与给定的约束x0和y0相冲突。这样的系统没有可行的解决方案,因此称为不可行的。
  另一个示例是添加与绿线平行的第二个等式约束。这两行没有共同点,因此不会有满足这两个约束的解决方案。无界线性规划问题
  一个线性规划问题是无界的,如果它的可行区域是无界,将溶液不是有限。这意味着您的变量中至少有一个不受约束,可以达到正无穷大或负无穷大,从而使目标也无限大。
  例如,假设您采用上面的初始问题并删除红色和黄色约束。从问题中删除约束称为放松问题。在这种情况下,x和y不会在正侧有界。您可以将它们增加到正无穷大,从而产生无限大的z值。资源分配问题
  在前面的部分中,您研究了一个与任何实际应用程序无关的抽象线性规划问题。在本小节中,您将找到与制造业资源分配相关的更具体和实用的优化问题。
  假设一家工厂生产四种不同的产品,第一种产品的日产量为x,第二种产品的产量为x2,依此类推。目标是确定每种产品的利润最大化日产量,同时牢记以下条件:第一种、第二种、第三种和第四种产品的每单位产品利润分别为20美元、12美元、40美元和25美元。由于人力限制,每天生产的总数量不能超过五十台。对于每单位第一个产品,消耗三个单位的原材料A。每单位第二产品需要两单位原料A和一单位原料B。每单位第三产品需要一单位A和两单位B。最后,每单位第四产品需要三B的单位由于运输和储存的限制,工厂每天最多可以消耗一百单位的原材料A和九十单位的B。
  数学模型可以这样定义:
  目标函数(利润)在条件1中定义。人力约束遵循条件2。对原材料A和B的约束可以从条件3和条件4中通过对每种产品的原材料需求求和得出。
  最后,产品数量不能为负,因此所有决策变量必须大于或等于零。
  与前面的示例不同,您无法方便地将其可视化,因为它有四个决策变量。但是,无论问题的维度如何,原理都是相同的。线性规划Python实现
  在本教程中,您将使用两个Python包来解决上述线性规划问题:SciPy是一个用于使用Python进行科学计算的通用包。PuLP是一个Python线性编程API,用于定义问题和调用外部求解器。
  SciPy设置起来很简单。安装后,您将拥有开始所需的一切。它的子包scipy。optimize可用于线性和非线性优化。
  PuLP允许您选择求解器并以更自然的方式表述问题。PuLP使用的默认求解器是COINORBranchandCutSolver(CBC)。它连接到用于线性松弛的COINOR线性规划求解器(CLP)和用于切割生成的COINOR切割生成器库(CGL)。
  另一个伟大的开源求解器是GNU线性规划工具包(GLPK)。一些著名且非常强大的商业和专有解决方案是Gurobi、CPLEX和XPRESS。
  除了在定义问题时提供灵活性和运行各种求解器的能力外,PuLP使用起来不如Pyomo或CVXOPT等替代方案复杂,后者需要更多的时间和精力来掌握。安装SciPy和PuLP
  要学习本教程,您需要安装SciPy和PuLP。下面的示例使用SciPy1。4。1版和PuLP2。1版。
  您可以使用pip以下方法安装两者:pythonmpipinstallUscipy1。4。pulp2。1
  您可能需要运行pulptest或sudopulptest启用PuLP的默认求解器,尤其是在您使用Linux或Mac时:pulptest
  或者,您可以下载、安装和使用GLPK。它是免费和开源的,适用于Windows、MacOS和Linux。在本教程的后面部分,您将看到如何将GLPK(除了CBC)与PuLP一起使用。
  在Windows上,您可以下载档案并运行安装文件。
  在MacOS上,您可以使用Homebrew:brewinstallglpk
  在Debian和Ubuntu上,使用apt来安装glpk和glpkutils:sudoaptinstallglpkglpkutils
  在Fedora,使用dnf具有glpkutils:sudodnfinstallglpkutils
  您可能还会发现conda对安装GLPK很有用:condainstallccondaforgeglpk
  安装完成后,可以查看GLPK的版本:glpsolversion
  有关详细信息,请参阅GLPK关于使用Windows可执行文件和Linux软件包进行安装的教程。使用SciPy
  在本节中,您将学习如何使用SciPy优化和求根库进行线性规划。
  要使用SciPy定义和解决优化问题,您需要导入scipy。optimize。linprog():fromscipy。optimizeimportlinprog
  现在您已经linprog()导入,您可以开始优化。示例1
  让我们首先解决上面的线性规划问题:
  linprog()仅解决最小化(而非最大化)问题,并且不允许具有大于或等于符号()的不等式约束。要解决这些问题,您需要在开始优化之前修改您的问题:不是最大化zx2y,你可以最小化它的负值(zx2y)。代替大于或等于符号,您可以将黄色不等式乘以1并得到小于或等于符号()的相反数。
  引入这些更改后,您将获得一个新系统:
  该系统与原始系统等效,并且将具有相同的解决方案。应用这些更改的唯一原因是克服SciPy与问题表述相关的局限性。
  下一步是定义输入值:obj〔1,2〕CoefficientforyCoefficientforxlhsineq〔〔2,1〕,Redconstraintleftside。。。〔4,5〕,Blueconstraintleftside。。。〔1,2〕〕Yellowconstraintleftsiderhsineq〔20,Redconstraintrightside。。。10,Blueconstraintrightside。。。2〕Yellowconstraintrightsidelhseq〔〔1,5〕〕Greenconstraintleftsiderhseq〔15〕Greenconstraintrightside
  您将上述系统中的值放入适当的列表、元组或NumPy数组中:obj保存目标函数的系数。lhsineq保存不等式(红色、蓝色和黄色)约束的左侧系数。rhsineq保存不等式(红色、蓝色和黄色)约束的右侧系数。lhseq保存来自等式(绿色)约束的左侧系数。rhseq保存来自等式(绿色)约束的右侧系数。
  注意:请注意行和列的顺序!
  约束左侧和右侧的行顺序必须相同。每一行代表一个约束。
  来自目标函数和约束左侧的系数的顺序必须匹配。每列对应一个决策变量。
  下一步是以与系数相同的顺序定义每个变量的界限。在这种情况下,它们都在零和正无穷大之间:bnd〔(0,float(inf)),Boundsofx。。。(0,float(inf))〕Boundsofy
  此语句是多余的,因为linprog()默认情况下采用这些边界(零到正无穷大)。
  注:相反的float(inf),你可以使用math。inf,numpy。inf或scipy。inf。
  最后,是时候优化和解决您感兴趣的问题了。你可以这样做linprog():optlinprog(cobj,Aublhsineq,bubrhsineq,。。。Aeqlhseq,beqrhseq,boundsbnd,。。。methodrevisedsimplex)optcon:array(〔0。〕)fun:16。818181818181817message:Optimizationterminatedsuccessfully。nit:3slack:array(〔0。,18。18181818,3。36363636〕)status:0success:Truex:array(〔7。72727273,4。54545455〕)
  参数c是指来自目标函数的系数。Aub和bub分别与不等式约束左边和右边的系数有关。同样,Aeq并beq参考等式约束。您可以使用bounds提供决策变量的下限和上限。
  您可以使用该参数method来定义要使用的线性规划方法。有以下三种选择:methodinteriorpoint选择内点法。默认情况下设置此选项。methodrevisedsimplex选择修正的两相单纯形法。methodsimplex选择传统的两相单纯形方法。
  linprog()返回具有以下属性的数据结构:。con是等式约束残差。。fun是最优的目标函数值(如果找到)。。message是解决方案的状态。。nit是完成计算所需的迭代次数。。slack是松弛变量的值,或约束左右两侧的值之间的差异。。status是一个介于0和之间的整数4,表示解决方案的状态,例如0找到最佳解决方案的时间。。success是一个布尔值,显示是否已找到最佳解决方案。。x是一个保存决策变量最优值的NumPy数组。
  您可以分别访问这些值:opt。fun16。818181818181817opt。successTrueopt。xarray(〔7。72727273,4。54545455〕)
  这就是您获得优化结果的方式。您还可以以图形方式显示它们:
  如前所述,线性规划问题的最优解位于可行区域的顶点。在这种情况下,可行区域只是蓝线和红线之间的绿线部分。最优解是代表绿线和红线交点的绿色方块。
  如果要排除相等(绿色)约束,只需删除参数Aeq并beq从linprog()调用中删除:optlinprog(cobj,Aublhsineq,bubrhsineq,boundsbnd,。。。methodrevisedsimplex)optcon:array(〔〕,dtypefloat64)fun:20。714285714285715message:Optimizationterminatedsuccessfully。nit:2slack:array(〔0。,0。,9。85714286〕)status:0success:Truex:array(〔6。42857143,7。14285714〕))
  解决方案与前一种情况不同。你可以在图表上看到:
  在这个例子中,最优解是红色和蓝色约束相交的可行(灰色)区域的紫色顶点。其他顶点,如黄色顶点,具有更高的目标函数值。示例2
  您可以使用SciPy来解决前面部分所述的资源分配问题:
  和前面的例子一样,你需要从上面的问题中提取必要的向量和矩阵,将它们作为参数传递给。linprog(),然后得到结果:obj〔20,12,40,25〕lhsineq〔〔1,1,1,1〕,Manpower。。。〔3,2,1,0〕,MaterialA。。。〔0,1,2,3〕〕MaterialBrhsineq〔50,Manpower。。。100,MaterialA。。。90〕MaterialBoptlinprog(cobj,Aublhsineq,bubrhsineq,。。。methodrevisedsimplex)optcon:array(〔〕,dtypefloat64)fun:1900。0message:Optimizationterminatedsuccessfully。nit:2slack:array(〔0。,40。,0。〕)status:0success:Truex:array(〔5。,0。,45。,0。〕)
  结果告诉您最大利润是1900并且对应于x5和x45。在给定条件下生产第二和第四个产品是没有利润的。您可以在这里得出几个有趣的结论:第三个产品带来的单位利润最大,因此工厂将生产最多。第一个slack是0,表示人力(第一)约束左右两边的值是一样的。工厂每天50生产单位,这是它的全部产能。第二个松弛是40因为工厂消耗了60单位的原材料A(第一种产品为15单位,第三种产品为45100单位)。第三个裕量是0,这意味着工厂消耗了所有90单位的原材料B。这全部量都用于第三个产品。这就是为什么工厂根本不能生产第二或第四种产品,也不能生产超过45单位的第三种产品。缺乏原材料B。
  opt。statusis0和opt。successisTrue,说明优化问题成功求解,最优可行解。
  SciPy的线性规划功能主要用于较小的问题。对于更大和更复杂的问题,您可能会发现其他库更适合,原因如下:SciPy无法运行各种外部求解器。SciPy不能使用整数决策变量。SciPy不提供促进模型构建的类或函数。您必须定义数组和矩阵,这对于大型问题来说可能是一项乏味且容易出错的任务。SciPy不允许您直接定义最大化问题。您必须将它们转换为最小化问题。SciPy不允许您直接使用大于或等于符号来定义约束。您必须改用小于或等于。
  幸运的是,Python生态系统为线性编程提供了几种替代解决方案,这些解决方案对于更大的问题非常有用。其中之一是PuLP,您将在下一节中看到它的实际应用。UsingPuLP
  PuLP具有比SciPy更方便的线性编程API。您不必在数学上修改您的问题或使用向量和矩阵。一切都更干净,更不容易出错。
  像往常一样,您首先导入您需要的内容:frompulpimportLpMaximize,LpProblem,LpStatus,lpSum,LpVariable
  现在您已经导入了PuLP,您可以解决您的问题。示例1
  您现在将使用PuLP解决此系统:
  第一步是初始化一个实例LpProblem来表示你的模型:CreatethemodelmodelLpProblem(namesmallproblem,senseLpMaximize)
  您可以使用该sense参数来选择是执行最小化(LpMinimize或1,这是默认值)还是最大化(LpMaximize或1)。这个选择会影响你的问题的结果。
  一旦有了模型,就可以将决策变量定义为LpVariable类的实例:InitializethedecisionvariablesxLpVariable(namex,lowBound0)yLpVariable(namey,lowBound0)
  您需要提供下限,lowBound0因为默认值为负无穷大。该参数upBound定义了上限,但您可以在此处省略它,因为它默认为正无穷大。
  可选参数cat定义决策变量的类别。如果您使用的是连续变量,则可以使用默认值Continuous。
  您可以使用变量x和y创建表示线性表达式和约束的其他PuLP对象:expression2x4ytype(expression)classpulp。pulp。LpAffineExpressionconstraint2x4y8type(constraint)classpulp。pulp。LpConstraint
  当您将决策变量与标量相乘或构建多个决策变量的线性组合时,您会得到一个pulp。LpAffineExpression代表线性表达式的实例。
  注意:您可以增加或减少变量或表达式,你可以乘他们常数,因为纸浆类实现一些Python的特殊方法,即模拟数字类型一样add(),sub()和mul()。这些方法用于像定制运营商的行为,和。
  类似地,您可以将线性表达式、变量和标量与运算符、、或以获取表示模型线性约束的纸浆。LpConstraint实例。
  注:也有可能与丰富的比较方法来构建的约束。eq(),。le()以及。ge()定义了运营商的行为,和。
  考虑到这一点,下一步是创建约束和目标函数并将它们分配给您的模型。您不需要创建列表或矩阵。只需编写Python表达式并使用运算符将它们附加到模型中:Addtheconstraintstothemodelmodel(2xy20,redconstraint)model(4x5y10,blueconstraint)model(x2y2,yellowconstraint)model(x5y15,greenconstraint)
  在上面的代码中,您定义了包含约束及其名称的元组。LpProblem允许您通过将约束指定为元组来向模型添加约束。第一个元素是一个LpConstraint实例。第二个元素是该约束的可读名称。
  设置目标函数非常相似:Addtheobjectivefunctiontothemodelobjfuncx2ymodelobjfunc
  或者,您可以使用更短的符号:Addtheobjectivefunctiontothemodelmodelx2y
  现在您已经添加了目标函数并定义了模型。
  注意:您可以使用运算符将约束或目标附加到模型中,因为它的类LpProblem实现了特殊方法。iadd(),该方法用于指定的行为。
  对于较大的问题,lpSum()与列表或其他序列一起使用通常比重复运算符更方便。例如,您可以使用以下语句将目标函数添加到模型中:AddtheobjectivefunctiontothemodelmodellpSum(〔x,2y〕)
  它产生与前一条语句相同的结果。
  您现在可以看到此模型的完整定义:modelsmallproblem:MAXIMIZE1x2y0SUBJECTTOredconstraint:2xy20blueconstraint:4x5y10yellowconstraint:x2y2greenconstraint:x5y15VARIABLESxContinuousyContinuous
  模型的字符串表示包含所有相关数据:变量、约束、目标及其名称。
  注意:字符串表示是通过定义特殊方法构建的。repr()。有关的更多详细信息。repr(),请查看PythonicOOP字符串转换:reprvsstr。
  最后,您已准备好解决问题。你可以通过调用。solve()你的模型对象来做到这一点。如果要使用默认求解器(CBC),则不需要传递任何参数:Solvetheproblemstatusmodel。solve()
  。solve()调用底层求解器,修改model对象,并返回解决方案的整数状态,1如果找到了最优解。有关其余状态代码,请参阅LpStatus〔〕。
  你可以得到优化结果作为的属性model。该函数value()和相应的方法。value()返回属性的实际值:print(fstatus:{model。status},{LpStatus〔model。status〕})status:1,Optimalprint(fobjective:{model。objective。value()})objective:16。8181817forvarinmodel。variables():。。。print(f{var。name}:{var。value()})。。。x:7。7272727y:4。5454545forname,constraintinmodel。constraints。items():。。。print(f{name}:{constraint。value()})。。。redconstraint:9。99999993922529e08blueconstraint:18。181818300000003yellowconstraint:3。3636362999999996greenconstraint:2。0000000233721948e07)
  model。objective持有目标函数model。constraints的值,包含松弛变量的值,以及对象x和y具有决策变量的最优值。model。variables()返回一个包含决策变量的列表:model。variables()〔x,y〕model。variables()〔0〕isxTruemodel。variables()〔1〕isyTrue
  如您所见,此列表包含使用的构造函数创建的确切对象LpVariable。
  结果与您使用SciPy获得的结果大致相同。
  注意:注意这个方法。solve()它会改变对象的状态,x并且y!
  您可以通过调用查看使用了哪个求解器。solver:model。solverpulp。apis。coinapi。PULPCBCCMDobjectat0x7f60aea19e50
  输出通知您求解器是CBC。您没有指定求解器,因此PuLP调用了默认求解器。
  如果要运行不同的求解器,则可以将其指定为的参数。solve()。例如,如果您想使用GLPK并且已经安装了它,那么您可以solverGLPK(msgFalse)在最后一行使用。请记住,您还需要导入它:frompulpimportGLPK
  现在你已经导入了GLPK,你可以在里面使用它。solve():CreatethemodelmodelLpProblem(namesmallproblem,senseLpMaximize)InitializethedecisionvariablesxLpVariable(namex,lowBound0)yLpVariable(namey,lowBound0)Addtheconstraintstothemodelmodel(2xy20,redconstraint)model(4x5y10,blueconstraint)model(x2y2,yellowconstraint)model(x5y15,greenconstraint)AddtheobjectivefunctiontothemodelmodellpSum(〔x,2y〕)Solvetheproblemstatusmodel。solve(solverGLPK(msgFalse))
  该msg参数用于显示来自求解器的信息。msgFalse禁用显示此信息。如果要包含信息,则只需省略msg或设置msgTrue。
  您的模型已定义并求解,因此您可以按照与前一种情况相同的方式检查结果:print(fstatus:{model。status},{LpStatus〔model。status〕})status:1,Optimalprint(fobjective:{model。objective。value()})objective:16。81817forvarinmodel。variables():。。。print(f{var。name}:{var。value()})。。。x:7。72727y:4。54545forname,constraintinmodel。constraints。items():。。。print(f{name}:{constraint。value()})。。。redconstraint:1。0000000000509601e05blueconstraint:18。181830000000005yellowconstraint:3。3636299999999997greenconstraint:2。000000000279556e05
  使用GLPK得到的结果与使用SciPy和CBC得到的结果几乎相同。
  一起来看看这次用的是哪个求解器:model。solverpulp。apis。glpkapi。GLPKCMDobjectat0x7f60aeb04d50
  正如您在上面用突出显示的语句定义的那样model。solve(solverGLPK(msgFalse)),求解器是GLPK。
  您还可以使用PuLP来解决混合整数线性规划问题。要定义整数或二进制变量,只需传递catInteger或catBinary到LpVariable。其他一切都保持不变:CreatethemodelmodelLpProblem(namesmallproblem,senseLpMaximize)Initializethedecisionvariables:xisinteger,yiscontinuousxLpVariable(namex,lowBound0,catInteger)yLpVariable(namey,lowBound0)Addtheconstraintstothemodelmodel(2xy20,redconstraint)model(4x5y10,blueconstraint)model(x2y2,yellowconstraint)model(x5y15,greenconstraint)AddtheobjectivefunctiontothemodelmodellpSum(〔x,2y〕)Solvetheproblemstatusmodel。solve()
  在本例中,您有一个整数变量并获得与之前不同的结果:print(fstatus:{model。status},{LpStatus〔model。status〕})status:1,Optimalprint(fobjective:{model。objective。value()})objective:15。8forvarinmodel。variables():。。。print(f{var。name}:{var。value()})。。。x:7。0y:4。4forname,constraintinmodel。constraints。items():。。。print(f{name}:{constraint。value()})。。。redconstraint:1。5999999999999996blueconstraint:16。0yellowconstraint:3。8000000000000007greenconstraint:0。0)model。solverpulp。apis。coinapi。PULPCBCCMDat0x7f0f005c6210
  Nowx是一个整数,如模型中所指定。(从技术上讲,它保存一个小数点后为零的浮点值。)这一事实改变了整个解决方案。让我们在图表上展示这一点:
  如您所见,最佳解决方案是灰色背景上最右边的绿点。这是两者的最大价值的可行的解决方案x和y,给它的最大目标函数值。
  GLPK也能够解决此类问题。示例2
  现在你可以使用PuLP来解决上面的资源分配问题:
  定义和解决问题的方法与前面的示例相同:DefinethemodelmodelLpProblem(nameresourceallocation,senseLpMaximize)Definethedecisionvariablesx{i:LpVariable(namefx{i},lowBound0)foriinrange(1,5)}Addconstraintsmodel(lpSum(x。values())50,manpower)model(3x〔1〕2x〔2〕x〔3〕100,materiala)model(x〔2〕2x〔3〕3x〔4〕90,materialb)Settheobjectivemodel20x〔1〕12x〔2〕40x〔3〕25x〔4〕Solvetheoptimizationproblemstatusmodel。solve()Gettheresultsprint(fstatus:{model。status},{LpStatus〔model。status〕})print(fobjective:{model。objective。value()})forvarinx。values():print(f{var。name}:{var。value()})forname,constraintinmodel。constraints。items():print(f{name}:{constraint。value()})
  在这种情况下,您使用字典x来存储所有决策变量。这种方法很方便,因为字典可以将决策变量的名称或索引存储为键,将相应的LpVariable对象存储为值。列表或元组的LpVariable实例可以是有用的。
  上面的代码产生以下结果:status:1,Optimalobjective:1900。0x1:5。0x2:0。0x3:45。0x4:0。0manpower:0。0materiala:40。0materialb:0。0
  如您所见,该解决方案与使用SciPy获得的解决方案一致。最有利可图的解决方案是每天生产5。0第一件产品和45。0第三件产品。
  让我们把这个问题变得更复杂和有趣。假设由于机器问题,工厂无法同时生产第一种和第三种产品。在这种情况下,最有利可图的解决方案是什么?
  现在您有另一个逻辑约束:如果x为正数,则x必须为零,反之亦然。这是二元决策变量非常有用的地方。您将使用两个二元决策变量y和y,它们将表示是否生成了第一个或第三个产品:1modelLpProblem(nameresourceallocation,senseLpMaximize)23Definethedecisionvariables4x{i:LpVariable(namefx{i},lowBound0)foriinrange(1,5)}5y{i:LpVariable(namefy{i},catBinary)foriin(1,3)}67Addconstraints8model(lpSum(x。values())50,manpower)9model(3x〔1〕2x〔2〕x〔3〕100,materiala)10model(x〔2〕2x〔3〕3x〔4〕90,materialb)1112M10013model(x〔1〕y〔1〕M,x1constraint)14model(x〔3〕y〔3〕M,x3constraint)15model(y〔1〕y〔3〕1,yconstraint)1617Setobjective18model20x〔1〕12x〔2〕40x〔3〕25x〔4〕1920Solvetheoptimizationproblem21statusmodel。solve()2223print(fstatus:{model。status},{LpStatus〔model。status〕})24print(fobjective:{model。objective。value()})2526forvarinmodel。variables():27print(f{var。name}:{var。value()})2829forname,constraintinmodel。constraints。items():30print(f{name}:{constraint。value()})
  除了突出显示的行之外,代码与前面的示例非常相似。以下是差异:第5行定义了二元决策变量y〔1〕并y〔3〕保存在字典中y。第12行定义了一个任意大的数M。100在这种情况下,该值足够大,因为您100每天的数量不能超过单位。第13行说如果y〔1〕为零,则x〔1〕必须为零,否则它可以是任何非负数。第14行说如果y〔3〕为零,则x〔3〕必须为零,否则它可以是任何非负数。第15行说要么y〔1〕ory〔3〕为零(或两者都是),所以要么x〔1〕or也x〔3〕必须为零。
  这是解决方案:status:1,Optimalobjective:1800。0x1:0。0x2:0。0x3:45。0x4:0。0y1:0。0y3:1。0manpower:5。0materiala:55。0materialb:0。0x1constraint:0。0x3constraint:55。0yconstraint:0。0
  事实证明,最佳方法是排除第一种产品而只生产第三种产品。线性规划求解器
  就像有许多资源可以帮助您学习线性规划和混合整数线性规划一样,还有许多具有Python包装器的求解器可用。这是部分列表:GLPKLPSolveCLPCBCCVXOPTSciPySCIPwithPySCIPOptGurobiOptimizerCPLEXXPRESSMOSEK
  其中一些库,如Gurobi,包括他们自己的Python包装器。其他人使用外部包装器。例如,您看到可以使用PuLP访问CBC和GLPK。结论
  您现在知道什么是线性规划以及如何使用Python解决线性规划问题。您还了解到Python线性编程库只是本机求解器的包装器。当求解器完成其工作时,包装器返回解决方案状态、决策变量值、松弛变量、目标函数等。

动视裁员引发罢工马斯克成无家可归任天堂法务部折戟News动视暴雪突发解雇员工《使命召唤:战区》开发者不满罢工近日,《使命召唤:战区》开发商RavenSoftware的开发者开始罢工,来抗议动视暴雪言而无信的突然裁……面对巨人杀手吉林队,广东队如何止住连败颓势峰回路转杀回巅峰第二阶段开赛以来CBA联赛广东队似乎有点NBA球队湖人的影子,易建联如队魂詹姆斯,周鹏好像浓眉哥戴维斯;苏伟更像是老将霍华德。强如这样的阵容很难想象开局居然遭遇两连败,尤其是输……助力梦想改造家!云米AI纤薄洗烘一体机Master2,究竟怎不知道大家有没有在看东方卫视的《梦想改造家》,它每期节目都会聚焦一户有住房难题的家庭,并委托设计师在有限的时间里使用有限的资金为其房屋进行房屋改造,因为去年刚刚结婚买了自己的小……深度分析没有伦纳德的快船,是如何做到胜率过半的上个赛季,在快船与爵士的季后赛中,伦纳德遭遇了膝盖伤势,直接退出了系列赛,但是在休赛期爆出了对快船来说更绝望的消息,伦纳德接受膝盖修复手术,归期未定,按照之前的经验,这种级别的……为什么人类不愿深入研究金星呢?越了解金星,便越觉得绝望在太阳系中,存在八颗行星,地球就是其中一个,行星需要围绕太阳这样的恒星运转,自身引力强大到足以客服刚体力让自身形状呈现球形,同时可以清除自身轨道附近其他的天体。满足这三个条件的……含金量不足?山东泰山夺冠的最大意义正本溯源记者陈永报道2021年12月26日,广州越秀山体育场,淅淅沥沥的细雨中,山东泰山队2比0击败河北队,提前三轮获得2021赛季中超联赛冠军,这是泰山队历史上的第5个联赛冠军,也是……新款比亚迪唐EV双电机版申报图曝光,零百加速4秒多,续航63近日,比亚迪新款唐EV双电机版车型的申报图也曝光了,同时也曝光了一些相关的信息。新车对外观设计也进行了改动,同时搭载的是双电动机,性能有很大的提升,零百加速不到5秒,而且最长续……用了这个工具后,再也不写gettersetter了作者:DrLauPen链接:https:juejin。cnpost7103135968256851976前言相信绝大多数的业务开发同学,日常的工作都离不开写getter、……让玩家听不厌的游戏音乐,背后有一门大学问2014年,米克戈登在接手重启版《毁灭战士》配乐工作的时候,收到了三个指示:他所创作的配乐要有足够的新鲜感,能够完全和游戏相符合,而且需要能够上上百万玩家一听就喜欢。米克……我们的冬奥唤醒五代人的记忆,这部动漫将创造新纪录第24届奥林匹克冬季奥运会将在北京召开,具体时间是在2022年2月4日。到时候全世界的运动员会集中到北京来,参加北京冬季奥运会。这部叫《我们的冬奥》的动画片非常给力,会让……花菜全身都是宝,鲜嫩营养,中老年多吃,简单一炒,真香叶酸冠军就是它,比胡萝卜高17倍,中老年人要多吃,强健筋骨,增强体质!冬季不养肝,40满脸斑,建议多吃这种菜,是肝的最爱,大家好我是傻姐美食,我们日常生活吃的蔬菜、水果、肉类等……烟雨中行走,感谢有你烟雨的画面却被我在这个城市所演绎,而且是那么的生动。每一天,都习惯性地把目光投向远方,任时光的列车飞驰而过,任车飞驰而过,任心驰骋。我们在尘世的烟雨中行走,感谢有你,感谢……
武汉三镇或将超越广州队,他们的这一点优势是当时广州队不具备的在本赛季的中超联赛中,武汉三镇绝对是最让球迷感到意外的一支球队了,目前他们在14轮比赛过后,依旧是排在联赛榜首的位置上,而且已经是领先了排在第二位的山东泰山4分,这在本赛季开始……建议皮肤偏黄偏黑的女人,多穿这4种高级色,衬肤色还洋气时代的审美主流,不再将女性定义为讨好男性,不再追求庸俗的曲线美感。女人穿衣打扮,真正做到了花为悦己者容,无需过多的参考外在的评价标准,遵从内心的选择,做到真正爱自己!穿衣……国产闪存半导体芯片,跳级突破128层技术,10年追平世界水平雄关漫道真如铁,而今迈步从头越。2020年底,长江存储Xtacking技术,助力其跳级量产128层堆栈闪存,没有代差,追平三星、镁光、海力士等国外大厂,达到了世界前沿水平……宝宝肌张力高一定是脑瘫吗?每个父母都希望孩子能够健康聪明,但是有出生缺陷的新生儿却屡见不鲜,他们生来就要接受不平等的待遇,他们需要和疾病不停地战斗,他们就是脑瘫宝宝。那肌张力高的宝宝一定是脑瘫吗?……赵丽颖身穿汉服,诠释东方美人如画的优雅,离婚后活出自信与自我赵丽颖为了代言一款产品,身穿汉服古装服饰,以盘发华贵的气质,手持扇子半遮面的姿态,诠释出东方美人如画的优雅。她代言的这款产品,品牌方以演绎古今大片《传承》为主,以赵丽颖古装为修……新能源55大涨半导体再跌,白酒整30医疗17白酒基金白酒上午依旧平稳,昨天收益率更新后不多不少刚好卡在了30,冥冥之中就是这么的神奇,就算跌也跌得这么让人称心如意。大多时候只要不是那种连续急跌,我基本只是看两眼然后……稳定币之王泰达币USDT为什么我可以不负责任地长概括以前,为了利息而持有Tether是没有意义的。USDC的透明度更高,两者的CeFi利率相似。最近市场条件发生了变化,使得对Tether的两位数兴趣成为一个有吸引力的前景。T……英超意甲曼联VS利物浦,罗马VS克雷莫纳,双红会谁拿到赛季首英超:004曼联VS利物浦双红会,万众瞩目,加上两队新赛季皆是未尝一胜,现场必定非常火爆曼联被打回19年前,联赛开局两连败丢6球,深究原因有几点:其一滕哈格的严格执……国羽世界冠军秀带娃美照,生活充满仪式感,女儿可爱眼神充满懵懂相信大家仍然熟悉有着极高水平的国家羽毛球运动员赵芸蕾和洪炜。这对夫妇去年9月迎来了他们的第一个新生儿。过去的八个月里,宝宝慢慢长大,妈妈的体型也恢复正常了。近期,这一家人借着天……手机的正确充电方法,你知道多少,不要再盲目地充电了在我们平常的日常生活中,大家都离不开手机,但往往大家却疏忽了对手机充电这一块,其实不正确的手机充电是很影响手机寿命的一种表现,那么我们应该如何正确的给手机充电呢。一定要注意以下……微信用户要注意出现这4种行为,或将导致你的账号被封停微信大家肯定不会陌生,在移动信息化时代,现如今人们的社交、感情和娱乐,似乎都是通过微信去维持,也正因为如此,微信在国内就有超12亿的用户使用。微信虽然很好用,但是由于用户……别替刘诗诗抱不平了,大她17岁的吴奇隆,公司早就上市了昨日有狗仔曝出一组刘诗诗吴奇隆的近况视频视频中的两人全程无交流,并相隔很远并且吴奇隆进入酒店的时候直接闪身进去酒店的门回弹还差点打到了刘诗诗的脸这时就有……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网