• 个人数学建模算法库之非线性规划模型


    模型描述

    min ⁡ f ( x ) s . t . { A x ≤ b A e q   ⋅ x = b e q c ( x ) ≤ 0 c e q ( x ) = 0 l b ≤ x ≤ u b 其中 , A , x , b , A e q , b e q , l b , u b 含义同线性规划 f ( x ) , c ( x ) , c e q ( x ) 代表非线性向量函数 \min f(x) \\ s.t. {AxbAeq x=beqc(x)0ceq(x)=0lbxub\\ 其中,A,x,b,Aeq,beq,lb,ub含义同线性规划\\ f(x),c(x),ceq(x)代表非线性向量函数 minf(x)s.t. AxbAeq x=beqc(x)0ceq(x)=0lbxub其中,A,x,b,Aeq,beq,lb,ub含义同线性规划f(x),c(x),ceq(x)代表非线性向量函数

    如:
    min ⁡ f ( x ) = x 1 2 + x 2 2 + x 3 2 + 8 s . t . { x 1 2 − x 2 + x 3 2 ≥ 0 x 1 + x 2 2 + x 3 2 ≤ 20 − x 1 − x 2 2 + 2 = 0 x 2 + 2 x 3 2 = 3 x 1 , x 2 , x 3 ≥ 0 \min f(x)=x_1^2+x_2^2+x_3^2+8\\ s.t. {x21x2+x230x1+x22+x2320x1x22+2=0x2+2x23=3x1,x2,x30\\ minf(x)=x12+x22+x32+8s.t. x12x2+x320x1+x22+x3220x1x22+2=0x2+2x32=3x1,x2,x30
    化为标准型:
    min ⁡ f ( x ) = x 1 2 + x 2 2 + x 3 2 + 8 s . t . { − x 1 2 + x 2 − x 3 2 ≤ 0 x 1 + x 2 2 + x 3 2 − 20 ≤ 0 − x 1 − x 2 2 + 2 = 0 x 2 + 2 x 3 2 − 3 = 0 0 ≤ x 1 , x 2 , x 3 \min f(x)=x_1^2+x_2^2+x_3^2+8\\ s.t. {x21+x2x230x1+x22+x23200x1x22+2=0x2+2x233=00x1,x2,x3\\ minf(x)=x12+x22+x32+8s.t. x12+x2x320x1+x22+x32200x1x22+2=0x2+2x323=00x1,x2,x3

    Matlab代码

    [x,fval]=fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options);
    
    • 1
    • fun可以为自定义的非线性向量函数,代表 f ( x ) f(x) f(x)
    • x0x的初始值
    • A,b,Aeq,beq,lb,ub的含义同linprog函数
    • nonlcon为非线性约束,可以为自定义的非线性向量函数,代表 c ( x ) c(x) c(x), c e q ( x ) ceq(x) ceq(x)
    • options为优化可选项
    % fun.m
    
    function y = fun(x)
    % 产生目标函数
    
    y=x(1)^2+x(2)^2+x(3)^2+8;
    
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    % nonlcon.m
    
    function  [c,ceq]= nonclon(x)
    % 产生非线性约束
    % c为非线性不等式约束
    % ceq为非线性等式约束
    
    c=[-x(1)^2+x(2)-x(3)^2 ;x(1)+x(2)^2+x(3)^2-20];
    ceq=[-x(1)-x(2)^2+2 ;x(2)+2*x(3)^2-3];
    
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    % NonlinprogTest.m
    
    x0=[1 ;1 ;1];
    lb=[0 ;0 ;0];
    [x,fval]=fmincon('fun',x0,[],[],[],[],lb,[],'nonclon');
    display(x);
    display(fval);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    x =
    
        0.5522
        1.2033
        0.9478
    
    
    fval =
    
       10.6511
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Python代码

    from scipy import optimize
    import numpy as np
    
    
    class Nolinprog:
        """非线性规划问题类"""
        def __init__(self,
                     fun,
                     x0,
                     A=[],
                     b=[],
                     Aeq=[],
                     beq=[],
                     lb=None,
                     ub=None,
                     c=None,
                     ceq=None):
    
            # 初始化参数
            self.fun = fun
            self.x0 = x0
            self.A = A
            self.b = b
            self.Aeq = Aeq
            self.beq = beq
            self.lb = lb
            self.ub = ub
            self.c = c
            self.ceq = ceq
            self.cons = self.__make_cons()
            self.bounds = None
    
            self.x, self.fval, self.status = None, None, False
    
        def __make_cons(self):
            # 创建约束条件
            cons = []
    
            # 线性等式约束
            if np.size(self.Aeq) and np.size(self.beq):
                for i in range(self.Aeq.shape[0]):
                    cons.append({
                        'type':
                        'eq',
                        'fun': (lambda x: sum(self.Aeq[i] * x) - self.beq[i])
                    })
    
            # 线性不等式约束(>=0)
            if np.size(self.A) and np.size(self.b):
                for i in range(self.A.shape[0]):
                    cons.append({
                        'type': 'ineq',
                        'fun': (lambda x: sum(self.A[i] * x) - self.b[i])
                    })
    
            # 非线性不等式约束(>=0)
            if self.c:
                for fun in self.c():
                    cons.append({'type': 'ineq', 'fun': fun})
    
            # 非线性等式约束
            if self.ceq:
                for fun in self.ceq():
                    cons.append({'type': 'eq', 'fun': fun})
    
            # 上下界约束
            if not self.lb:
                self.lb = -np.ones(self.x0.shape) * np.inf
    
            if not self.ub:
                self.ub = np.ones(self.x0.shape) * np.inf
    
                self.bounds = np.array(list(zip(self.lb, self.ub)), dtype=object)
    
            cons = tuple(cons)
            return cons
    
        def solve(self):
            # 求解规划问题
            result = optimize.minimize(self.fun,
                                       self.x0,
                                       constraints=self.cons,
                                       bounds=self.bounds)
            self.x, self.fval, self.status = result.x, result.fun, result.success
            return result
    
        def show(self, for_min=True):
            # 展示规划结果
            if self.status == False:
                print("无满足条件的解")
                return
    
            if for_min:
                print(f"当x取 {self.x} 时,得最小值{self.fval}")
            else:
                print(f"当x取 {self.x} 时,得最大值{-self.fval}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    测试结果如下:

    # 创建目标函数
    def fun(x):
        y = x[0]**2 + x[1]**2 + x[2]**2 + 8
        return y
    
    
    # 创建非线性不等式约束函数(>=0)
    def c():
        c1 = lambda x: x[0]**2 - x[1] + x[2]**2
        c2 = lambda x: -x[0] - x[1]**2 - x[2]**2 + 20
        return c1, c2
    
    
    # # 创建非线性等式约束函数
    def ceq():
        ceq1 = lambda x: -x[0] - x[1]**2 + 2
        ceq2 = lambda x: x[1] + 2 * x[2]**2 - 3
        return ceq1, ceq2
    
    
    x0 = np.array([1, 1, 1])
    lb = [0, 0, 0]
    
    # 求解非线性规划问题
    pro = Nolinprog(fun, x0, c=c, ceq=ceq, lb=lb)
    pro.solve()
    pro.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    当x取 [0.55216734 1.20325918 0.94782404] 时,得最小值10.651091840594646
    
    • 1
  • 相关阅读:
    【Spring Security】安全框架学习(十三)
    MongoDB归并连续号段-(待验证)
    Python基于Flask的招聘信息爬取、招聘信息可视化系统
    怎么测试服务器访问速度
    技术分享 | 测试开发工程师必读经典好书清单
    [附源码]Python计算机毕业设计Django电影推荐网站
    【Go】slice
    如何从一个美术变成程序员?
    【Spark】PySpark DataFrame
    六、Echart图表 之 tooltip提示框组件配置项大全
  • 原文地址:https://blog.csdn.net/ncu5509121083/article/details/126909340