一.模型优化
1.线性规划
目标函数和约束条件都是线性的最优化方法称为线性最优化,也称为线性规划问题。Matlab 中线性规划的标准形式为
\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad m i n x x = f T x \mathop{minx}\limits_{x} = f^{T}x xminx=fTx
s . t = { A ⋅ x ≤ b , A e q ⋅ x = b e q , l b ≤ x ≤ u b . s.t = \left\{\begin{array}{l} A \cdot x \leq b, \\Aeq \cdot x = beq, \\lb \leq x \leq ub. \end{array}\right. s.t=⎩⎨⎧A⋅x≤b,Aeq⋅x=beq,lb≤x≤ub.
通常称 x x x 为决策变量, f f f 为价值系数。
Matlab 中求解线性规划的命令为
[ x , f v a l ] = l i n p r o g ( f , A , b , A e q , b e q , l b , u b ) [x,fval] = linprog(f, A, b, Aeq, beq, lb, ub) [x,fval]=linprog(f,A,b,Aeq,beq,lb,ub)
其中 A A A 和 b b b 对应线性不等式约束, A e q Aeq Aeq 和 b e q beq beq 对应线性等式约束, l b lb lb 和 u b ub ub 分别为决策向量的下界向量和上界向量。
下面以一个例题来说明如何求解线性规划问题。
假设目标函数为
\qquad\qquad\qquad\qquad\qquad\qquad m i n z = 13 x 1 + 9 x 2 + 10 x 3 + 11 x 4 + 12 x 5 + 8 x 6 minz = 13x_{1} + 9x_{2} + 10x_{3} + 11x_{4} +12x_{5} + 8x_{6} minz=13x1+9x2+10x3+11x4+12x5+8x6
约束条件为
s . t = { x 1 + x 4 = 400 , x 2 + x 5 = 600 , x 3 + x 6 = 500 , 0.4 x 1 + 1.1 x 2 + x 3 ≤ 800 , 0.5 x 4 + 1.2 x 5 + 1.3 x 6 ≤ 900 , x i ≥ 0 , i = 1 , 2 , . . . , 6. s.t = \left\{\begin{array}{l} x_{1} + x{4} = 400, \\x_{2} + x_{5} = 600, \\x_{3} + x_{6} = 500, \\0.4x_{1} + 1.1x_{2} + x_{3} \leq 800, \\0.5x_{4} + 1.2x_{5} + 1.3x_{6} \leq 900, \\x_{i} \geq 0, i = 1, 2,...,6. \end{array}\right. s.t=⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧x1+x4=400,x2+x5=600,x3+x6=500,0.4x1+1.1x2+x3≤800,0.5x4+1.2x5+1.3x6≤900,xi≥0,i=1,2,...,6.
首先,注意到目标函数有6个系数,我们改写为
\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad m i n z = ( 13 9 10 11 12 8 ) X minz = (13\quad9\quad10\quad11\quad12\quad8)X minz=(1391011128)X
接着处理不等式约束的两个式子 0.4 x 1 + 1.1 x 2 + x 3 ≤ 800 0.4x_{1} + 1.1x_{2} + x_{3} \leq 800 0.4x1+1.1x2+x3≤800 和 0.5 x 4 + 1.2 x 5 + 1.3 x 6 ≤ 900 0.5x_{4} + 1.2x_{5} + 1.3x_{6} \leq 900 0.5x4+1.2x5+1.3x6≤900,这里有 2 条式子以及 6 个决策变量,于是我们要构造一个 2 行 6 列的矩阵
( 0.4 1.1 1 0 0 0 0 0 0 0.5 1.2 1.3 ) X ≤ ( 800 900 ) \begin{pmatrix} 0.4 & 1.1 & 1 & 0 & 0 & 0\\ 0 & 0 & 0 & 0.5 & 1.2 & 1.3\\ \end{pmatrix}X \leq \begin{pmatrix}800\\900\end{pmatrix} (0.401.101000.501.201.3)X≤(800900)
最后来处理等式约束的三个式子 x 1 + x 4 = 400 x_{1} + x{4} = 400 x1+x4=400 和 x 2 + x 5 = 600 x_{2} + x_{5} = 600 x2+x5=600 以及 x 3 + x 6 = 500 x_{3} + x_{6} = 500 x3+x6=500,由于这里有 3 条式子以及 6 个决策变量,于是我们要构造一个 3 行 6 列的矩阵
( 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 ) X = ( 400 600 500 ) \begin{pmatrix} 1 & 0 & 0 & 1 & 0 & 0\\ 0 & 1 & 0 & 0 & 1 & 0\\ 0 & 0 & 1 & 0 & 0 & 1\\ \end{pmatrix}X = \begin{pmatrix}400\\600\\500\end{pmatrix} ⎝⎛100010001100010001⎠⎞X=⎝⎛400600500⎠⎞
Matlab 求解的代码如下
f = [13 9 10 11 12 8];
A = [0.4 1.1 1 0 0 0; 0 0 0 0.5 1.2 1.3];
b = [800; 900];
Aeq = [1 0 0 1 0 0; 0 1 0 0 1 0; 0 0 1 0 0 1];
beq = [400; 600; 500];
lb = zeros(6, 1);
ub = [];
[x,fval] = linprog(f, A, b, Aeq, beq, lb, ub)
下面再来看一个例子:
clc,clear,close all
%% 选择优化求解器,线性规划求解可由linprog实现
%% 将所有变量合并为一个向量,共16个变量
variables = {
'I1','I2','HE1','HE2','LE1','LE2','C','BF1','BF2','HPS','MPS','LPS','P1','P2','PP','EP'}
N = length(variables)
for v = 1:N
eval([variables{
v}, '=', num2str(v), ';']) %将I1到EP映射为1到16
end
%% 设置上下限约束(lb<=x<=ub)
% 设置下限约束,即lb<=x
lb = zeros(size(variables)); % 1x16的矩阵,每个数都是0
lb([P1, P2, MPS, LPS]) = [2500, 3000, 271536, 100623];
% 设置上限约束,即x<=ub
ub = Inf(size(variables)); % 1想6的矩阵,每个数都是无穷大
ub([P1, P2, I1, I2, C, LE2]) = [6250, 9000, 192000, 244000, 62000, 142000];
%% 创建线性不等式约束(A*x<=b)
A = zeros(3,16); % 3x16的矩阵,每个数均为0,为什么是3x16,因为约束条件有3个不等式
% 由不等式I1-HE1<=132000得到下面一行代码
A(1, I1) = 1;
A(1, HE1) = -1;
b(1) = 132000;
% 由不等式-EP-PP<=12000得到下面一行代码
A(2, EP) = -1;
A(2, PP) = -1;
b(2) = -12000;
% 由不等式-P1-P2-PP<=-24550得到下面一行代码
A(3, [P1, P2, PP]) = [-1, -1, -1];
b(3) = -24550;
%% 创建线性等式约束(Aeq*x=beq)
Aeq = zeros(8,16);
beq = zeros(8,1) % 约束条件中共有8个等式
% 把等式I2=LE2+HE2转化为LE2+HE2-I2=0后,得到下面一行代码
Aeq(1, [LE2, HE2, I2]) = [1, 1, -1];
Aeq(2, [LE1, LE2, BF2, LPS]) = [1, 1, 1, -1];
Aeq(3, [I1, I2, BF1, HPS]) = [1, 1, 1, -1];
Aeq(4, [C, MPS, LPS, HPS]) = [1, 1, 1, -1];
Aeq(5, [LE1, HE1, C, I1]) = [1, 1, 1, -1];
Aeq(6, [HE1, HE2, BF1, BF2, MPS]) = [1, 1, 1, -1, -1];
Aeq(7, [HE1, LE1, C, P1, I1]) = [1267.8, 1251.4, 192, 3413, -1359.8];
Aeq(8, [HE2, LE2, P2, I2]) = [1267.8, 1251.4, 3413, -1359.8];
%% 创建目标函数
f = zeros(size(variables));
% 由目标函数0.002614HPS + 0.0239PP + 0.009825EP
f([HPS, PP, EP]) = [0.002614, 0.0239, 0.009825];
%% 由linprog实现线性规划问题求解
options = optimoptions('linprog', 'Algorithm', 'dual-simplex');
% 将前面已经确定的各个参数传入linprog()中
[x, fval] = linprog(f, A, b, Aeq, beq, lb, ub, options);
for d = 1:N
fprintf('%12.2f\t%s\n', x(d), variables{
d})
end
2.整数规划
数学规划中的变量(部分或全部)限制为整数时,称为整数规划。
2.1 0 − 1 0 - 1 0−1型整数规划
0 − 1 0 - 1 0−1 型整数规划中某个变量 x j x_{j} xj 只能取值 0 或 1。
求解 0 − 1 0 - 1 0−1 型整数规划可以使用 Matlab 的 i n t l i n p r o g intlinprog intlinprog 函数, i n t l i n p r o g intlinprog intlinprog函数参数如下
i n t l i n p r o g ( f , i n t c o n , A , b , A e q , b e q , l b , u b ) intlinprog(f, intcon, A, b, Aeq, beq, lb, ub) intlinprog(f,intcon,A,b,Aeq,beq,lb,ub)
其中 f f f 为目标函数各变量的系数, i n t c o n intcon intcon 为只能取 0 − 1 0 - 1 0−1 的变量的下标数值, A A A 和 b b b 对应线性不等式约束, A e q Aeq Aeq 和 b e q beq beq 对应线性等式约束, l b lb lb 和 u b ub ub 分别为决策向量的下界向量和上界向量。
下面用一个例子来说明如何求解 0 − 1 0 - 1 0−1 整数规划问题。
假设目标函数为
\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad m a x z = 3 x 1 − 2 x 2 + 5 x 3 maxz = 3x_{1} - 2x_{2} + 5x_{3} maxz=3x1−2x2+5x3
约束条件为
s . t = { x 1 + 2 x 2 − x 3 ≤ 2 , x 1 + 4 x 2 + x 3 ≤ 4 , x 1 + x 2 ≤ 3 , 4 x 2 + x 3 ≤ 6 , 0.5 x 4 + 1.2 x 5 + 1.3 x 6 ≤ 900 , x 1 , x 2 , x 3 = 0 或 1. s.t = \left\{\begin{array}{l} x_{1} + 2x_{2} - x_{3} \leq 2, \\x_{1} + 4x_{2} + x_{3} \leq 4, \\x_{1} + x_{2} \leq 3, \\4x_{2} + x_{3} \leq 6, \\0.5x_{4} + 1.2x_{5} + 1.3x_{6} \leq 900, \\x_{1},x_{2},x_{3} = 0 或 1. \end{array}\right. s.t=⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧x1+2x2−x3≤2,x1+4x2+x3≤4,x1+x2≤3,4x2+x3≤6,0.5x4+1.2x5+1.3x6≤900,x1,x2,x3=0或1.
求解的 Matlab 代码如下
因为这里 x 1 , x 2 , x 3 x_{1},x_{2},x_{3} x1,x2,x3 都只能取 0 或 1,因此 i n t c o n intcon intcon 为 [ 1 , 2 , 3 ] [1,2,3] [1,2,3]。
f = [-3; 2; -5];
intcon = [1, 2, 3];
A = [1 2 -1; 1 4 1; 1 1 0; 0 4 1]; % 四个不等式中的变量系数
b = [2; 4; 3; 6]; % 约束条件中不等式右边的常数
lb = [0, 0, 0]; % x1,x2,x3=0
ub = [1, 1, 1]; % x1,x2,x3=1
Aeq = [0, 0, 0];
beq = 0;
x = intlinprog(f, intcon, A, b, Aeq, beq, lb, ub)
3.多目标规划
二.插值与拟合
插值:已知若干点 ( x i , y i ) (x_{i},y_{i}) (xi,yi),构造一个过所有已知点的函数 y = f ( x ) y = f(x) y=f(x)。
拟合:已知一些点,寻找一个函数曲线,使其与所有已知的数据点最为接近。
通常在已知数据较少时使用插值,数据较多时使用拟合。
首先是插值算法
1.拉格朗日插值
Matlab 代码:
function y1 = Lagrange(x, y, x1);
% x 插值节点
% y 被插值函数在节点x处的函数值
% x1 待插值节点
% y1 待插值节点的插值结果
n = length(x); % 数据点个数
m = length(x1); % 待插值点数
for k = 1:m
z = x1(k);
sum = 0.0;
for i = 1:n
prod = 1.0;
for j = 1:n
if j ~= i
prod = prod * (z - x(j)) / (x(i) - x(j));
end
end
sum = sum + prod * y(i);
end
y1(k) = sum;
end
测试样例:
clear all
clc
% 人口数据
T = 1:30; % +1970=年份
P = [33815 33981 34004 34165 34212 34327 34344 34458 34498 34476 34483 34488 34513 34497 34511 34520 34507 34509 34521 34513 34515 34517 34519 34519 34521 34521 34523 34525 34525 34527];%人口
plot(T, P, 'r o')% 只画数据点
hold on
x1 = 1.5 : 30.5;
y1 = Lagrange(T, P, x1);
plot(x1, y1, 'b +')
axis([0 30 33600 34800])
title('拉格朗日插值&人口预测模型')
2.牛顿插值
Matlab 代码:
%newton.m
%求牛顿插值多项式、差商、插值及其误差估计的MATLAB主程序
%输入的量:X是n+1个节点(x_i,y_i)(i = 1,2, ... , n+1)横坐标向量,Y是纵坐标向量,
%x是以向量形式输入的m个插值点,M在[a,b]上满足|f~(n+1)(x)|≤M
%注:f~(n+1)(x)表示f(x)的n+1阶导数
%输出的量:向量y是向量x处的插值,误差限R,n次牛顿插值多项式L及其系数向量C,
%差商的矩阵A
function[y, R, A, C, L] = newton(X, Y, x, M)
n = length(X);
m = length(x);
for t = 1 : m
z = x(t);
A = zeros(n, n);
A(:,1) = Y';
s = 0.0; p = 1.0; q1 = 1.0; c1 = 1.0;
for j = 2 : n
for i = j : n
A(i,j) = (A(i,j-1) - A(i-1,j-1))/(X(i) - X(i-j+1));
end
q1 = abs(q1 * (z - X(j-1))); % 余项计算中的差值连乘项
c1 = c1 * j; % 余项计算中的分母,阶乘
end
C = A(n, n); q1 = abs(q1 * (z-X(n)));
for k = (n - 1) : -1 : 1
C = conv(C, poly(X(k)));
% poly函数把根转换为求得此根的多项式,X(k)是一个数,所以转换为一次多项式,得到其系数向量
% conv函数的输入是多项式的系数向量时,相当于直接相乘
d = length(C);
C(d) = C(d) + A(k, k);%在最后一维,也就是常数项加上新的差商
end
y(t) = polyval(C, z); % 插值结果
R(t) = M * q1 / c1; % 用M代替f~(n+1)(x),即f(x)的n+1阶导数,这样求得的余项比真实值略大
end
L = vpa(poly2sym(C), 3);% vpa让输出结果系数为小数而非分数,3表示用3位小数
测试样例1:
clear all
clc
X = [0 pi/6 pi/4 pi/3 pi/2];
Y = [0 0.5 0.7071 0.8660 1];
x = linspace(0,pi,50);
M = 1;
[y, R, A, C, L] = newton(X, Y, x, M);
y1 = sin(x);
errorbar(x, y, R, '.g')
hold on
plot(X, Y, 'or', x, y, '.k', x, y1, '-b');
legend('误差', '样本点', '牛顿插值估算', 'sin(x)');
测试样例2:
X = [0.4 0.55 0.65 0.80 0.90 1.05];
Y = [0.41075 0.57815 0.69675 0.88811 1.02652 1.25386];
x = 0.4 : 0.01 : 1.05;
M = 1;
[y, R, A, C, L] = newton(X, Y, x, M);
errorbar(x, y, R, '.g')
hold on
plot(X, Y, 'or', x, y, '.k');
legend('误差', '样本点', '牛顿插值估算');
接着是拟合算法
1.最小二乘法线性拟合
Matlab 代码:
clear;clc
load data1
plot(x, y, 'o')
% 给x和y轴加上标签
xlabel('x的值')
ylabel('y的值')
n = size(x,1);
k = (n * sum(x.*y) - sum(x) * sum(y)) / (n * sum(x.*x) - sum(x) * sum(x))
b = (sum(x.*x) * sum(y) - sum(x) * sum(x.*y)) / (n * sum(x.*x) - sum(x) * sum(x))
hold on % 继续在之前的图形上来画图形
grid on % 显示网格线
% % 画出y=kx+b的函数图像 plot(x,y)
% % 传统的画法:模拟生成x和y的序列,比如要画出[0,5]上的图形
% x = 0: 0.1 :5 % 间隔设置的越小画出来的图形越准确
% y = k * x + b % k和b都是已知值
% plot(x,y,'-')
f = @(x) k * x + b;
fplot(f, [min(x) - 1, max(x) + 1]);
legend('样本数据', '拟合函数', 'location', 'SouthEast')
% 匿名函数的基本用法。
% handle = @(arglist) anonymous_function
% 其中handle为调用匿名函数时使用的名字。
% arglist为匿名函数的输入参数,可以是一个,也可以是多个,用逗号分隔。
% anonymous_function为匿名函数的表达式。
% 举个小例子
% % >> z=@(x,y) x^2+y^2;
% % >> z(1,2)
% % ans = 5
% fplot函数可用于画出匿名函数的图形。
% fplot(f,xinterval) 将在指定区间绘图。将区间指定为 [xmin xmax] 形式的二元素向量。
y_hat = k * x + b; % y的拟合值
SSR = sum((y_hat - mean(y)).^2) % 回归平方和
SSE = sum((y_hat - y).^2) % 误差平方和
SST = sum((y - mean(y)).^2) % 总体平方和
SST - SSE - SSR % 非常小的数,接近0
R_2 = SSR / SST % 拟合优度
三.算法
多元线性回归:求一个变量与两个及以上其他变量的线性关系的方法
Python求解代码如下
import numpy as np
from sklearn import linear_model
"""
scikit-learn
"""
Y = np.array([89, 91, 93, 95, 97])
X = np.array([[87, 72, 83, 90],
[89, 76, 88, 93],
[89, 74, 82, 91],
[92, 71, 91, 89],
[93, 76, 89, 94]])
m = np.alen(X)
ones = np.ones(m)
X = np.column_stack((ones, X))
model = linear_model.LinearRegression()
model.fit(X, Y)
x_predict = np.array([[1, 88, 73, 87, 92]])
result = model.predict(x_predict)
print(model.intercept_)
print(model.coef_)
print("Predit result: ", result)
这里求得的 y y y 与 x x x 的关系式为 y = x ⋅ θ y = x \cdot \theta y=x⋅θ,其中
x = [ 1 87 72 83 90 1 89 76 88 93 1 89 74 82 91 1 92 71 91 89 1 93 76 89 94 ] x = \begin{bmatrix} 1 & 87 & 72 & 83 & 90\\ 1 & 89 & 76 & 88 & 93\\ 1 & 89 & 74 & 82 & 91\\ 1 & 92 & 71 & 91 & 89\\ 1 & 93 & 76 & 89 & 94 \end{bmatrix} x=⎣⎢⎢⎢⎢⎡111118789899293727674717683888291899093918994⎦⎥⎥⎥⎥⎤, θ = [ θ 0 θ 1 θ 2 θ 3 θ 4 ] = [ − 19.5 1.6875 0.375 − 0.3125 − 0.4375 ] \theta = \begin{bmatrix}\theta_{0}\\\theta_{1}\\\theta_{2}\\\theta_{3}\\\theta_{4}\end{bmatrix} = \begin{bmatrix}-19.5\\1.6875\\0.375\\-0.3125\\-0.4375\end{bmatrix} θ=⎣⎢⎢⎢⎢⎡θ0θ1θ2θ3θ4⎦⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎡−19.51.68750.375−0.3125−0.4375⎦⎥⎥⎥⎥⎤.
该程序输出的 i n t e r c e p t intercept intercept 代表 θ 0 \theta_{0} θ0, c o e f coef coef_代表 θ 1 到 θ 4 \theta_{1} 到 \theta_{4} θ1到θ4。
四.Matlab常用函数总结
Matlab导入Excel数据:
P = xlsread('3.xlsx', 'A2:A402');
%把3.xlsx中A2到A402的数据导入并赋给变量P
Matlab二次拟合:
y = polyfit(自变量, 因变量, 2);
z = polyval(y, 自变量);
plot(自变量, 因变量, '.', 自变量, z, 'b');
未完待续
参考博客 https://blog.csdn.net/qq_41149269/article/details/84202777
https://blog.csdn.net/sinat_31790817/article/details/79884618
https://blog.csdn.net/qq_36607894/article/details/100012334