| 
 | 
 
一、教材及例题说明 
 
 
  
本文例题来源于清华大学出版的运筹学(第三版)P79例题1,课本已经讲解了表上作业法的求解过程,本文主要讲解如何用程序求解问题。(在实际解决问题的时候如果采用表上作业法,黄花菜都凉透了。。。) 
题目如下所示: 
 
  
 
  
构建如下模型: 
min z =\sum_{i=1}^{3}\sum_{j=1}^{4}{c_{ij}}{x_{ij}}   
\sum_{i=1}^{3}{x_{ij}}=b_{j},j=1,2,3,4  
\sum_{j=1}^{4}{x_{ij}}=a_{i},i=1,2,3  
\sum_{i=1}^{3}\sum_{j=1}^{4}{x_{ij}}\geq0  
根据运价表和产销平衡表构建如下数学模型: 
min z =3*x_{11}+11*x_{12}+3*x_{13}+10*x_{14}+1*x_{21}+9*x_{22}+2*x_{23}+8*x_{24}+7*x_{31}+4*x_{32}+10*x_{33}+5*x_{34}  
x_{11}+x_{12}+x_{13}+x_{14}=7      (1) 
x_{21}+x_{22}+x_{23}+x_{24}=4      (2) 
x_{31}+x_{32}+x_{33}+x_{34}=9      (3) 
x_{11}+x_{21}+x_{31}=3   (4) 
x_{12}+x_{22}+x_{32}=6   (5) 
x_{13}+x_{23}+x_{33}=5   (6) 
x_{14}+x_{24}+x_{34}=6   (7) 
二、采用面向过程思维求解 
 
这也是一个线性规划问题,可以按照我们前一节中讲的五步法求解,先展示以下过程,然后再说这种方法的弊端。具体代码如下: 
package cplex.practice; 
 
import ilog.concert.*; 
import ilog.cplex.*; 
 
public class TransportionProblem { 
        public static void main(String[] args) { 
                try { 
//                        1、定义模型 
                        IloCplex cplex = new IloCplex(); 
                         
//                        2、定义参数变量 
                        double[] lb = new double[12]; 
                        for(int i=0; i<lb.length; i++) {lb=0;} 
                        double[] up = new double[12]; 
                        for(int i=0; i<up.length; i++) {up=Double.MAX_VALUE;} 
                        IloNumVar[] x =cplex.numVarArray(12, lb, up); 
                         
//                        3、定义目标函数 
                        // 定义目标函数系数 
                        double[] objvals = {3, 11, 3, 10, 1, 9, 2, 8, 7, 4, 10, 5}; 
                        //定义目标函数 
                        cplex.addMinimize(cplex.scalProd(x, objvals)); 
                         
//                        4、定义约束条件 
                        IloNumExpr cs1 = cplex.numExpr(); 
                        IloNumExpr cs2 = cplex.numExpr(); 
                        IloNumExpr cs3 = cplex.numExpr(); 
                        for(int i=0;i<3;i++) { 
                                for(int j=0; j<4; j++){ 
                                        switch(i){ 
                                                case 0: 
                                                        cs1= cplex.sum(cs1,x[i*j+j]); 
                                                        continue; 
                                                case 1: 
                                                        cs2= cplex.sum(cs2,x[i*4+j]); 
                                                        continue; 
                                                case 2: 
                                                        cs3= cplex.sum(cs3,x[i*4+j]); 
                                                        continue;                         
                                        } 
 
                                } 
                        } 
                        cplex.addEq(cs1,7); 
                        cplex.addEq(cs2,4); 
                        cplex.addEq(cs3,9); 
 
                        IloNumExpr cs4 = cplex.numExpr(); 
                        IloNumExpr cs5 = cplex.numExpr(); 
                        IloNumExpr cs6 = cplex.numExpr(); 
                        IloNumExpr cs7 = cplex.numExpr(); 
                        for(int j=0;j<4;j++) { 
                                for(int i=0; i<3; i++){ 
                                        switch(j){ 
                                                case 0: 
                                                        cs4= cplex.sum(cs4,x[i*4+j]); 
                                                        continue; 
                                                case 1: 
                                                        cs5= cplex.sum(cs5,x[i*4+j]); 
                                                        continue; 
                                                case 2: 
                                                        cs6= cplex.sum(cs6,x[i*4+j]); 
                                                        continue; 
                                                case 3: 
                                                        cs7= cplex.sum(cs7,x[i*4+j]); 
                                                        continue; 
                                        } 
 
                                } 
                        } 
                        cplex.addEq(cs4,3); 
                        cplex.addEq(cs5,6); 
                        cplex.addEq(cs6,5); 
                        cplex.addEq(cs7,6); 
                         
//                        5、求解、获得并展示结果 
                        if(cplex.solve()) { 
                            cplex.output().println(&#34;Solution status = &#34; + cplex.getStatus()); 
                            cplex.output().println(&#34;Solution value = &#34; + cplex.getObjValue()); 
                            double[] val = cplex.getValues(x); 
//                            for (int j = 0; j < val.length; j++) { 
//                                        cplex.output().println(&#34;x&#34; + (j+1) + &#34;  = &#34; + val[j]); 
//                                } 
                            for (int i = 0; i < 3; i++) { 
                                    for(int j = 0; j<4; j++) { 
                                            cplex.output().print(&#34;x&#34; + (i*4+j) + &#34;  = &#34; + val[i*4+j]+&#34;   &#34;); 
                                    } 
                                        System.out.println(); 
                                } 
                        } 
                        else {System.out.println(&#34;No feasible solution!&#34;);} 
                } 
                catch(IloException e) { 
                        System.err.println(&#34;Concert exception caught:&#34; + e); 
                } 
        } 
} 
三、结果展示 
 
程序求解结果: 
 
  
教材求解结果: 
 
  
两者是一致的。 
四、面向过程求解方法优、缺点分析 
 
优点:代码过程直观、好理解; 
缺点:代码通用性差,如果运输节点、需求、运价等数据发生变化,改动代码比较麻烦,容易出错。 
下一节将介绍如何利用面向对象思维求解运输问题。 
PS : 文章中有任何问题,欢迎大家批评指正! |   
 
 
 
 |