1. 项目概述:从“清风数学建模”到线性规划的核心
如果你正在准备数学建模竞赛,或者在工作中需要处理资源分配、生产计划这类优化问题,那么“线性规划”这四个字你一定不陌生。尤其是在“清风数学建模”这个圈子里,规划论,特别是线性规划,几乎是每个参赛者必须掌握的“硬通货”。它不像一些复杂的机器学习模型那样听起来高大上,但它的实用性和普适性,在解决实际问题时,往往能起到四两拨千斤的效果。
简单来说,线性规划就是在一组线性等式或不等式的约束条件下,去求解一个线性目标函数的最大值或最小值。听起来有点抽象?我举个例子:你是一个工厂的生产经理,手上有一定数量的原材料、机器工时和工人,你需要决定生产A、B两种产品各多少,才能在资源有限的情况下,让总利润达到最高。这里的“利润”就是你的目标函数(比如 5A + 8B),“原材料、工时”的限制就是约束条件(比如 2A + 3B ≤ 100)。线性规划要做的,就是帮你找到那个最优的A和B的产量组合。
为什么“清风数学建模”特别强调它?因为在国赛、美赛等数学建模竞赛中,优化类问题出现的频率极高。无论是运输调度、投资组合、还是人员排班,其内核往往都能抽象成一个线性规划模型。掌握了它,你就等于握住了一把打开许多赛题大门的钥匙。而且,线性规划的理论清晰,求解工具成熟(从简单的Excel规划求解到专业的MATLAB、Python库),非常适合在有限竞赛时间内构建并求解一个可靠的模型。网络上常说的“线性规划svm”这个热词,其实是个有趣的混合,它把经典的优化方法(线性规划)和现代的机器学习算法(支持向量机SVM)联系了起来,虽然两者在数学形式上有关联(SVM的原始问题可以转化为一个二次规划问题),但这恰恰说明了线性规划思想在更广阔领域的渗透和基础地位。
接下来,我将以一个从业者和多次指导建模竞赛的视角,为你彻底拆解线性规划。我们不仅会搞懂它的数学原理,更会聚焦于如何将它从一个抽象的数学公式,变成解决实际问题的利器,涵盖从模型建立、软件求解到结果分析的完整链条,并分享那些在课本和官方文档里不会明说的实操技巧与避坑指南。
2. 线性规划的核心思想与数学模型拆解
2.1 模型三要素:决策变量、目标函数与约束条件
任何线性规划模型,都像搭建一个积木城堡,离不开三块最基础的积木:决策变量、目标函数和约束条件。理解这三者,你就理解了线性规划的全部。
决策变量:这是你模型中的“未知数”,是你能够控制的因素。在上面的生产例子中,产品A和B的产量x1和x2就是决策变量。它们必须是连续可分的(通常是非负实数),这意味着你可以生产3.5件产品,这是线性规划与整数规划的关键区别。在建模时,给变量起一个清晰的名字至关重要,比如用x_ij表示从i地运往j地的货物量,这能极大提升模型的可读性和调试效率。
目标函数:这是你追求的“目标”,必须表示成决策变量的线性组合。要么是最大化(如利润、效率),要么是最小化(如成本、时间)。其形式为Z = c1*x1 + c2*x2 + ... + cn*xn。系数c1, c2...的经济或物理意义必须明确,比如单位利润、单位成本。一个常见的误区是目标函数写得太复杂,试图把多个目标揉在一起。记住,标准的线性规划是单目标优化。如果遇到多目标(既要利润高又要风险低),你需要使用目标规划或将其一个目标转化为约束条件。
约束条件:这是现实世界给你的“紧箍咒”,限制了决策变量的取值范围。它们也必须是以决策变量构成的线性等式或不等式。资源限制(≤)、最低需求(≥)、供需平衡(=)是主要的约束类型。例如:
- 原材料约束:
2*x1 + 4*x2 ≤ 800(生产消耗的原材料不能超过800单位) - 市场需求约束:
x1 ≤ 300(产品A的市场需求上限是300) - 非负约束:
x1 ≥ 0, x2 ≥ 0(产量不能为负,这是默认隐含条件,但务必显式写出)
注意:约束条件的右端项(即不等式右边的常数)的量纲必须一致。你不能把“工时(小时)”和“原材料(吨)”直接相加放在一个约束里。每个约束都应描述一个独立的限制条件。
2.2 可行域与最优解:几何直观理解
把只有两个决策变量的模型画在坐标系里,是理解线性规划最直观的方式。每个线性不等式都对应坐标系中的一个半平面(比如2x1 + 3x2 ≤ 100表示直线2x1+3x2=100左下方的区域)。所有约束条件(包括非负约束)所对应的半平面的公共交集,就构成了一个凸多边形区域,称为可行域。你的所有可能方案(即每一组满足约束的(x1, x2))都落在这个区域内。
而目标函数Z = 5x1 + 8x2可以看作是一族平行的直线(等利润线)。沿着目标函数值增加的方向平移这族直线,最终它会与可行域最后一个接触的点(或边),就是最优解。这个点一定是可行域的某个顶点(对于二维是多边形的顶点,高维则是多面体的顶点)。这就是线性规划一个极其重要的性质:最优解如果存在,必定可以在可行域的某个顶点上找到。这也正是单纯形法等求解算法的理论基础——沿着边从一个顶点迭代到另一个更优的顶点,直至找到最优。
这个几何观点能帮你快速判断解的情况:
- 唯一最优解:通常发生在目标函数直线与可行域在某一个顶点相切。
- 无穷多最优解:当目标函数直线与可行域的一条边完全平行时,这条边上的所有点都是最优解。
- 无界解:可行域朝目标函数优化的方向无限延伸,意味着你的资源无限,可以赚取无限利润(现实中几乎不存在,通常是模型漏掉了关键约束)。
- 无可行解:约束条件互相矛盾,画不出公共区域。比如一个约束要求
x1 ≥ 100,另一个却要求x1 ≤ 50。这意味着你的问题设定本身不可实现。
2.3 标准化形式:为求解做准备
不同的教材和软件对线性规划模型可能有略微不同的“标准写法”。为了通用性和算法处理方便,我们通常将模型化为如下标准型:
- 目标函数统一为最小化:如果是最大化
max Z,等价于最小化min -Z。 - 约束条件统一为等式:通过引入松弛变量或剩余变量,将不等式变为等式。
- 对于
≤约束:2x1 + 3x2 ≤ 100→2x1 + 3x2 + s1 = 100,其中s1 ≥ 0称为松弛变量,代表未被使用的资源量。 - 对于
≥约束:x1 + x2 ≥ 20→x1 + x2 - s2 = 20,其中s2 ≥ 0称为剩余变量,代表超出最低要求的部分。
- 对于
- 决策变量非负:所有变量(包括引入的松弛/剩余变量)均要求
≥ 0。
标准化后的模型,其矩阵形式非常简洁:min c^T * x, s.t. A*x = b, x ≥ 0。这为编写程序和使用求解器提供了极大的便利。在实际操作中,你通常不需要手动做标准化,成熟的求解器(如MATLAB的linprog,Python的scipy.optimize.linprog)会内部处理。但理解这个过程,能让你在调试模型、理解输出结果(特别是对偶变量和松弛变量)时更加得心应手。
3. 从问题到模型:建模实战与技巧
3.1 第一步:准确的语言翻译与抽象
建模最难也最关键的一步,是把一段文字描述的现实问题,精准地翻译成数学语言。我总结了一个“三步提问法”来梳理思路:
- 要决定什么?—— 确定决策变量。寻找问题中那些你可以控制、且不同的选择会导致不同结果的量。通常问题里“分配…的数量”、“…的生产计划”、“…的路径选择”对应的就是决策变量。
- 追求什么目标?—— 确定目标函数。找到问题中“最大”、“最小”、“最优”等词后面跟的指标。明确这个指标是求和(总利润、总成本)还是其他线性组合。
- 受到哪些限制?—— 找出所有约束条件。仔细扫描题目中的每一个数字和条件陈述,问自己:这个条件对我的决策变量构成了怎样的限制?是资源上限(≤),还是最低要求(≥),或是必须满足的平衡(=)?
实战案例:营养配餐问题
某食堂需要为员工配餐,要求每份餐食中至少含有热量2000千卡,蛋白质50克,钙400毫克。现有四种食材可供选择,其每千克营养成分和价格如下表。如何搭配食材,在满足营养需求的前提下,使总成本最低?
食材 价格(元/kg) 热量(千卡/kg) 蛋白质(g/kg) 钙(mg/kg) A 10 1000 50 400 B 6 800 60 200 C 3 900 20 300 D 2 200 10 500
建模过程:
- 决策变量:设四种食材的采购量(千克)分别为
x1, x2, x3, x4。 - 目标函数:最小化总成本
min Z = 10*x1 + 6*x2 + 3*x3 + 2*x4。 - 约束条件:
- 热量约束:
1000*x1 + 800*x2 + 900*x3 + 200*x4 ≥ 2000 - 蛋白质约束:
50*x1 + 60*x2 + 20*x3 + 10*x4 ≥ 50 - 钙约束:
400*x1 + 200*x2 + 300*x3 + 500*x4 ≥ 400 - 非负约束:
x1, x2, x3, x4 ≥ 0
- 热量约束:
看,一个实际问题就这样被“翻译”成了一个标准的线性规划模型。这里所有的系数都来自题目表格,约束都是“≥”因为要求“至少”。
3.2 第二步:处理建模中的常见“陷阱”
在实际建模中,你会遇到一些需要特别处理的场景:
1. 固定成本问题:如果启用某个项目(如开工生产)需要一笔固定费用,而不仅仅是可变成本。这超出了线性范围,需要引入0-1变量,转化为混合整数线性规划(MILP)。例如,设y为0-1变量,表示是否生产,x为产量,约束可写为x ≤ M*y,其中M是一个足够大的数(称为“大M”),当y=0时强制x=0,当y=1时x可以取合理范围内的值。目标函数中加上固定成本F*y。
2. 分段线性函数:有些成本或收益不是严格线性的,比如阶梯电价、有折扣的采购价。这可以通过引入多个辅助变量和约束,将其近似或精确地转化为线性形式,核心思想是将分段函数表示为若干线性段的组合。
3. 比例或比率约束:例如“产品A的产量不能超过总产量的30%”,即x1 ≤ 0.3*(x1+x2+...)。这看起来是非线性的,但可以通过移项转化为线性:x1 - 0.3*(x1+x2+...) ≤ 0->0.7*x1 - 0.3*x2 - ... ≤ 0。
实操心得:建模时,量纲一致性检查是避免低级错误的最佳手段。列出所有约束,检查每一项的单位是否可加、是否与右端项匹配。另一个技巧是,先建立一个小规模的、只有2-3个变量的简化模型,用手算或画图验证思路是否正确,然后再扩展到全规模模型。
3.3 第三步:模型检验与敏感性分析预备
模型建立后,不要急于丢给软件求解。先做逻辑检验:
- 极端情况测试:如果某个决策变量取0或极大值,约束是否合理?目标函数是否反应了你的意图?
- 单位检验:确保目标函数和每个约束两边的单位一致。
- 可行性直觉:根据你对问题的理解,最优解的大致范围应该心里有数。如果软件求出的解严重违背直觉(比如某种极其昂贵的食材用量很大),首先要回头检查模型,而不是怀疑软件。
此外,要意识到模型中的系数(如价格、资源量)往往是估计值,可能存在波动。线性规划的敏感性分析(后优化分析)就是用来研究这些系数在多大范围内变化时,当前的最优基(即哪些变量在解中不为零)保持不变。这能告诉你模型结果的稳健性。在建模时,就要有意识地为后续的敏感性分析做准备,比如明确哪些参数是可能变化的。
4. 求解工具选择与MATLAB/Python实战
4.1 工具选型:从Excel到专业求解器
对于线性规划,可用的工具非常多,选择取决于你的场景:
- Excel规划求解:最适合初学者、小规模问题(变量和约束几百个以内)和商业场景演示。界面友好,无需编程,但处理大规模问题慢,自动化程度低。
- MATLAB:在学术界和工程界广泛使用,优化工具箱功能强大且稳定。
linprog函数接口简洁,非常适合数学建模竞赛和算法原型开发。 - Python (SciPy/PuLP):数据科学和现代算法开发的首选。
scipy.optimize.linprog提供基础求解,而PuLP库提供了更直观的建模语法,并且可以调用如CBC,GLPK, 乃至商业求解器Gurobi,CPLEX的后端,灵活性极高。 - 专业优化软件 (Lingo, Gurobi, CPLEX):用于求解超大规模、复杂的工业级问题,速度极快,支持多种高级模型。对于普通学习和竞赛,前期可能用不到。
对于“清风数学建模”的参与者,我强烈建议掌握MATLAB或Python (PuLP)。它们既能应对竞赛规模的问题,其代码形式也便于将建模、求解、结果分析整合在一个脚本中,形成清晰的解题报告。
4.2 MATLABlinprog函数深度使用
MATLAB的linprog函数是求解线性规划的核心。其标准调用格式为:
[x, fval, exitflag, output, lambda] = linprog(f, A, b, Aeq, beq, lb, ub, options)f: 目标函数系数列向量(注意是最小化)。A,b: 线性不等式约束A*x ≤ b的矩阵和向量。Aeq,beq: 线性等式约束Aeq*x = beq的矩阵和向量。lb,ub: 变量的下界和上界向量。默认lb为0(非负),ub为无穷大。x: 求得的最优解向量。fval: 最优解处的目标函数值。exitflag: 求解器退出状态,大于0表示成功找到最优解,这是判断求解是否成功的首要指标!lambda: 拉格朗日乘子,包含对偶变量和影子价格信息,用于敏感性分析。
实战:求解营养配餐问题
% 1. 定义模型参数 f = [10; 6; 3; 2]; % 目标函数系数(成本),最小化 % 不等式约束 A*x <= b (注意我们的模型是 >=,需要两边乘以-1转换) % 原约束: 1000x1+800x2+900x3+200x4 >= 2000 % 等价于: -1000x1 -800x2 -900x3 -200x4 <= -2000 A = [-1000, -800, -900, -200; -50, -60, -20, -10; -400, -200, -300, -500]; b = [-2000; -50; -400]; % 没有等式约束 Aeq = []; beq = []; % 变量下界为0(非负),上界为无穷大(默认) lb = zeros(4, 1); ub = []; % 2. 求解 options = optimoptions('linprog', 'Display', 'iter'); % 显示迭代过程 [x, fval, exitflag, output] = linprog(f, A, b, Aeq, beq, lb, ub, options); % 3. 输出结果 if exitflag > 0 fprintf('求解成功!\n'); fprintf('最优食材采购量 (kg):\n'); fprintf(' 食材A: %.4f\n', x(1)); fprintf(' 食材B: %.4f\n', x(2)); fprintf(' 食材C: %.4f\n', x(3)); fprintf(' 食材D: %.4f\n', x(4)); fprintf('最低总成本: %.2f 元\n', fval); else fprintf('求解失败或未找到最优解。退出标志: %d\n', exitflag); fprintf('输出信息: %s\n', output.message); end运行这段代码,你会得到最优解。exitflag为1表示成功。output结构体包含了迭代次数、算法等信息,对撰写建模论文很有帮助。
注意事项:
linprog默认使用对偶单纯形法,对于大多数问题都很高效。如果问题规模很大或遇到数值困难,可以通过options参数尝试切换算法,如'interior-point'(内点法)。务必养成检查exitflag的习惯,这是避免使用错误结果的第一步。
4.3 Python PuLP 建模:更直观的语法
Python的PuLP库提供了声明式的建模方式,更贴近人的思维。
from pulp import LpProblem, LpVariable, LpMinimize, LpStatus, value # 1. 创建问题 prob = LpProblem("营养配餐问题", LpMinimize) # 2. 定义决策变量 (lowBound=0 表示下界为0) x1 = LpVariable("食材A_kg", lowBound=0) x2 = LpVariable("食材B_kg", lowBound=0) x3 = LpVariable("食材C_kg", lowBound=0) x4 = LpVariable("食材D_kg", lowBound=0) # 3. 定义目标函数 prob += 10*x1 + 6*x2 + 3*x3 + 2*x4, "总成本" # 4. 添加约束条件 prob += 1000*x1 + 800*x2 + 900*x3 + 200*x4 >= 2000, "热量需求" prob += 50*x1 + 60*x2 + 20*x3 + 10*x4 >= 50, "蛋白质需求" prob += 400*x1 + 200*x2 + 300*x3 + 500*x4 >= 400, "钙需求" # 5. 求解问题 prob.solve() # 6. 输出结果 print(f"求解状态: {LpStatus[prob.status]}") if prob.status == 1: # Optimal print("最优解如下:") for v in prob.variables(): print(f" {v.name}: {v.varValue:.4f}") print(f"最低总成本: {value(prob.objective):.2f} 元") else: print("未找到最优解。")PuLP的优点是模型看起来就像数学公式,易于理解和修改。它默认调用开源的CBC求解器,对于竞赛问题完全够用。你也可以轻松切换后端求解器。
5. 结果解读、敏感性分析与模型扩展
5.1 读懂求解器输出:不止是最优解
求解器给出的不只是x和fval。以MATLAB的lambda输出为例,它包含了至关重要的影子价格信息。
lambda.ineqlin: 对应不等式约束A*x ≤ b的拉格朗日乘子(影子价格)。lambda.eqlin: 对应等式约束Aeq*x = beq的拉格朗日乘子。lambda.lower/lambda.upper: 对应变量下界/上界约束的乘子。
影子价格的经济意义:它衡量了约束条件右端项(资源量)边际增加一个单位时,目标函数最优值(如最大利润或最小成本)的改善量。在我们的营养配餐例子中,lambda.ineqlin(1)对应热量约束,如果其值为0.5,意味着如果热量需求从2000千卡增加到2001千卡,总成本将大约增加0.5元。如果影子价格为0,则表示该资源有剩余,再增加它对优化目标无益。
松弛变量:在标准化模型中引入的松弛/剩余变量,其最优解的值直接告诉你资源的利用情况。松弛变量=0表示该资源被完全利用(紧约束);大于0则表示有剩余。
5.2 敏感性分析实操:参数变化的影响
敏感性分析回答两个核心问题:
- 目标函数系数(如产品单价)在什么范围内变化,当前最优解结构(哪些产品生产)不变?
- 约束右端项(如资源总量)在什么范围内变化,当前影子价格保持不变?
MATLAB的linprog不直接提供敏感性分析报告,但我们可以通过参数化并循环求解来近似获得。Python的PuLP结合一些商业求解器后端(如Gurobi)可以直接输出敏感性分析范围。
手动进行系数敏感性分析的思路:以某个产品利润系数c_i为例,固定其他系数,逐步增大或减小c_i,重新求解,观察最优解x的结构(哪些变量为0,哪些不为0)何时发生变化。变化的临界点就是该系数的允许变化范围边界。
实操心得:在数学建模论文中,敏感性分析是体现模型深度和实用价值的重要部分。不要只满足于给出一个最优解,一定要分析“如果……会怎样”。例如,在资源分配问题中,指出哪种资源是最紧缺的(影子价格最高),增加哪种资源对提升效益最有效,这能让你的论文脱颖而出。
5.3 从线性规划到整数规划与非线性规划
线性规划是规划论的基石。当你掌握了它,就自然能理解其扩展形式:
- 整数线性规划:要求部分或全部决策变量取整数值。这用于建模离散决策,如是否投资(0-1变量)、设备台数、人员数量(必须为整数)。求解难度远大于线性规划,常用分支定界法。MATLAB中用
intlinprog,Python PuLP中在定义变量时指定cat='Integer'或'Binary'。 - 非线性规划:目标函数或约束条件中包含非线性函数。求解方法多样(如梯度下降、内点法),没有通用且保证找到全局最优的算法。MATLAB的
fmincon是常用工具。 - 多目标规划:同时优化多个相互冲突的目标。没有唯一的最优解,而是一组“帕累托最优”解。常用方法包括加权和法、目标规划法。
理解这些扩展,能让你在面对更复杂的现实问题时,知道该选用哪种建模工具。很多问题起初可以简化为线性规划来获得洞察和初始解,然后再考虑更精细的模型。
6. 常见问题、调试技巧与竞赛应用
6.1 求解失败?问题排查指南
在竞赛或工作中,模型求解失败是常事。不要慌张,按以下步骤排查:
| 问题现象 | 可能原因 | 排查与解决方法 |
|---|---|---|
exitflag为负值(MATLAB)或status非 Optimal | 1. 模型无可行解(Infeasible) 2. 模型无界(Unbounded) 3. 数值问题(Numerical issues) | 1.检查约束矛盾:逐一检查约束,特别是那些涉及“=”的等式约束,是否过于严格。尝试放松或移除部分约束看是否可行。 2.检查目标函数和约束方向:最小化成本时,是否漏掉了资源上限约束(导致成本可无限降低)?最大化利润时,是否漏掉了市场需求约束(导致利润可无限增加)? 3.检查数据量级:系数之间数量级差异过大(如 1e-10和1e10并存)会导致数值不稳定。尝试对模型进行缩放(Scaling),例如将约束两边同时除以一个常数,使系数范围在[0.1, 10]附近。 |
| 求解时间过长 | 1. 问题规模太大 2. 模型退化或结构特殊 | 1. 检查变量和约束数量。对于千级别以上的问题,考虑使用更高效的求解器(如Gurobi)或算法选项(如内点法)。 2. 尝试不同的初始解或切换求解算法(如从单纯形法切换到内点法)。 |
| 结果与预期严重不符 | 1. 目标函数系数符号错误(最大/最小弄反) 2. 约束条件方向(≤, ≥)写反 3. 单位不一致导致数量级错误 | 1.代入验证:将求得的解x代入原问题的文字描述中,手动计算目标函数值和检查每个约束是否满足,看是否符合常识。2.构建微型测试案例:用2-3个变量,手算或画图验证模型逻辑是否正确。 3.打印并仔细核对输入矩阵:确保 A,b,f等矩阵的每一个元素都正确对应原问题。 |
6.2 在数学建模竞赛中的高分技巧
基于“清风数学建模”等竞赛的特点,想拿高分,在线性规划应用上要注意:
- 模型假设清晰合理:在论文中明确列出所有假设,并论证其合理性。例如,“假设各种食材的价格和营养成分恒定”、“忽略加工过程中的损耗”。好的假设能简化模型,同时体现你的思考。
- 模型表述规范美观:在论文的模型建立部分,使用规范的数学符号,清晰地写出目标函数和所有约束条件。可以像这样:
决策变量:设
x_i表示...。目标函数:min Z = Σ c_i * x_i。约束条件:- 资源约束:
Σ a_ij * x_j ≤ b_i, ∀i。 - 需求约束:
... - 非负约束:
x_j ≥ 0, ∀j。
- 资源约束:
- 灵敏度分析深入:不要只做简单的参数变动。结合影子价格,分析哪个约束是“活跃”的(紧约束),并提出管理建议。例如,“计算结果显示电力约束的影子价格最高,建议优先考虑增加发电容量或提高能效。”
- 模型检验与稳健性分析:用不同的数据或参数进行测试,看最优解是否发生剧烈变化。如果变化很大,说明模型对某些参数敏感,需要在结论中说明这一局限性。
- 可视化结果:对于二维问题,画出可行域和等值线。对于高维问题,用条形图展示最优解中各变量的值,用表格展示敏感性分析结果。一图胜千言。
- 代码作为附录:将完整、整洁、带注释的MATLAB或Python代码放在附录中,这既是规范,也方便评委验证。
6.3 线性规划与“线性规划svm”的关联
最后,简单回应一下网络热词“线性规划svm”。支持向量机(SVM)是机器学习中一个强大的分类算法。其核心思想是寻找一个最优超平面来分隔两类数据,并且使得两类数据到该超平面的“间隔”最大。在硬间隔SVM中,这个最大化间隔的问题,可以转化为一个凸二次规划问题。
而二次规划是目标函数为二次、约束为线性的规划问题。当这个二次规划问题通过拉格朗日对偶性进行转换后,其求解过程最终会归结于求解一个线性约束的优化问题。更基础的一些SVM变体或简化版本,其模型本身就可以直接表述为线性规划。因此,“线性规划svm”这个词,反映了线性规划作为最优化基础工具,在像SVM这样的高级算法中扮演着理论基石的角色。理解线性规划,对于深入理解SVM的对偶理论和求解过程大有裨益。
掌握线性规划,远不止是学会调用一个函数。它培养的是一种将模糊的现实问题转化为清晰数学模型的结构化思维能力。这种能力,无论是在数学建模竞赛中快速破题,还是在工作中优化流程、配置资源,都是极其宝贵的。从看懂一个简单的生产计划模型,到能够独立为复杂的物流系统建模,这中间需要的是大量的练习和对每个求解结果背后意义的追问。下次当你遇到一个分配、调度、规划类问题时,不妨先问问自己:这能不能变成一个线性规划问题?很多时候,答案都是肯定的。