栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2021-11-09

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021-11-09

含分式的非线性规划求解: 基于Outer Approximation的Branch-and-cut 算法及其Java实现
  • 问题介绍
  • Outer Approximation介绍
  • java调用cplex代码
  • 参考文献

问题介绍

在混合整数规划求解中,如果目标函数和约束都为线性的情况下,求解器可以直接求解得到精确解。虽然目前求解器也可以完成一些特殊非线性目标函数和约束的求解,如MIQP, MIQCP, MIQCQP, MISOCP等(详情参见运小筹第60期推文),但针对一般的非线性问题,如目标函数为以下的分式形式,就无法利用求解器直接求解。
m i n ∑ i ∈ I U 1 U 2 + ∑ j ∈ J x j (1) min sum_{i in I} frac{U_1 }{U_2+sum_{jin J}x_j}tag{1} mini∈I∑​U2​+∑j∈J​xj​U1​​(1)
针对目标函数为凸函数的情况,我们采取Outer-Approximation(下称OA)的方法进行求解,OA由Duran和Grossmann在1986年提出 [ 1 ] ^{[1]} [1],后面被不断发展改进。OA的基本思想就是利用松弛问题的解生成切线,再加入松弛主问题中,直至找到最优解,利用多条切线去刻画原来的凸函数曲线。近年来的研究中,学者们通常将OA与Branch-and-cut结合使用,利用OA生成cut加入算法中。

Outer Approximation介绍

下面将借助一个具体模型介绍OA的求解过程。
m i n ∑ i ∈ I U 1 U 2 + ∑ j ∈ J ω i j x j (2) min sum_{i in I} frac{U_1 }{U_2+sum_{jin J}omega_{ij}x_j}tag{2} mini∈I∑​U2​+∑j∈J​ωij​xj​U1​​(2)
∑ j ∈ J x j ≤ r (3) sum_{jin J} x_j le r tag{3} j∈J∑​xj​≤r(3)
x j ∈ { 0 , 1 } , ∀ j ∈ J (4) x_j in {0,1}, forall jin Jtag{4} xj​∈{0,1},∀j∈J(4)
针对原问题,我们进行一些变换,引入连续变量 θ theta θ,将复杂的目标函数放在约束条件中
m i n θ (5) min thetatag{5} minθ(5)
θ ≥ ∑ i ∈ I U 1 U 2 + ∑ j ∈ J ω i j x j (6) theta ge sum_{i in I} frac{U_1 }{U_2+sum_{jin J}omega_{ij}x_j} tag{6} θ≥i∈I∑​U2​+∑j∈J​ωij​xj​U1​​(6)
∑ j ∈ J x j ≤ r (7) sum_{jin J} x_j le r tag{7} j∈J∑​xj​≤r(7)
x j ∈ { 0 , 1 } , ∀ j ∈ J (8) x_j in {0,1}, forall jin J tag{8} xj​∈{0,1},∀j∈J(8)
对约束(6),它在 x x x上是凸函数,所以我们在 x ∗ x^* x∗处进行一阶展开得到
θ ≥ F ( x ∗ ) + ∑ j ∈ J F j ′ ( x ∗ ) ( x j − x j ∗ ) (9) theta ge F(x^*)+sum_{j in J} F^{'}_j(x^*)(x_j-x_j^*) tag{9} θ≥F(x∗)+j∈J∑​Fj′​(x∗)(xj​−xj∗​)(9)
其中 F ( x ) = ∑ i ∈ I U 1 U 2 + ∑ j ∈ J ω i j x j F(x)=sum_{i in I} frac{U_1 }{U_2+sum_{jin J}omega_{ij}x_j} F(x)=∑i∈I​U2​+∑j∈J​ωij​xj​U1​​
F j ′ ( x ) = d F ( x ) d x j = − ∑ i ∈ I U 1 ω i j ( U 2 + ∑ k ∈ J w i k x k ) 2 (10) F^{'}_j(x)=frac{dF(x)}{dx_j }=-sum_{i in I}frac{U_1omega_{ij}}{(U_2 +sum_{kin J}w_{ik}x_k)^2} tag{10} Fj′​(x)=dxj​dF(x)​=−i∈I∑​(U2​+∑k∈J​wik​xk​)2U1​ωij​​(10)
所以约束(6)变换为
θ ≥ ∑ i ∈ I U 1 U 2 + ∑ j ∈ J ω i j x j ∗ − ∑ j ∈ J ∑ i ∈ I U 1 ω i j ( U 2 + ∑ k ∈ J w i k x k ∗ ) 2 ( x j − x j ∗ ) (11) theta ge sum_{i in I} frac{U_1 }{U_2+sum_{jin J}omega_{ij}x_j^*}-sum_{jin J}sum_{i in I}frac{U_1omega_{ij}}{(U_2 +sum_{kin J}w_{ik}x_k^*)^2}(x_j-x_j^*) tag{11} θ≥i∈I∑​U2​+∑j∈J​ωij​xj∗​U1​​−j∈J∑​i∈I∑​(U2​+∑k∈J​wik​xk∗​)2U1​ωij​​(xj​−xj∗​)(11)
式(11)就被称为OA cut

java调用cplex代码

Branch-and-cut实现: 为了求解上述模型,我们借助cplex求解器中的callback函数,当当前LP松弛的解决方案 x ∗ x^* x∗被证明是整数时,我们检查是否违反了约束(11),如果违背,则将它们添加到当前LP中,OA cut是全局有效的,通过在MILP求解器的lazy-cut callback实现的。下面是Java调用cplex实现OA cut的Branch-and-cut算法代码。
首先是Cut类,用于存储OA生成的cuts

import java.util.ArrayList;

import ilog.concert.IloNumExpr;

public class Cuts {
	ArrayList lhs;
	ArrayList rhs;
	
	public ArrayList getLhs() {
		return lhs;
	}
	
	public void setLhs(ArrayList lhs) {
		this.lhs = lhs;
	}
	
	public ArrayList getRhs() {
		return rhs;
	}
	
	public void setRhs(ArrayList rhs) {
		this.rhs = rhs;
	}

}

下面是主要的代码


import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import Cuts;
import ilog.concert.*;
import ilog.cplex.IloCplex;
import ilog.cplex.IloCplex.LazyConstraintCallback;

public class OA {
	
	//calculate the gradient
	public static double CalculateGradient(double[] x,double[][] w,int j,int num,double U1,double U2) throws IloException {
		double gradient_j=0; 
		for(int i=0;i cutLhs = new ArrayList();
		ArrayList cutRhs = new ArrayList();
		
		IloLinearNumExpr lhsExpr=ilcplex.linearNumExpr();
		double rhsExpr=0;
		double lhs = 0, rhs = 0;
		
		
		lhsExpr.addTerm(1, theta); 
		
		rhsExpr+=calF(xSol,w,num,U1,U2);
		
		
		for(int j=0;j cutLhs;
		ArrayList cutRhs;
		IloIntVar[] x;
		IloCplex ilcplex;
		IloNumVar theta;
		double[][] w;
		int num;
		double U1,U2;
		
		
		
		LazyCallback(IloIntVar[] x0,IloCplex ilcplex0,IloNumVar theta0,double[][]w0,int num0,double U10,double U20){
			x=x0;
			ilcplex=ilcplex0;
			theta=theta0;
			w=w0;
			num=num0;
			U1=U10;
			U2=U20;
			
		}
		
		public void main() throws IloException{
			double[] xSol =getValues(x);
			double theta0=getValue(theta);
			cut = makecuts(x, xSol,w,num,U1,U2,ilcplex,theta,theta0);
		
			cutLhs = cut.getLhs();
			cutRhs= cut.getRhs();
			for(int i = 0; i< cutLhs.size(); i++) {
				addLocal(ilcplex.ge(ilcplex.diff(cutLhs.get(i),cutRhs.get(i)), 0));
			}
		}
	}
	

	public static void main(String[] args) throws IOException, IloException {
		double U1=5;
		double U2=3;
		int num1=5;
		int num2=10;
		
		double[][] w= {{3,2,5,7,2},{6,2,4,9,3},{3,1,6,5,2},{4,1,3,2,2},{2,8,3,6,2},{7,5,4,9,3},{3,7,5,2,6},{6,4,2,4,6},{4,6,2,8,1},{3,4,8,5,3}};
		
		buildModel(w,num1,num2,U1,U2);

下面为代码的求解结果:

参考文献

[1] Duran M A , Grossmann I E . An outer-approximation algorithm for a class of mixed-integer nonlinear programs[J]. Mathematical Programming, 1986, 36(3):307-339.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/531980.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号