十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

《优化类:一》线性规划、整数规划、多目标规划

《优化类:一》线性规划、整数规划、多目标规划 算法一线性规划 (LP) —— 连续决策的“最优配比”1.1线性规划Linear Programming模型最核心的三要素1. 决策变量Decision Variables这是你要做的“选择题”。它们通常是未知数x1, x2, ..., xn代表了你能掌控的具体行动方案比如生产多少件产品 A、调配多少吨物资 B。2. 目标函数Objective Function这是你要追求的“终极目标”。它是决策变量的线性函数通常写为或比如追求利润最大化或成本最小化。3. 约束条件Constraints这是你面临的“现实限制”。它们是决策变量的线性等式或不等式组比如原材料不能超过库存、人工工时有限、市场需求有上限等。1.2 线性规划模型建立步骤从实际问题中建立数学模型一般有以下三个步骤根据影响所要达到目的的因素找到决策变量由决策变量和所在达到目的之间的函数关系确定目标函数由决策变量所受的限制条件确定决策变量所要满足的约束条件1.3 数学标准形式一定要写在论文里的(约束条件)(决策变量非负)其中c 是价值向量x 是决策变量A 是技术系数矩阵b 是资源限量。核心数学逻辑可行域是凸集最优解一定在凸集的顶点基可行解上。不需要遍历单纯形法就是沿着棱找顶点。经典例题生产计划问题某工厂生产甲、乙两种产品。生产甲产品每件需消耗原料 A 2kg原料 B 1kg生产乙产品每件需消耗原料 A 1kg原料 B 3kg。工厂现有原料 A 100kg原料 B 120kg。甲产品每件利润40 元乙产品每件利润30 元。问甲乙各生产多少利润最大建模步骤手把手写式子设决策变量设甲产品生产 x1 件乙产品生产 x2 件。写目标函数求最大统一转为最小 min−z写约束条件资源不能超原料 A 限制原料 B 限制非负性求解结果用scipy.optimize.linprog或 Lingo 求解得到 x1 36 件x2 28 件。最大利润 z 40×36 30×28 2280 元。纯小白避坑约束条件必须统一方向。如果你的题里既有“≥”又有“≤”记得乘以 -1 统一成“≤”再写进矩阵 A。另外线性规划绝对不允许出现这种乘法项否则就是非线性了算法要换import numpy as np from scipy.optimize import linprog 1. 目标函数系数 (注意linprog 只能求最小值求最大值要加负号) 原题max z 40x1 30x2 转换min (-z) -40x1 - 30x2 c [-40, -30] 2. 不等式约束矩阵 (A_ub * x b_ub) 2x1 1x2 100 1x1 3x2 120 A_ub [[2, 1], [1, 3]] b_ub [100, 120] 3. 变量边界 (x1 0, x2 0) bounds [(0, None), (0, None)] # None 代表正无穷 4. 求解 result linprog(c, A_ubA_ub, b_ubb_ub, boundsbounds, methodhighs) 5. 打印结果 【输出】: x136.00, x228.00, 利润2280.00算法二整数 / 0-1 规划 —— 离散决策的“是非选择”在规划问题中有些最优解可能是分数或小数但对于某些具体问题常要求某些变量全部或部分的解必须是整数。例如当变量代表的是机器的台数、工作的人数或装货的车数等。为了满足整数的要求初看起来似乎只要把已有的非整数解舍入化整数就可以了。实际上化整后的数不见得是可行解和最优解所以应该有特殊的方法来求解整数规划。在整数规划中如果所有变量都限制为整数则称为纯整数规划如果仅一部分变量限制为整数则称为混合整数规划。整数规划的一种特殊情形是0-1 规划它的变量仅限于 0 或 1。数学标准形式在 LP 基础上加一行限制(约束条件)(整数约束) 或(二值约束)核心数学逻辑可行域不再是连续的凸集而是离散的格点。没有了“顶点优先”的性质只能用分支定界法砍掉非整数区域或割平面法切掉不含整数的部分来隐式枚举。经典例题指派问题 / 任务分配有 3 项任务A、B、C必须分别交给 3 个工人甲、乙、丙一人完成一项。不同工人做不同任务的成本如下表。求总成本最小的指派方案。工人\任务ABC甲6元8元5元乙7元4元9元丙3元6元7元建模步骤手把手写式子设 0-1 决策变量设 xij 表示“是否派工人 i 去做任务 j”。例如 x甲A1 表示派甲做 A0 表示不派。写目标函数总成本最小写约束条件每个任务必须且只能有 1 个人做每个人必须且只能做 1 个任务任务 A 只能被一人做任务 B 只能被一人做任务 C 只能被一人做甲只能做一个任务求解结果用scipy.optimize.milp求解最优解是甲做 C5 元、乙做 B4 元、丙做 A3 元总成本12 元。纯小白避坑线性化技巧比赛中常遇到“如果选了 A就必须选 B”的逻辑。绝对不能在论文里写 if 语句必须转化为线性约束xA−xB≤0。意思是如果 xA1那么 xB 必须等于 1 才能满足 1−xB≤0如果 xA0xB 随便。import numpy as np from scipy.optimize import milp, LinearConstraint, Bounds 1. 目标函数系数 (按行展开: 甲A, 甲B, 甲C, 乙A, 乙B, 乙C, 丙A, 丙B, 丙C) c [6, 8, 5, # 甲 7, 4, 9, # 乙 3, 6, 7] # 丙 2. 约束矩阵 (共6个约束每个约束都是 1) 约束1(甲): 甲A 甲B 甲C 1 约束2(乙): 乙A 乙B 乙C 1 约束3(丙): 丙A 丙B 丙C 1 约束4(A任务): 甲A 乙A 丙A 1 约束5(B任务): 甲B 乙B 丙B 1 约束6(C任务): 甲C 乙C 丙C 1 A_eq [ [1, 1, 1, 0, 0, 0, 0, 0, 0], # 甲 [0, 0, 0, 1, 1, 1, 0, 0, 0], # 乙 [0, 0, 0, 0, 0, 0, 1, 1, 1], # 丙 [1, 0, 0, 1, 0, 0, 1, 0, 0], # 任务A [0, 1, 0, 0, 1, 0, 0, 1, 0], # 任务B [0, 0, 1, 0, 0, 1, 0, 0, 1], # 任务C ] b_eq [1, 1, 1, 1, 1, 1] # 全都等于1 3. 定义变量范围全是 0-1 变量 bounds Bounds(lb0, ub1) # 所有变量统一在0到1之间 4. 定义整数类型1 代表整数变量 (配合ub1自动变成0-1) integrality np.ones(9) # 9个变量全是整数 5. 线性约束对象 constraints LinearConstraint(A_eq, lbb_eq, ubb_eq) # lbub 代表等式约束 6. 求解 result milp(cc, constraintsconstraints, boundsbounds, integralityintegrality) 7. 打印结果将结果还原成3x3矩阵好看 【输出】: 甲-C, 乙-B, 丙-A, 总成本12算法三多目标规划 —— 冲突目标的“帕累托寻优”多目标规划简单说就是在资源有限的情况下同时追求多个“鱼和熊掌不可兼得”的目标并找出一个最平衡、最满意的解决方案。为了方便理解可以拆成三个关键点1. 核心难点目标之间“打架”多个目标现实决策中目标往往是互相冲突的。比如买东西想质量最好又想价格最低。质量好通常价格高价格低质量可能差。找工作想工资高又想工作清闲。高薪通常伴随高强度。多目标规划要处理的就是这种“按下葫芦浮起瓢”的矛盾。2. 和单目标规划的区别单目标规划只有一个明确指标比如“只求利润最大”直接算出唯一最优解就行。多目标规划没有“唯一最好”的答案因为没有一个方案能让所有目标同时达到最大。它给出的是一组“折中方案”也叫帕累托最优解。3. 怎么解决常用思路下面是各类方法的详细介绍。 帕累托方法 (Pareto-based Methods)这类方法的核心是直接寻找并呈现一组帕累托最优解即非劣解将最终的选择权交给决策者让决策者根据偏好做权衡。此类方法也称为后验方法 (A Posteriori Methods)。帕累托最优帕累托最优是指在资源分配中无法在不损害任何人的情况下让某些人变得更好的理想状态。因此形成帕累托最优边界帕累托最优边界可以这样理解在X值不变的情况下Y越高越好从而绘制出任意组合集的上边界就是我们的帕累托最优解集数学规划方法加权和法 (Weighted-Sum Approach)给每个目标赋予权重合并成单目标求解。简单但可能无法找到非凸前沿上的所有解。ε-约束法 (ε-Constraint Method)选择一个目标进行优化将其他目标转化为约束条件。能处理非凸问题但可能产生非帕累托最优解。法线边界交叉法 (Normal Boundary Intersection, NBI)和标准化法线约束法 (Normalized Normal Constraint, NNC)旨在更均匀地生成帕累托前沿上的解。进化算法 (Evolutionary Algorithms, EAs)基于种群并行搜索特别适合一次性找到一组多样化的帕累托最优解。经典算法NSGA-II非支配排序遗传算法、SPEA2改进型强度帕累托进化算法、MOPSO多目标粒子群优化、VEGA向量评估遗传算法等。 非帕累托方法 (Non-Pareto Methods)这类方法不直接寻找完整的帕累托解集而是根据决策者预先设定的偏好或目标直接导向一个最终解。它们通常更为高效但解的质量高度依赖偏好信息的准确性。目标规划法 (Goal Programming, GP)为每个目标设定一个期望达到的“目标值”然后最小化实际值与目标值的偏差。这是最常用的方法之一但缺点是有可能产生非帕累托最优的解。字典序法 (Lexicographic Method)将所有目标按重要性严格排序在保证更重要的目标最优的前提下再去优化次要目标。标量化/聚合方法 (Scalarization/Aggregation Methods)通过特定函数将多个目标合并成一个单目标如理想点法、几何加权法等。一句话总结多目标规划就是在冲突中找平衡在妥协中找最优的决策工具。它不告诉你“哪个最好”而是告诉你“有哪些不错的折中选择”最终由决策者根据主观偏好拍板。import numpy as np import pandas as pd from scipy.optimize import linprog ---------- 第一步ε-约束法 生成帕累托前沿 ---------- 项目参数项目1收益20%风险0.5项目2收益10%风险0.1 设 x 为投项目1的比例目标1收益最大f1 0.2x 0.1(1-x) 0.1 0.1x 目标2风险最小f2 0.5x 0.1(1-x) 0.1 0.4x 约束0 x 1 pareto_solutions [] # 存 (x, f1, f2) 让风险 f2 从 0.5 降低到 0.15步长0.04看收益最大能到多少 for epsilon in np.arange(0.50, 0.14, -0.04): # 目标函数最大化 f1 0.1 0.1x即最小化 -0.1x常数0.1可以忽略不影响x取值 c [-0.1] # 因为 f10.10.1x, 最大化等价于最小化 -0.1x # 约束1: 风险 lt; epsilon gt; 0.1 0.4x lt; epsilon gt; 0.4x lt; epsilon - 0.1 A_ub [[0.4]] b_ub [epsilon - 0.1] 约束2: 0 lt; x lt; 1 bounds [(0, 1)] res linprog(c, A_ubA_ub, b_ubb_ub, boundsbounds, methodhighs) if res.success: x_opt res.x[0] f1 0.1 0.1 * x_opt # 收益 f2 0.1 0.4 * x_opt # 风险 pareto_solutions.append([x_opt, f1, f2]) 转为DataFrame df pd.DataFrame(pareto_solutions, columns[x(投项目1比例), 收益(f1), 风险(f2)]) print(*30) print(【ε-约束法生成的帕累托解集】) print(df) print(*30) ---------- 第二步TOPSIS 选出折中解 ---------- 注意收益(f1) 是越大越好正向指标风险(f2) 是越小越好负向指标 data df[[收益(f1), 风险(f2)]].values 矩阵正向化与归一化 (向量归一化) norm_data data / np.sqrt((data**2).sum(axis0)) 构造加权矩阵 (这里假设收益和风险同等重要权重各0.5) weights np.array([0.5, 0.5]) weighted_matrix norm_data * weights 确定正理想解 (收益最大风险最小) 和 负理想解 (收益最小风险最大) ideal_best np.array([max(weighted_matrix[:,0]), min(weighted_matrix[:,1])]) ideal_worst np.array([min(weighted_matrix[:,0]), max(weighted_matrix[:,1])]) 计算欧氏距离 dist_best np.sqrt(((weighted_matrix - ideal_best)**2).sum(axis1)) dist_worst np.sqrt(((weighted_matrix - ideal_worst)**2).sum(axis1)) 计算贴近度 (得分越高越好) topsis_score dist_worst / (dist_best dist_worst) 将得分加入DataFrame并排序 df[TOPSIS得分] topsis_score df df.sort_values(TOPSIS得分, ascendingFalse) df[排名] range(1, len(df)1)总结LP 结尾“通过影子价格对偶变量分析发现原料 B 的紧缺程度高于原料 A建议优先采购原料 B。”IP 结尾“当变量规模超过 500 个时采用启发式截断分支在 5% 的容忍误差内求得满意解确保算法在 2 小时内收敛。”多目标结尾“决策者若偏好稳健型可选帕累托前沿左端方案若偏好激进型可选右端方案。本文给出 3 套推荐方案供管理层拍板。”
返回列表