49、基于遗传算法的优化方法及MATLAB实现

基于遗传算法的优化方法及MATLAB实现

1. 引言

在优化问题中,传统方法往往在处理复杂的目标函数和约束条件时存在一定的局限性。而遗传算法(Genetic Algorithm,GA)作为一种基于生物进化原理的优化方法,为解决这些复杂问题提供了新的思路。它适用于目标函数和/或约束函数高度非线性、不可微或不连续的优化问题,并且变量可以是连续的、离散的或两者的组合。

2. 遗传算法基础

2.1 遗传算法原理

遗传算法基于生物进化和适者生存的原则。与传统方法从单个点开始并在每次迭代中生成单个点不同,遗传算法从一组随机点(称为种群)开始,并在算法的每次迭代(代)中生成一组随机点(称为个体)。遗传算法使用三种算子来改进种群并收敛到最终的解种群,分别是选择、交叉和变异:
- 选择算子 :在种群中识别父代。
- 交叉算子 :应用于随机选择并匹配的两个父代,以产生子代。
- 变异算子 :应用于个体,以在种群中产生多样性。

这些操作在每一代中执行,当种群无法再改进或达到最大迭代次数时,算法停止。由于遗传算法是一种随机优化方法,每次运行可能会产生略有不同的解。

2.2 MATLAB中的遗传算法函数

MATLAB提供了两个基于遗传算法的函数: ga gamultiobj
- ga 函数 :用于解决单目标优化问题,形式如下:

minimize
x
f(x)
subject to:
lb ≤ x ≤ ub
Ceq(x) = 0    (nonlinear equality constraints)
C(x) ≤ 0   (nonlinear inequality constraints)
Aeqx = beq (linear equality constraints)
Ax ≤ b   (linear inequality constraints)

基本命令为:

[x, f] = ga(@UserFunction, nvars, A, b, Aeq, beq, lb, ub, @NonLinConstr, options)

其中:
- UserFunction :计算目标函数的函数名。
- nvars :变量的数量。
- A b :线性不等式约束的系数。
- Aeq beq :线性等式约束的系数。
- lb ub :变量的下界和上界向量。
- NonLinConstr :定义非线性不等式和等式约束的函数。
- options :设置 gaoptimset 中描述的参数。

  • gamultiobj 函数 :用于解决多目标优化问题,形式如下:
minimize
x
{f1, f2, …, fm}
subject to:
lb ≤ x ≤ ub
Aeqx = beq      (linear equality constraints)
Ax ≤ b           (linear inequality constraints)

MATLAB函数为:

[x, f] = gamultiobj(@UserFunction, nvars, A, b, Aeq, beq, lb, ub, options)

其中:
- x :获得的Pareto解。
- f :对应的目标函数值。
- 其他参数与 ga 函数类似。

2.3 约束处理

ga gamultiobj 函数中,变量可以是连续的或二进制的(0或1)。但在当前版本的MATLAB中,当 'PopulationType' 选项设置为 'bitstring' (二进制)时,线性和非线性约束可能不满足。为了解决这个问题,可以将约束以不可行性约束的形式添加到目标函数中。即当约束被违反时,将一个大的惩罚项添加到目标函数中,否则惩罚项设置为零。惩罚方法的表达式为:

minimize
x
f + P[max(0, (Ax - b)) +  max(0, C(x)) + (Aeqx - beq)2 + Ceq
2 ]

其中 P 是一个大的惩罚参数。

3. 示例分析

3.1 示例1:背包问题(单目标,二进制变量)

考虑一个背包问题,通过最小化以下目标函数来确定七个二进制变量:

minimize f(x) = -(12x1 + 12x2 + 9x3 + 15x4 + 90x5 + 26x6 + 112x7) + P max[0, (3x1 + 4x2 + 3x3 + 3x4 + 15x5 + 13x6 + 16x7 - 35)]

其中 P 设置为100。MATLAB代码如下:

function Example13_20
    nvars = 7;
    options = gaoptimset;
    options = gaoptimset(options, 'PopulationType', 'bitstring');
    options = gaoptimset(options, 'PopulationSize', 100);
    options = gaoptimset(options, 'PlotFcns', {@gaplotbestf, @gaplotbestindiv});
    [x, f] = ga(@KnapsackObj, nvars, [], [], [], [], [], [], [], options);
    disp([repmat('x(', 7,1) num2str((1:7)') repmat(') = ', 7,1) int2str(x')])
    disp(['Total value of placed objects = $' num2str(-f, '%6.2f')])
end

function f = KnapsackObj(x)
    P = 100;
    c = 3*x(1)+4*x(2)+3*x(3)+3*x(4)+15*x(5)+13*x(6)+16*x(7)-35;
    f = -(12*x(1)+12*x(2)+9*x(3)+15*x(4)+90*x(5)+26*x(6)+112*x(7))+P*max(0,c);
end

运行该程序,得到的结果与之前的示例一致。

3.2 示例2:两杆桁架问题(单目标,连续变量)

考虑两杆桁架问题,通过 ga 函数求解,同时对变量进行缩放以提高数值精度。MATLAB代码如下:

function Example13_21
    global sigma
    nvars = 3;
    lb = [100, 0, 0];
    ub = [300, 20, 20];
    sigma = 1e5;
    options = gaoptimset;
    options = gaoptimset(options, 'PopulationSize', 60);
    options = gaoptimset(options, 'Generations', 200);
    options = gaoptimset(options, 'Display', 'final');
    options = gaoptimset(options, 'PlotFcns', {@gaplotbestindiv, @gaplotscorediversity});
    [x, V] = ga(@TwoBarTrussObj, nvars, [], [], [], [], lb, ub, @TwoBarTrussNonLinCon, options);
    disp(['y = ' num2str(x(1)) ' cm x1 = ' num2str(x(2)) ' cm^2 x2= ' num2str(x(3)) ' cm^2 Volume = ' num2str(V*1e6) ' cm^3'])
end

function f = TwoBarTrussObj(x)
    x(1) = x(1)/1e2;
    x(2:3) = x(2:3)/1e4;
    % Values scaled
    f = x(2)*sqrt(16+x(1)^2)+x(3)*sqrt(1+x(1)^2);
end

function [C, Ceq] = TwoBarTrussNonLinCon(x)
    global sigma
    x(1) = x(1)/1e2;
    x(2:3) = x(2:3)/1e4;
    % Values scaled
    C(1) = 20*sqrt(16+x(1)^2)-sigma*x(1)*x(2);
    C(2) = 80*sqrt(1+x(1)^2)-sigma*x(1)*x(3);
    Ceq = [];
end

运行该程序,结果与之前的示例相当吻合。由于遗传算法的随机性,每次运行 ga 可能会产生略有不同的结果,因此通常建议多次运行并选择目标函数值最小的解。

3.3 示例3:两杆桁架问题(多目标,连续变量)

将两杆桁架问题转换为多目标形式,使用 gamultiobj 函数求解。目标函数如下:

minimize {f1, f2}
subject to:
0.05 ≤ (x1, x2) ≤ 0.25
1 ≤ y ≤ 3
80√(1 + y²)/(σyx2) - 1 ≤ 0
f2 = 20√(16 + y²)/(σyx1) - 1
where f1 = x1√(16 + y²) + x2√(1 + y²)

MATLAB代码如下:

function Example13_22
    global P sigma
    P = 100;
    sigma = 1e5;
    nvars = 3;
    lb = [0.05, 0.05, 1];
    ub = [0.25, 0.25, 3];
    options = gaoptimset;
    options = gaoptimset(options, 'Vectorized', 'on');
    [x, V] = gamultiobj(@TwoBarTrussTwoObj, nvars, [], [], [], [], lb, ub, options);
    [f , C] = TwoBarTrussTwoObj(x);
    disp(C)
    plot(V(:,1),V(:,2), 'k*')
    xlabel('f_1')
    ylabel('f_2')
    grid on
end

function [f, C] = TwoBarTrussTwoObj(x)
    global P sigma
    f1(:,1) = x(:,1).*sqrt(16+x(:,3).^2)+x(:,2).*sqrt(1+x(:,3).^2);
    f1(:,2) = 20*sqrt(16+x(:,3).^2)./(sigma*x(:,1).*x(:,3))-1;
    C (:,1) = 80*sqrt(1+x(:,3).^2)./(sigma*x(:,2).*x(:,3))-1;
    f(:,1) = f1(:,1)+P*max(0,C(:,1));
    f(:,2) = f1(:,2)+P*max(0,C(:,1));
end

运行该程序,得到Pareto最优解,并绘制Pareto前沿图。需要验证约束条件是否满足,在本示例中, C < 0

3.4 示例4:两杆桁架问题(单目标,连续和离散变量)

假设两杆桁架问题具有混合连续 - 离散变量,变量 x1 x2 为连续变量,变量 y 为离散变量,取值为 {1, 1.3, 1.6, 1.9, 2.2, 2.5, 2.8} 。目标函数为:

minimize 
f = x1√(16 + y²) + x2√(1 + y²)
subject to:
0 ≤ (x1, x2) ≤ 0.25
80√(1 + y²)/(σyx2) - 1 ≤ 0
20√(16 + y²)/(σyx1) - 1 ≤ 0

为了处理连续变量,将其通过二进制变量表示。对于连续变量 x ,定义在闭区间 [lb, ub] 内,可以表示为:

x = lb + (ub - lb)/(2^N - 1) * D(s)
where D(s) = ∑(i = 0 to N - 1) 2^i * si, si = 0 or 1

其中 N 是所需的最小二进制变量数量,通过以下公式计算:

N = 1 + floor(d + log10(ub - lb) / log10(2))

d 是所需的有效小数位数。

MATLAB代码如下:

function Example13_23
    nvars = 47;
    PopulationSize = 100;
    Generations = 100;
    options = gaoptimset;
    options = gaoptimset(options, 'PopulationType', 'bitstring');
    options = gaoptimset(options, 'PopulationSize', PopulationSize);
    options = gaoptimset(options, 'Generations', Generations);
    options = gaoptimset(options, 'PlotFcns', {@gaplotbestindiv, @gaplotscorediversity});
    [x, fval] = ga(@TwoBarTrussTwoObjGa, nvars, [], [], [], [], [], [], [], options);
    finalx1 = GetRealFromBinary(x, 1, 22, 0, 0.25);
    finalx2 = GetRealFromBinary(x, 23, 44, 0, 0.25);
    finaly = GetDiscreteFromBinary(x, 45, 47);
    disp(['x1 = ' num2str(finalx1*1e4) ' cm^2 x2 = ' num2str(finalx2*1e4) ' cm^2 y = ' num2str(finaly*100) ' cm'])
    disp(['V = ' num2str(fval*1e6)])
end

function f = TwoBarTrussTwoObjGa(x)
    P = 100;
    sigma = 1e5;
    var(1) = GetRealFromBinary(x, 1, 22, 0, 0.25);
    var(2) = GetRealFromBinary(x, 23, 44, 0, 0.25);
    var(3) = GetDiscreteFromBinary(x, 45, 47);
    f1 = var(1)*sqrt(16+var(3)^2)+var(2)*sqrt(1+var(3)^2);
    C1 = 80*sqrt(1+var(3)^2)/(sigma*var(2)*var(3))-1;
    C2 = 20*sqrt(16+var(3)^2)/(sigma*var(1)*var(3))-1;
    f = f1+P*(max(0,C1)+max(0,C2));
end

function x = GetRealFromBinary(y, startbit, endbit, lowerlimit, upperlimit)
    temp = y(startbit:endbit);
    ii = length(temp);
    newint = 0;
    for i = 1:ii
        newint = newint + temp(i)*2^(i - 1);
    end
    maxbitvalue = 2^(length(temp)) - 1;
    x = lowerlimit + (upperlimit - lowerlimit)/maxbitvalue * newint;
end

function x = GetDiscreteFromBinary(y, startbit, endbit)
    choice = [1, 1.3, 1.6, 1.9, 2.2, 2.5, 2.8];
    temp = y(startbit:endbit);
    ii = length(temp);
    newint = 0;
    for i = 1:ii
        newint = newint + temp(i)*2^(i - 1);
    end
    if newint == 0
        x = choice(1);
    else
        x = choice(newint);
    end
end

运行该程序,得到优化结果。由于变量 y 被限制为离散值,该解可能比之前的示例稍差。

4. MATLAB优化工具箱函数总结

MATLAB函数 描述
bintprog 二进制整数规划求解器
fgoalattain 多目标目标达成求解器
fminbnd 固定区间上单变量函数的最小值
fmincon 约束非线性多变量函数的最小值
fminimax 极小极大求解器
fminsearch 无约束多变量函数的最小值
fminunc 无约束多变量函数的最小值
fseminf 半无限约束多变量非线性函数的最小值
linprog 线性规划求解器
lsqcurvefit 非线性最小二乘曲线拟合求解器
lsqnonlin 非线性最小二乘求解器
quadprog 二次规划求解器
ga 实现遗传算法,求解单目标函数的最小值
gamultiobj 实现遗传算法,求解多目标函数的最小值

5. 遗传算法优化流程

graph TD;
    A[初始化种群] --> B[评估适应度];
    B --> C{是否满足停止条件};
    C -- 是 --> D[输出最优解];
    C -- 否 --> E[选择操作];
    E --> F[交叉操作];
    F --> G[变异操作];
    G --> B;

通过以上内容,我们可以看到遗传算法在解决复杂优化问题方面的强大能力,以及MATLAB提供的相关函数为我们实现这些算法提供了便利。在实际应用中,可以根据具体问题选择合适的优化方法和函数。

6. 优化问题练习案例

6.1 两杆机构平衡问题

考虑一个两杆机构,受到外部力作用,通过最小化势能函数来获得机构的平衡状态。势能函数为:

minimize PE = -P1*L1*sin(α) - P2*L2*sin(β) + 2*P3*[L1*(1 - cos(α)) + L2*(1 - cos(β))]

操作步骤如下:
1. 创建势能函数的等高线和曲面图。
2. 使用 fminunc 函数,以初始点 (α, β) = (1, 1) 进行求解,得到 α = 0.4636 rad β = 0.1651 rad PE = -0.3789

6.2 水道设计优化问题

对于水道的设计,目标是在固定横截面积的情况下,最大化流量。流量与湿周的倒数成正比,湿周 p = c + 2*h/sin(θ) ,横截面积 A = c*h + h^2*cot(θ) 。要最小化的函数为:

minimize 1/p = (A/(h - h*cot(θ) + 2*h/sin(θ)))^(-1)

操作步骤如下:
1. 创建目标函数的等高线和曲面图。
2. 使用 fminsearch 函数,以初始点 (h, θ) = (1, 1) 进行求解,得到 h = 2.3172 θ = 60°

6.3 两弹簧系统平衡问题

两弹簧系统在受力后达到平衡,势能函数为:

PE = 0.5*k1*x1^2 + 0.5*k2*(x2 - x1)^2 - F*x2

操作步骤如下:
1. 创建势能函数的等高线和曲面图。
2. 使用 fminsearch 函数,以初始点 (x1, x2) = (1, 1) 进行求解,得到 x1 = 4.1289 x2 = 0 PE = -15.2802

6.4 加工操作优化问题

加工操作中,平均总生产时间 T = tm + tm*tc/Tl + taux ,其中 tm 为切削时间, Tl 为刀具寿命, tc 为换刀时间, taux 为辅助时间。切削时间 tm = π*D*L/(1000*V*f) ,刀具寿命受切削速度 V 、进给率 f 和切削深度 d 影响。
操作步骤如下:
1. 创建系统的等高线和曲面图。
2. 使用 fmincon 函数,以初始点 (V, f) = (10, 1) 进行求解,得到 T = 3.942 V = 100.46 f = 2.000

6.5 弹簧 - 质量系统平衡问题

对于弹簧 - 质量系统,通过最小化势能函数 PE = 0.5*X'*K*X - X'*P 来求解平衡位置,其中 K 为刚度矩阵, P 为外力向量。
操作步骤如下:
使用 fminunc 函数,以初始点 (x1, x2) = (1, 1) 进行求解,得到 x1 = 4.7059 x2 = 10.5882 PE = 529.41

6.6 弹簧 - 重量系统平衡问题

弹簧 - 重量系统中,通过最小化势能函数来求解平衡位置。势能函数为:

PE = 0.5*∑(i = 1 to 6) Ki*(ΔLi)^2 + ∑(j = 1 to 5) Wj*Yj+1

操作步骤如下:
使用 fminunc 函数,以初始点 (X2, X3, X4, X5, X6, Y2, Y3, Y4, Y5, Y6) = (7.5, 15, 22.5, 30, 37.5, 0, 0, 0, 0, 0) 进行求解。

6.7 管状柱屈曲问题

管状柱的屈曲载荷 F = π*a*E*R^b*t^(4 - b)/(4*L^2) ,通过曲线拟合实验数据来确定未知常数 a b
操作步骤如下:
使用 lsqcurvefit 函数,以初始点 (a, b) = (1, 1) 进行求解,得到 a = -3.3182 b = 3.1588

6.8 药物成分含量问题

药物中某成分的含量随时间变化,假设非线性模型为 Y = a + (0.51 - a)*exp(-b*(t - 8))
操作步骤如下:
使用 lsqcurvefit 函数,以初始点 (a, b) = (1, 1) 进行求解,得到 a = 0.3918 b = 0.1394

6.9 车辆运动问题

车辆的加速度 a(t) = C*t^2 + D*t + 2*a0 ,位置 x(t) = A*t^4 + B*t^3 + a0*t^2
操作步骤如下:
使用 lsqnonlin 函数,以初始点 (A, B) = (0, 0) 进行求解,得到车辆速度关于时间的方程 v(t) = -0.032693*t^3 + 0.2515*t^2 + 1.22*t ,误差为 5.6533

6.10 圆孔定位问题

对于圆孔,通过 rn = sqrt((xc - xn)^2 + (yc - yn)^2) 来确定圆心位置 (xc, yc) 和半径 r
操作步骤如下:
使用模拟数据,通过MATLAB表达式 r = ro + 0.02*randn(N, 1) 生成数据,其中 ro = 0.075 N = 40 xc = 1.25 yc = 1.5 ,求解得到圆心和半径。

6.11 最小球体问题

找到包含四个给定点的最小球体的圆心和半径。球体半径公式为 R^2 = (xc - x)^2 + (yc - y)^2 + (zc - z)^2
操作步骤如下:
使用 fmincon 函数,以初始点 (xc, yc, zc, R) = (4, 4, 4, 4) 进行求解,得到 (xc, yc, zc, R) = (-0.5, -0.5, 2.5, 4.5552)

6.12 三杆桁架问题

三杆桁架的目标函数为其加载节点的垂直挠度:

minimize f = P*h/(E*(1/(x1 + 12*x2)))

约束条件包括应力约束和设计变量的上下界。
操作步骤如下:
使用 fmincon 函数,以初始点 (x1, x2) = (0, 0) 进行求解,得到 x1 = 8.3177 x2 = 26.924 f = 0.021554

6.13 电阻桥网络问题

电阻桥网络的总功率 P = ∑(n = 1 to 5) In^2*Rn ,约束条件为电流范围 1 ≤ In ≤ 2
操作步骤如下:
使用 fmincon 函数,以初始点 (R1, R2, R3, R4, R5) = (1, 1, 1, 1, 1) 进行求解,得到 [R1, R2, R3, R4, R5] = [3, 1, 1, 2, 0.5] 欧姆,总功率耗散为 12 W

6.14 生产运输优化问题

公司有 m 个生产设施和 n 个仓库,目标是最小化运输成本:

minimize ∑(i = 1 to m) ∑(j = 1 to n) (cij*xij + dij*xij^2)

约束条件包括生产能力和仓库需求。
操作步骤如下:
使用 quadprog 函数,以给定的初始点进行求解,得到最优的生产和运输数量。

6.15 两杆桁架多目标问题

两杆桁架的多目标问题,目标函数为重量和应力相关的函数,约束条件包括应力范围和设计变量的上下界。
操作步骤如下:
使用 fseminf 函数,以初始点 (x1, x2) = (0.1, 0.1) 进行求解,得到 x1 = 0.8088 x2 = 0.45058 w = 12.6431

7. 总结

通过上述各种优化问题的案例,我们可以看到不同的优化方法和MATLAB函数在解决实际问题中的应用。以下是对不同函数适用场景的总结表格:
| 问题类型 | 适用函数 |
| — | — |
| 单目标无约束优化 | fminsearch , fminunc |
| 单目标约束优化 | fmincon , ga |
| 多目标优化 | fgoalattain , gamultiobj |
| 线性规划 | linprog |
| 二次规划 | quadprog |
| 曲线拟合 | lsqcurvefit , lsqnonlin |

在实际应用中,需要根据问题的特点,如目标函数的性质(线性、非线性、单目标、多目标等)、约束条件的类型(等式约束、不等式约束等)以及变量的类型(连续、离散、二进制等),选择合适的优化方法和函数。同时,由于遗传算法等方法具有随机性,多次运行并选择最优结果是一个不错的策略。

graph LR;
    A[问题定义] --> B{问题类型};
    B -- 单目标无约束 --> C[fminsearch/fminunc];
    B -- 单目标约束 --> D[fmincon/ga];
    B -- 多目标 --> E[fgoalattain/gamultiobj];
    B -- 线性规划 --> F[linprog];
    B -- 二次规划 --> G[quadprog];
    B -- 曲线拟合 --> H[lsqcurvefit/lsqnonlin];

这个流程图展示了根据问题类型选择合适MATLAB优化函数的过程。希望这些内容能帮助大家在遇到优化问题时,能够更加从容地选择和应用合适的方法。

【四轴飞行器】非线性三自由度四轴飞行器模拟器研究(Matlab代码实现)内容概要:本文围绕非线性三自由度四轴飞行器模拟器的研究展开,重点介绍了基于Matlab的建模与仿真方法。通过对四轴飞行器的动力学特性进行分析,构建了非线性状态空间模型,并实现了姿态与位置的动态模拟。研究涵盖了飞行器运动方程的建立、控制系统设计及数值仿真验证等环节,突出非线性系统的精确建模与仿真优势,有助于深入理解飞行器在复杂工况下的行为特征。此外,文中还提到了多种配套技术如PID控制、状态估计与路径规划等,展示了Matlab在航空航天仿真中的综合应用能力。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的高校学生、科研人员及从事无人机系统开发的工程技术人员,尤其适合研究生及以上层次的研究者。; 使用场景及目标:①用于四轴飞行器控制系统的设计与验证,支持算法快速原型开发;②作为教学工具帮助理解非线性动力学系统建模与仿真过程;③支撑科研项目中对飞行器姿态控制、轨迹跟踪等问题的深入研究; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注动力学建模与控制模块的实现细节,同时可延伸学习文档中提及的PID控制、状态估计等相关技术内容,以全面提升系统仿真与分析能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值