2. 优化问题建模基础
遗传算法并不直接理解“排班要公平”“成本要低”“结构要轻”这类自然语言目标,它只接受一种形式化的描述:一组可以取值的决策变量、一个用于评价优劣的目标函数,以及一组必须满足的约束条件。建模的任务,就是把现实问题翻译成这套数学语言,并进一步整理成遗传算法能够编码、交叉、变异和评价的形式。本节围绕这条翻译链路展开,重点说明三类要素的数学表达,以及转化过程中最容易出错的几个环节。
决策变量:确定“算法可以改什么”
决策变量是优化过程中允许被调整的量,它决定了搜索空间的维度。建模第一步不是写目标函数,而是先划定变量的边界:哪些量由我们决定,哪些量是环境给定的常量。例如一个零件下料问题,需要决定每种规格零件的下料数量,那么“各规格数量”是决策变量,而“原料长度、切割损耗率”是常量参数。
变量还需要明确类型。连续变量(如长度、温度、比例)与离散变量(如台数、班次数、是否选中)在遗传算法中的编码方式完全不同。对于 0-1 型选择变量,常用二进制编码;对于整数或连续变量,则多用实数编码。此外要给出取值范围,例如某设备投入台数 x ∈ {0,1,2,3},某参数 θ ∈ [0.1, 0.9]。范围过宽会拖慢收敛,范围过窄则可能把最优解排除在外,因此取值上下界应来自工艺能力或业务规则,而不是随意设定。
目标函数:把“好坏”压缩成一个可比较的数
目标函数把一组变量取值映射为一个实数,遗传算法依靠这个数做选择。单目标问题写作 min f(x) 或 max f(x),多目标问题则是一组函数 f₁(x), f₂(x), …。建模时要注意三点:一是量纲统一,若把成本(元)与时间(小时)直接相加,权重必须显式给出并说明依据;二是方向统一,遗传算法通常默认求最大适应度,若原问题是求最小,需要在适应度计算时做转换,如 F = 1/(1+f) 或 F = C_max − f;三是可计算性,目标函数必须能对任意一组可行或近似可行的变量取值给出数值,不能依赖人工判断。
以一个简化的生产计划为例:两种产品产量为 x₁, x₂,单位利润分别为 80 元和 120 元,则目标可写为 max f = 80x₁ + 120x₂。这个表达式本身很简单,但它已经隐含了“利润可线性叠加”的假设,建模者需要确认该假设在业务上成立。
约束条件:划定“哪些解不允许出现”
约束把搜索空间裁剪为可行域,常见形式包括资源上限(2x₁ + 3x₂ ≤ 120)、需求下限(x₁ + x₂ ≥ 10)、变量边界(x₁, x₂ ≥ 0)以及逻辑约束(如“若选 A 则必选 B”,可用 x_A ≤ x_B 表达)。在遗传算法中,约束的处理方式直接影响求解质量,常见有三种策略:
- 惩罚函数法:对违反约束的个体施加罚项,如
F = f − M·max(0, g(x)),实现简单,但罚系数 M 过小则可行解难出现,过大则早熟收敛。 - 修复法:对交叉变异产生的不可行个体做定向修正,例如超出库存上限时截断到上限,适合约束结构清晰的排产、装箱问题。
- 可行域限制法:在编码或初始化阶段就只生成可行解,如用排列编码保证每个任务只出现一次,适合旅行商、调度类问题。
从数学模型到遗传算法可求解形式
完成上述三步后,还需要一次“适配转换”,核心是编码设计与适应度映射。编码把变量向量转成染色体,例如三个整数变量各用 4 位二进制表示,则染色体长度为 12 位;解码时按位段还原为整数并检查边界。适应度函数则在目标函数基础上叠加约束处理,输出一个非负、越大越好的数值。下图展示了一个带约束的二维生产计划问题从数学描述到遗传算法求解要素的对应关系。
图中示例参数(利润系数、工时上限、种群规模等)均为教学假设值,用于说明建模与映射过程,并非实测结果。实际使用时,这些数值应替换为业务数据,并通过小规模试验确认罚系数与编码长度是否合理。
建模中最常见的三个偏差
第一是变量遗漏:把本应可调的参数当成常量,导致算法只能在很小的空间里搜索,结果“优化了但没明显改善”。第二是目标与约束错位:把硬性要求写成罚项,或把可妥协的偏好写成硬约束,前者可能产出不可行解,后者可能让可行域为空。第三是编码与变量语义脱节:例如用二进制编码表示有明确物理间隔的档位,解码后出现无意义的中间值,需要在解码函数中做离散化映射。
把上述工作做扎实,后续的种群初始化、选择算子、交叉变异才有意义。建模阶段多花时间明确变量类型、目标方向和约束处理方式,往往比在算法参数上反复调优更能提升最终解的质量。