python数学建模基础教程,如何用python数学建模

这篇文章主要介绍了python数学建模基础教程,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。

🚧 线性规划

声明:

  • 采用如下求解方法:

    • python cxpy
    • matlab
    • lingo
  • 5.1 求解下列线性规划的解:
    m a x   z = 8 x 1 − 2 x 2 + 3 x 3 − 4 x 4 − 2 x 5 { x 1 + x 2 + x 3 + x 4 + x 5 ≤ 400 , x 1 + 2 x 2 + 2 x 3 + x 4 + 6 x 5 ≤ 800 , 2 x 1 + x 2 + 6 x 3 ≤ 200 , x 3 + x 4 + 5 x 5 ≤ 200 , 0 ≤ x i ≤ 99 ,   i = 1 , 2 , 3 , 4 x 5 ≥ 10 max~z=8x_1-2x_2+3x_3-4x_4-2x_5\\ \left\{ \begin{aligned} x_1+x_2+x_3+x_4+x_5\le&400,\\ x_1+2x_2+2x_3+x_4+6x_5&\le800,\\ 2x_1+x_2+6x_3\le200,\\ x_3+x_4+5x_5\le 200,\\ 0\le x_i \le99,~i=1,2,3,4\\ x_5\ge10 \end{aligned} \right. max z=8x1​−2x2​+3x3​−4x4​−2x5​⎩ ⎨ ⎧​x1​+x2​+x3​+x4​+x5​≤x1​+2x2​+2x3​+x4​+6x5​2x1​+x2​+6x3​≤200,x3​+x4​+5x5​≤200,0≤xi​≤99, i=1,2,3,4x5​≥10​400,≤800,

    • matlab
    c=-[8,-2,3,-1,-2];%价值向量
     A=[ones(1,5);1,2,2,1,6;2,1,6,0,0;0,0,1,1,5];
     b=[400,800,200,200]';
     [x,fval]=linprog(c,A,b,[],[],[zeros(1,4),-10]',[ones(1,4)*99,inf]');
     disp('最优解为:');disp(x)
     disp('最大值为:');disp(-fval)
     %结果
     Optimal solution found.
    
    最优解为:
       99.0000
             0
        0.3333
             0
      -10.0000
    
    最大值为:
       813
    
    
    • python
    #导入凸优化库
    import  cvxpy as cv
    import numpy as np
    #构造系数矩阵
    A=np.array([[1]*5,[1,2,2,1,6],[2,1,6,0,0],[0,0,1,1,5]])
    b=np.array([400,800,200,200])
    c=np.array([8,-2,3,-1,-2])
    x=cv.Variable(5)#5个决策变量 x等同与列向量
    obj=cv.Maximize(c@x)#构造目标函数
    con=[A@x<=b,x[0:-1]<=99*np.ones(4),x[4]>=-10,x[0:4]>=0]
    prob=cv.Problem(obj,con)
    prob.solve(solver='GLPK_MI')
    print('可行解=\n')
    for i in x.value:
        print(i,'\n')
    print('最大值:',prob.value)
    #结果:
    可行解=
    
    99.0  
    -0.0  
    0.3333333333333333  
    -0.0  
    -10.0  
    最大值: 813.0
    
    • lingo

    结果: 813

    sets:
    factory/1..5/:x,c;
    plant/1..4/:k;
    endsets
    data:
    c=8,-2,3,-1,-2;
    enddata
    
    max=@sum(factory(i):x(i)*c(i));
    @sum(factory(i):x(i))<400;
    x(1)+2*x(2)+2*x(3)+x(4)+6*x(5)<800;
    2*x(1)+x(2)+6*x(3)<200;
    x(3)+x(4)+5*x(5)<200;
    @for(plant(i):@bnd(0,x(i),99));
    @free(x(5));
    x(5)>-10;
    
                                       X( 1)        99.00000            
                                       X( 2)        0.000000            
                                       X( 3)       0.3333333            
                                       X( 4)        0.000000            
                                       X( 5)       -10.00000            
    
  • 5.2 求5.4节模型三的解

    模型三:
    m i n   s { m a x 1 ≤ i ≤ n { q i x i } } − ( 1 − s ) ∑ i = 0 n ( r i − p i ) x i { ∑ i = 0 n ( 1 + p i ) x i = M , x i ≥ 0 , i = 0 , 1 , 2 , … min~s\big\{\mathop{max}\limits_{1\le i\le n}\{q_ix_i\}\big\}-(1-s)\sum_{i=0}^{n}(r_i-p_i)x_i\\ \left\{ \begin{aligned} &\sum_{i=0}^{n}(1+p_i)x_i=M,\\ &x_i\ge0,i=0,1,2,\dots \end{aligned} \right. min s{1≤i≤nmax​{qi​xi​}}−(1−s)i=0∑n​(ri​−pi​)xi​⎩ ⎨ ⎧​​i=0∑n​(1+pi​)xi​=M,xi​≥0,i=0,1,2,…​
    令 { m a x 1 ≤ i ≤ n { q i x i } } = x 5 \big\{\mathop{max}\limits_{1\le i\le n}\{q_ix_i\}\big\}=x_5 {1≤i≤nmax​{qi​xi​}}=x5​ :
    m i n f = s x 5 − ( 1 − s ) [ 0.05 , 0.27 , 0.19 , 0.185 , 0.185 ] [ x 0 , x 1 , x 2 , x 3 , x 4 ] T { 0.025 x 1 − x 5 ≤ 0 0.015 x 2 − x 5 ≤ 0 0.055 x 3 − x 5 ≤ 0 0.026 x 4 − x 5 ≤ 0 x 0 + 1.01 x 2 + 1.02 x 2 + 1.045 x 3 + 1.065 x 4 = 1 min \quad f= sx_5-(1-s)[0.05,0.27,0.19,0.185,0.185][x_0,x_1,x_2,x_3,x_4]^T\\ \left\{\begin{aligned} &0.025x_1-x_5\le0\\ &0.015x_2-x_5\le0\\ &0.055x_3-x_5\le0\\ &0.026x_4-x_5\le0\\ &x_0+1.01x_2+1.02x_2+1.045x_3+1.065x_4=1 \end{aligned} \right. minf=sx5​−(1−s)[0.05,0.27,0.19,0.185,0.185][x0​,x1​,x2​,x3​,x4​]T⎩ ⎨ ⎧​​0.025x1​−x5​≤00.015x2​−x5​≤00.055x3​−x5​≤00.026x4​−x5​≤0x0​+1.01x2​+1.02x2​+1.045x3​+1.065x4​=1​

    • python
    #利用cxpy
    import cvxpy as cp
    import numpy as np
    import matplotlib.pyplot as plt
    
    s = 0.01
    point = []
    S=[]
    v = np.array([0.05, 0.27, 0.19, 0.185, 0.185]).reshape(1, 5)
    X = cp.Variable((6, 1))  # 决策变量 列向量
    q = np.array([0.025, 0.015, 0.055, 0.026])
    Aeq = np.array([1, 1.01, 1.02, 1.045, 1.065, 0]).reshape(1, 6)
    # 约束条件
    con = [Aeq@X == 1, cp.multiply(q, X[1:5, 0]) - X[5, 0] <= 0,X>=np.zeros((6,1))]
    while s < 1:
       f = cp.Minimize(s * X[5, 0] - (1 - s) * (v @ X[0:5,0]))  # 构造目标函数
       prob=cp.Problem(f,con)
       prob.solve(solver='GLPK_MI')
       point.append(-prob.value)
       S.append(s)
       s+=0.02
    plt.plot(S,point,'ro')
    plt.show()
    
    

    在这里插入图片描述

    • matlab
    s=0.01;
    V=[0.025,0.015,0.005,0.026];
    %构造系数矩阵
    A=diag(V,1);A(end,:)=[];
    A(:,6)=-ones(4,1);
    Aeq=[1,1.01,1.02,1.045,1.065,0];
    beq=1;
    while s<1
        %构造价值向量
        c=(s-1).*[0.05,0.27,0.19,0.185,0.185,0];
        c(6)=s;
        %求解最优解
        [x,fval]=linprog(c,A,zeros(4,1),Aeq,beq,zeros(6,1),inf.*ones(6,1));
        s=s+0.025;
        hold on
        plot(s,-fval,'ko')
        hold off
    end       
    

    在这里插入图片描述

    • lingo 在此处无法实现可视化操作,所以建议使用上述的两种语言
  • 5.3 某股民决定对6家公司的股票进行投资,根据对着6家公司的了解,估计这6家公司股票的明年预期收益和这6种股票的收益的协方差矩阵的数据见表5.6.要获得至少25%的预期收益,最小风险是多少

    1. 目标函数:风险 R a n k ( p ) = w ′ V w , w 为投资组合的权重, V 为协方差矩阵 Rank(p)=w^{'}Vw,w为投资组合的权重,V为协方差矩阵 Rank(p)=w′Vw,w为投资组合的权重,V为协方差矩阵
    2. 决策变量:权重向量的元素(6个)
    3. 约束条件:权重之和=1;收益 ≤ 25 % \le 25\% ≤25%
    4. 二次规划问题

    m i n   R a n k = [ x 1 , x 2 , x 3 , x 4 , x 5 , x 6 ] T ⋅ V ⋅ [ x 1 , x 2 , x 3 , x 4 , x 5 , x 6 ] { ∑ i = 1 6 x i = 1 ,    i = 1 , 2 , … 6 0.02 x 1 + 0.42 x 2 + x 3 + 0.5 x 4 + 0.46 x 5 + 0.3 x 6 ≥ 0.25 x i ≥ 0 ,    i = 1 , 2 , … 6 min~Rank=[x_1,x_2,x_3,x_4,x_5,x_6]^T\cdot V\cdot[x_1,x_2,x_3,x_4,x_5,x_6]\\ \left\{\begin{aligned} & \sum_{i=1}^{6}x_i=1,~~i=1,2,\dots6\\ &0.02x_1+0.42x_2+x_3+0.5x_4+0.46x_5+0.3x_6\ge 0.25\\ &x_i\ge0,~~i=1,2,\dots6 \end{aligned} \right. min Rank=[x1​,x2​,x3​,x4​,x5​,x6​]T⋅V⋅[x1​,x2​,x3​,x4​,x5​,x6​]⎩ ⎨ ⎧​​i=1∑6​xi​=1,  i=1,2,…60.02x1​+0.42x2​+x3​+0.5x4​+0.46x5​+0.3x6​≥0.25xi​≥0,  i=1,2,…6​

    • python
    #导入凸优化库
    import  cvxpy as cv
    import numpy as np
    from scipy.optimize import linprog
    import pandas as pd
    d=pd.read_excel('协方差矩阵.xlsx')
    data=np.vstack((np.array(d.columns),d.values))
    #六个决策变量
    x=cv.Variable((6,1))
    #构造目标函数
    rank=cv.quad_form(x,data)# """ Alias for :math:`x^T P x`构造矩阵(二次型)
    #构造约束条件
    A=np.array([0.02,0.42,1,0.5,0.46,0.3]).reshape(1,6)
    con=[cv.sum(x)==1,A@x>=0.25]
    prob=cv.Problem(cv.Minimize(rank),con)
    prob.solve()
    print('可行解为:\n')
    for i in x.value:
         print(i,' ')
    print('最小值:',prob.value)
    #结果:
    
    可行解为:
    
    [0.45748689]  
    [0.12414101]  
    [0.00955066]  
    [0.12427119]  
    [0.19787315]  
    [0.0866771]  
    最小值: 0.009432199759803417
    
    

    最小 风险为0.94%

    • matlab 二次规划标准型:
      m i n   1 2 x T H x + f T x . s . t . { A x ≤ b A e q ⋅ x = b e q l b ≤ x ≤ u b 。 min~\frac{1}{2}x^THx+f^Tx.\\s.t. \left\{\begin{aligned} & Ax\le b\\ &Aeq\cdot x=beq\\ &lb\le x\le ubpython流星雨特效代码简单。 \end{aligned} \right. min 21​xTHx+fTx.s.t.⎩ ⎨ ⎧​​Ax≤bAeq⋅x=beqlb≤x≤ub。​
    %这里是纯二次型 
    %注意是2*H
    [x,value]=quadprog(2*H,zeros(6,1),A,b,Aeq,beq,zeros(6,1))%H为协方差矩阵
    %结果:
    x =
    
        0.4575    0.1241    0.0096    0.1243    0.1979    0.0867
    value =
    
        0.0094    
    
    

    最小风险为9.4%

    • 该二次规划的二次项过多,lingo求解不如matlab和python(矩阵思想)直观,所以这里不提供lingo求解
  • 5.4 某糖果厂用原料A,B,C加工成三种不同牌号的糖果甲,乙,丙。已知各种牌号糖果中A,B,C含量,原料成本,各种原料的每月限制用量,三种牌号的糖果的单位加工费以及售价,如表5.7所示。问该厂每月生产者三种牌号糖果各多少千克,才能使其获利最大。试建立这个问题的线性规划问题模型。

    原料原料成本/(元/kg)每月限制用量/kg
    A≥ \ge ≥ 60%≥ \ge ≥ 30%22000
    B1.52500
    C≤ \le ≤ 20%≤ \le ≤ 50%≤ \le ≤ 60%11200
    加工费/(元/kg)0.50.40.3
    售价/(元/kg)3.42.852.25
    • 决策变量: x 1 , x 2 , x 3 , x 4 , x 5 , x 6 x_1,x_2,x_3,x_4,x_5,x_6 x1​,x2​,x3​,x4​,x5​,x6​ (甲,乙,丙三种糖果在各自每种原料上的质量)

      原料
      Ax1x2x3
      Bx4x5x6
      Cx7x8x9
    • 利润:售价-加工费-原料成本

    • 目标函数 z = 2.9 ( x 1 + x 4 + x 7 ) + 2.45 ( x 2 + x 5 + x 8 ) + 1.95 ( x 3 + x 6 + x 9 ) − 2 ( x 1 + x 2 + x 3 ) − 1.5 ( x 4 + x 5 + x 6 ) − ( x 7 + x 8 + x 9 ) z=2.9(x_1+x_4+x_7)+2.45(x_2+x_5+x_8)+1.95(x_3+x_6+x_9)-2(x_1+x_2+x_3)-1.5(x_4+x_5+x_6)\\-(x_7+x_8+x_9) z=2.9(x1​+x4​+x7​)+2.45(x2​+x5​+x8​)+1.95(x3​+x6​+x9​)−2(x1​+x2​+x3​)−1.5(x4​+x5​+x6​)−(x7​+x8​+x9​)

    • 约束条件:

      • A,B, C用料限制:
        • A: x 1 + x 2 + x 3 ≤ 2000 x_1+x_2+x_3\le2000 x1​+x2​+x3​≤2000
        • B: x 4 + x 5 + x 6 ≤ 2500 x_4+x_5+x_6\le2500 x4​+x5​+x6​≤2500
        • C: x 7 + x 8 + x 9 ≤ 1200 x_7+x_8+x_9\le1200 x7​+x8​+x9​≤1200
      • 甲,乙,丙中A,B,C的含量限制:
        • 甲: x 1 x 1 + x 4 + x 7 ≥ 60 % , x 7 x 1 + x 4 + x 7 ≤ 20 % \frac{x_1}{x_1+x_4+x_7}\ge60\%,\frac{x_7}{x_1+x_4+x_7}\le20\% x1​+x4​+x7​x1​​≥60%,x1​+x4​+x7​x7​​≤20%
        • 乙: x 2 x 2 + x 5 + x 8 ≥ 30 % , x 8 x 2 + x 5 + x 8 ≤ 50 % \frac{x_2}{x_2+x_5+x_8}\ge30\%,\frac{x_8}{x_2+x_5+x_8}\le50\% x2​+x5​+x8​x2​​≥30%,x2​+x5​+x8​x8​​≤50%
        • 丙: x 9 x 3 + x 6 + x 9 ≤ 60 % \frac{x_9}{x_3+x_6+x_9}\le60\% x3​+x6​+x9​x9​​≤60%
    • 建立线性规划模型:
      m a x   z = [ 0.9 , 0.45 , − 0.05 , 1.4 , 0.95 , 0.45 , 1.9 , 1.45 , 0.95 ] ⋅ X T s . t . { x 1 + x 2 + x 3 ≤ 2000 x 4 + x 5 + x 6 ≤ 2500 x 7 + x 8 + x 9 ≤ 1200 0.6 ( x 1 + x 4 + x 7 ) ≤ x 1 − 0.2 ( x 1 + x 4 + x 7 ) ≤ − x 7 0.3 ( x 2 + x 5 + x 8 ) ≤ x 2 − 0.5 ( x 2 + x 5 + x 8 ) ≤ − x 8 − 0.6 ( x 3 + x 6 + x 9 ) ≤ x 9 max ~z=[0.9,0.45,-0.05,1.4,0.95,0.45,1.9,1.45,0.95]\cdot X^T\\s.t. \left\{\begin{aligned} &x_1+x_2+x_3\le2000\\ &x_4+x_5+x_6\le2500\\ &x_7+x_8+x_9\le1200\\ &0.6(x_1+x_4+x_7)\le x_1\\ &-0.2(x_1+x_4+x_7)\le -x_7\\ &0.3(x_2+x_5+x_8)\le x_2\\ &-0.5(x_2+x_5+x_8)\le -x_8\\ &-0.6(x_3+x_6+x_9)\le x_9 \end{aligned} \right. max z=[0.9,0.45,−0.05,1.4,0.95,0.45,1.9,1.45,0.95]⋅XTs.t.⎩ ⎨ ⎧​​x1​+x2​+x3​≤2000x4​+x5​+x6​≤2500x7​+x8​+x9​≤12000.6(x1​+x4​+x7​)≤x1​−0.2(x1​+x4​+x7​)≤−x7​0.3(x2​+x5​+x8​)≤x2​−0.5(x2​+x5​+x8​)≤−x8​−0.6(x3​+x6​+x9​)≤x9​​

      • python
      import  numpy as np
      import cvxpy as cp
      c=np.array([0.9,0.45,-0.05,1.4,0.95,0.45,1.9,1.45,0.95]).reshape(9,1)
      x=cp.Variable((1,9))
      obj=cp.Maximize(x@c)
      con=[x[0,0]+x[0,1]+[0,2]<=2000,x[0,3]+x[0,4]+x[0,5]<=2500,x[0,6]+x[0,7]+x[0,8]<=1200,
           0.6*(x[0,0]+x[0,3]+x[0,6])<=x[0,0],-0.2*(x[0,0]+x[0,3]+x[0,6])<=-x[0,6],
           0.3*(x[0,1]+x[0,4]+x[0,7])<=x[0,1],-0.5*(x[0,1]+x[0,4]+x[0,7])<=-x[0,7],
           -0.6*(x[0,2]+x[0,5]+x[0,8])<=x[0,8],x>=np.zeros((1,9))
           ]
      prob=cp.Problem(obj,con)
      prob.solve(cp.SCS,verbose=True)
      
      print(x.value)
      print(prob.value)  #求解出来的最大利润5446.98650061946
      
      • lingo
      sets:
      fac/1..9/:c,x;
       
      endsets
      
      data:
      c=0.9,0.45,-0.05,1.4,0.95,0.45,1.9,1.45,0.95;
       
      enddata
      max =@sum(fac(i):c(i)*x(i));
      x(1)+x(2)+x(3)<2000;
      x(4)+x(5)+x(6)<2500;
      x(7)+x(8)+x(9)<1200;
      0.6*(x(1)+x(4)+x(7))<x(1);
      -0.2*(x(1)+x(4)+x(7))<-x(7);
      0.3*(x(2)+x(5)+x(8))<x(2);
      -0.5*(x(2)+x(5)+x(8))<-x(8);
      -0.6*(x(3)+x(6)+x(9))<x(9);
      #结果
                                         X( 1)        580.0000             
                                         X( 2)        1420.000            
                                         X( 3)        0.000000            
                                         X( 4)        386.6667            
                                         X( 5)        2113.333             
                                         X( 6)        0.000000            
                                         X( 7)        0.000000            
                                         X( 8)        1200.000            
                                         X( 9)        0.000000            
      
      
      

      可以看到lingo的代码非常直观

      最大利润:5450

      • matlab 在这里构造系数矩阵A比较繁琐,不考虑matlab实现(不够直观)
  • 5.5 试求解多目标线性规划问题:
    m a x    z 1 = 100 x 1 + 90 x 2 + 80 x 3 + 70 x 4 m i n    z 2 = 3 x 2 + 2 x 4 { x 1 + x 2 ≥ 30 x 3 + x 4 ≥ 30 3 x 1 + 2 x 3 ≤ 120 3 x 2 + 2 x 4 ≤ 48 x i ≥ 0 ,   i = 1 , 2 , 3 , 4 \begin{aligned} &max~~z_1=100x_1+90x_2+80x_3+70x_4\\ &min~~z_2=3x_2+2x_4\\ &\left\{\begin{aligned} &x_1+x_2\ge30\\ &x_3+x_4\ge 30\\ &3x_1+2x_3\le120\\ &3x_2+2x_4\le48\\ &x_i\ge0,~i=1,2,3,4 \end{aligned}\right. \end{aligned} ​max  z1​=100x1​+90x2​+80x3​+70x4​min  z2​=3x2​+2x4​⎩ ⎨ ⎧​​x1​+x2​≥30x3​+x4​≥303x1​+2x3​≤1203x2​+2x4​≤48xi​≥0, i=1,2,3,4​​

    • 求解该多目标问题,只需要构造 f = m i n ( z 2 − z 1 ) f=min(z_2-z_1) f=min(z2​−z1​)即可
    • m i n   f = [ − 100 , − 87 , − 80 , − 68 ] ⋅ X T min ~f=[-100,-87,-80,-68]\cdot X^T min f=[−100,−87,−80,−68]⋅XT
    • matlab
    c=[-100,-87,-80,-68];
    A=[-1,-1,0,0;0,0,-1,-1;3,0,2,0;0,3,0,2];
    b=[-30,-30,120,48]';
    [x,fval]=linprog(c,A,b,[],[],zeros(4,1));
    %结果
    fval =
    
      -5.9120e+03
    
    >> x
    
    x =
    
       14.0000
       16.0000
       39.0000
             0
    
    • python
    import cvxpy as cp
    import numpy as np
    c=np.array([-100,-87,-80,-68]).reshape((1,4))
    x=cp.Variable((4,1))
    b=np.array([-30,-30,120,48]).reshape(4,1)
    A=np.array([[-1,-1,0,0],[0,0,-1,-1],[3,0,2,0],[0,3,0,2]])
    obj=cp.Minimize(c@x)
    con=[A@x<=b,x>=np.zeros((4,1))]
    pro=cp.Problem(obj,con)
    pro.solve()
    print(pro.value)
    print(x.value)
    
    #结果:
    -5911.999999475287
    [[1.40000001e+01]
     [1.59999999e+01]
     [3.89999998e+01]
     [1.26453538e-07]]
    
    
    • lingo 在这里反而还需要将不等式一一输入,相较于矩阵的思想变得繁琐(不做赘述)

综上可以发现求解线性规划问题没有最好的方法,那种方法更直观就使用哪种方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值