优化|单纯形法及其Java实现
本文中的课件来自清华大学深圳国际研究生院,物流与交通学部张灿荣教授《高级运筹学》课程。
张灿荣教授个人主页:https://www.sigs.tsinghua.edu.cn/zcr/list.htm
单纯形法(Simplex Method)
单纯形法是求解线性规划问题的一个经典算法,是一种直接、快速的搜索最小值方法,其优点是收敛速度快,适用面较广。
很多同学肯定对使用单纯形表解决线性规划问题并不陌生,但是每次迭代时对系数矩阵进行变换,其中某些系数的变换是不必要的。通过矩阵变换的形式表达单纯形法的过程可以使计算过程更加简洁,编程实现也更加方便。
该方法涉及的重要公式推导过程如上图所示。其中 x B x_B xB表示基变量, x N x_N xN表示非基变量, B B B和
N N N分别代表基变量与非基变量的约束系数,而 c B c_B cB和 c N c_N cN则分别表示其目标函数的系数。
由目标函数 z z z的表达式可以看出,由于基变量最终取值为零,若其系数 c N − c B B − 1 N c_N-c_BB^{-1}N cN−cBB−1N大于零,则目标函数值仍有提升的空间未得到最优解。故$c_N-c_BB^{-1}N$正是检验数。
单纯形法伪代码
下图给出了单纯形法实现的伪代码。注意,此处解决的是一个最大化问题。
单纯形法的Java实现
接下来,将详细介绍单纯形法的Java实现。
变量符号定义
计算中用到的变量符号定义,具体代码为:
double[] c = new double[c_.size()+l]; //定义目标函数的系数矩阵c
double[][] A = new double[A_.size()][A_.get(0).size()+l]; //定义约束的系数矩阵A
double[] b = new double[b_.size()]; //定义约束值的矩阵b
int per = 0; // 需要添加人工变量的约束个数
double M = 1000000; // 大M法中的“M”
int[] x_B_Num = new int[A.length]; //定义存储基变量标号的一维数组
int[] x_N_Num = new int</