线性规划 单纯性法
2015-11-12 21:52
176 查看
<span style="font-family: Arial, Helvetica, sans-serif;">package linearProgramming;</span>
import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; /** * @author Administrator 单纯形法 * * 第一行第一个数字为1代表求目标函数的最大值,-1代表求目标函数的最小值; 第二个数字代表约束条件的个数; 第三个数字代表变量个数; * 第四、五、六个数字分别代表≤的约束条件个数,=的约束条件个数,≥的约束条件个数; * 接下来输入约束条件的系数矩阵和右端项,注意按照≤,=,≥的顺序; 最后按照变量下标顺序输入目标函数的价值系数; * * */ public class Main { // W * X >= B public static int MAX = 1; public static int MIN = -1; public static int nCondition = 6; // row public static int nX = 7; // col public static int nLess = 0; public static int nEqual = 0; public static int nGreater = 6; public static double w[][] = { { 0, 1, 1, 1, 1, 1, 0, 12 }, { 0, 0, 1, 1, 1, 1, 1, 15 }, { 1, 0, 0, 1, 1, 1, 1, 12 }, { 1, 1, 0, 0, 1, 1, 1, 14 }, { 1, 1, 1, 0, 0, 1, 1, 16 }, { 1, 1, 1, 1, 0, 0, 1, 18 } }; public static int x[] = { 1, 1, 1, 1, 1, 1, 1}; public static void main(String[] args) { // readFile(); // showMatrix(); double t1 = System.currentTimeMillis(); LP lp = new LP(MIN, nCondition, nX, nLess, nEqual, nGreater, w, x); double[] ans = lp.solve(); double t2 = System.currentTimeMillis(); showAns(ans); System.out.println("####### time = " + (t2 - t1)); System.out.println(nCondition); System.out.println(nX); } private static void showAns(double[] ans) { System.out.println("\n####### answer as follow"); int xCount = 0; int xSum = 0; for(int i = 0; i < ans.length - 1; i++){ if(ans[i] == 0) continue; xCount++; xSum += ans[i]; System.out.println("X" + (i+1) + " = " + ans[i]); } System.out.println("min = " + ans[ans.length - 1]); System.out.println("xCount = " + xCount); System.out.println("xSum = " + xSum); } private static void readFile() { ArrayList<String> lines = new ArrayList<String>(); File file = new File("src/com/W.csv"); try { BufferedReader br = new BufferedReader(new FileReader(file)); while(br.ready()){ lines.add(br.readLine().trim()); } br.close(); } catch (IOException e) { e.printStackTrace(); } nCondition = lines.size(); nX = lines.get(0).split(",").length; nLess = 0; nEqual = 0; nGreater = nCondition; w = new double[nCondition][nX + 1]; x = new int[nX]; for(int i = 0; i < x.length; i++){ x[i] = 1; } for(int i = 0; i < lines.size(); i++){ String[] strs = lines.get(i).split(","); for(int j = 0; j < strs.length; j++){ w[i][j] = Double.parseDouble(strs[j]); } } file = new File("src/com/A.csv"); try { BufferedReader br = new BufferedReader(new FileReader(file)); int i = 0; while(br.ready()){ w[i++][nX] = Math.ceil(Double.parseDouble(br.readLine().trim()) / 1000); } br.close(); } catch (IOException e) { e.printStackTrace(); } } public static void showMatrix(){ // System.out.println("第一行第一个数字为1代表求目标函数的最大值,-1代表求目标函数的最小值; "); // System.out.println("第二个数字代表约束条件的个数;"); // System.out.println("第三个数字代表变量个数;"); // System.out.println("第四、五、六个数字分别代表≤的约束条件个数,=的约束条件个数,≥的约束条件个数;"); // System.out.println("接下来输入约束条件的系数矩阵和右端项,注意按照≤,=,≥的顺序;"); // System.out.println("最后按照变量下标顺序输入目标函数的价值系数;"); // System.out.println("系数矩阵"); // System.out.println("-1 7 7 0 0 7"); // System.out.println("系数矩阵"); System.out.println("####### W * X>= B"); for (int i = 0; i < w.length; i++) { for (int j = 0; j < w[i].length; j++) { System.out.print(w[i][j] + " "); } System.out.println(); } System.out.println("\n####### the weights of goaling X"); for (int i = 0; i < x.length; i++) { System.out.print(x[i] + " "); } System.out.println(); } }
package linearProgramming;public class LP {<span style="white-space:pre"> </span>private int m; // 约束条件的个数<span style="white-space:pre"> </span>private int n; // 变量个数<span style="white-space:pre"> </span>private int m1; // <=的约束条件个数<span style="white-space:pre"> </span>private int m2; // =的约束条件个数<span style="white-space:pre"> </span>private int m3; // >=的约束条件个数<span style="white-space:pre"> </span>private int error; // 判断是否是错误的<span style="white-space:pre"> </span>private int basic[];<span style="white-space:pre"> </span>private int nonbasic[];<span style="white-space:pre"> </span>private double a[][]; // 约束条件的系数矩阵<span style="white-space:pre"> </span>private double minmax; // 目标函数的最大值或最小值<span style="white-space:pre"> </span>/**<span style="white-space:pre"> </span> * <span style="white-space:pre"> </span> * @param minmax<span style="white-space:pre"> </span> * -求函数的最大值或最小值<span style="white-space:pre"> </span> * @param m<span style="white-space:pre"> </span> * -约束条件的个数<span style="white-space:pre"> </span> * @param n<span style="white-space:pre"> </span> * -变量个数<span style="white-space:pre"> </span> * @param m1<span style="white-space:pre"> </span> * -<=的约束条件个数<span style="white-space:pre"> </span> * @param m2<span style="white-space:pre"> </span> * -=的约束条件个数<span style="white-space:pre"> </span> * @param m3<span style="white-space:pre"> </span> * ->=的约束条件个数<span style="white-space:pre"> </span> * @param a<span style="white-space:pre"> </span> * -约束条件的系数矩阵<span style="white-space:pre"> </span> * @param x<span style="white-space:pre"> </span> * -目标函数的价值系数<span style="white-space:pre"> </span> */<span style="white-space:pre"> </span>public LP(double minmax, int m, int n, int m1, int m2, int m3,<span style="white-space:pre"> </span>double a[][], int x[])// 构造函数<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>double value;<span style="white-space:pre"> </span>this.error = 0;<span style="white-space:pre"> </span>this.minmax = minmax;<span style="white-space:pre"> </span>this.m = m;<span style="white-space:pre"> </span>this.n = n;<span style="white-space:pre"> </span>this.m1 = m1;<span style="white-space:pre"> </span>this.m2 = m2;<span style="white-space:pre"> </span>this.m3 = m3;<span style="white-space:pre"> </span>if (m != m1 + m2 + m3)// 约束条件的溢出<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>this.error = 1;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>this.a = new double[m + 2][];<span style="white-space:pre"> </span>for (int i = 0; i < m + 2; i++) {<span style="white-space:pre"> </span>this.a[i] = new double[n + m + m3 + 1];<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>this.basic = new int[m + 2];<span style="white-space:pre"> </span>this.nonbasic = new int[n + m3 + 1];<span style="white-space:pre"> </span>for (int i = 0; i <= m + 1; i++)// 初始化基本变量和非基本变量<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>for (int j = 0; j <= n + m + m3; j++) {<span style="white-space:pre"> </span>this.a[i][j] = 0.0;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>for (int j = 0; j <= n + m3; j++) {<span style="white-space:pre"> </span>nonbasic[j] = j;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>for (int i = 1, j = n + m3 + 1; i <= m; i++, j++) {<span style="white-space:pre"> </span>basic[i] = j;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 引入松弛变量和人工变量<span style="white-space:pre"> </span>for (int i = m - m3 + 1, j = n + 1; i <= m; i++, j++) {<span style="white-space:pre"> </span>this.a[i][j] = -1;<span style="white-space:pre"> </span>this.a[m + 1][j] = -1;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 输入约束系数和右端项<span style="white-space:pre"> </span>for (int i = 1; i <= m; i++) {<span style="white-space:pre"> </span>for (int j = 1; j <= n; j++) {<span style="white-space:pre"> </span>value = a[i - 1][j - 1];<span style="white-space:pre"> </span>this.a[i][j] = value;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>value = a[i - 1];<span style="white-space:pre"> </span>if (value < 0) {<span style="white-space:pre"> </span>error = 1;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>this.a[i][0] = value;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>for (int j = 1; j <= n; j++) // 输入目标函数系数<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>value = x[j - 1];<span style="white-space:pre"> </span>this.a[0][j] = value * minmax;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 引入人工变量,构造第一阶段的辅助目标函数<span style="white-space:pre"> </span>for (int j = 1; j <= n; j++) {<span style="white-space:pre"> </span>value = 0;<span style="white-space:pre"> </span>for (int i = m1 + 1; i <= m; i++)<span style="white-space:pre"> </span>value += this.a[i][j];<span style="white-space:pre"> </span>this.a[m + 1][j] = value;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 函数enter(objrow)根据目标函数系数所在的行objrow,选取入基变量<span style="white-space:pre"> </span>public int enter(int objrow) {<span style="white-space:pre"> </span>int col = 0;<span style="white-space:pre"> </span>for (int j = 1; j <= this.n + this.m3; j++) {<span style="white-space:pre"> </span>if (this.nonbasic[j] <= this.n + this.m1 + this.m3<span style="white-space:pre"> </span>&& this.a[objrow][j] > 10e-8) {<span style="white-space:pre"> </span>col = j;<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return col;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 函数leave(col)根据入基变量所在的列col,选取离基变量<span style="white-space:pre"> </span>public int leave(int col) {<span style="white-space:pre"> </span>double temp = -1;<span style="white-space:pre"> </span>int row = 0;<span style="white-space:pre"> </span>for (int i = 1; i <= this.m; i++) {<span style="white-space:pre"> </span>double val = this.a[i][col];<span style="white-space:pre"> </span>if (val > 10e-8) {<span style="white-space:pre"> </span>val = this.a[i][0] / val;<span style="white-space:pre"> </span>if (val < temp || temp == -1) {<span style="white-space:pre"> </span>row = i;<span style="white-space:pre"> </span>temp = val;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return row;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 函数swapbasic(row, col)交换基本变量row和非基本变量col的位置<span style="white-space:pre"> </span>public void swapbasic(int row, int col) {<span style="white-space:pre"> </span>int temp = this.basic[row];<span style="white-space:pre"> </span>this.basic[row] = this.nonbasic[col];<span style="white-space:pre"> </span>this.nonbasic[col] = temp;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 函数pivot(row, col)以入基变量所在的列col和离基变量所在的行row交叉处元素a[row][col]为轴心,作转轴变换<span style="white-space:pre"> </span>public void pivot(int row, int col) {<span style="white-space:pre"> </span>for (int j = 0; j <= this.n + this.m3; j++) {<span style="white-space:pre"> </span>if (j != col) {<span style="white-space:pre"> </span>this.a[row][j] = this.a[row][j] / this.a[row][col];<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>this.a[row][col] = 1.0 / this.a[row][col];<span style="white-space:pre"> </span>for (int i = 0; i <= this.m + 1; i++) {<span style="white-space:pre"> </span>if (i != row) {<span style="white-space:pre"> </span>for (int j = 0; j <= this.n + this.m3; j++) {<span style="white-space:pre"> </span>if (j != col) {<span style="white-space:pre"> </span>this.a[i][j] = this.a[i][j] - this.a[i][col]<span style="white-space:pre"> </span>* this.a[row][j];<span style="white-space:pre"> </span>if (Math.abs(this.a[i][j]) < 10e-8)<span style="white-space:pre"> </span>this.a[i][j] = 0;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>this.a[i][col] = -this.a[i][col] * this.a[row][col];<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>swapbasic(row, col);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 函数simplex(objrow)根据目标函数系数所在的行objrow,执行约束标准型线性规划问题的单纯形算法<span style="white-space:pre"> </span>public int simplex(int objrow) {<span style="white-space:pre"> </span>int row = 0;<span style="white-space:pre"> </span>while (true) {<span style="white-space:pre"> </span>int col = enter(objrow);<span style="white-space:pre"> </span>if (col > 0) {<span style="white-space:pre"> </span>row = leave(col);<span style="white-space:pre"> </span>} else {<span style="white-space:pre"> </span>return 0;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>if (row > 0) {<span style="white-space:pre"> </span>pivot(row, col);<span style="white-space:pre"> </span>} else {<span style="white-space:pre"> </span>return 2;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 构造初始基本可行解的第一阶段单纯形算法由phase1()实现<span style="white-space:pre"> </span>public int phase1() {<span style="white-space:pre"> </span>this.error = simplex(this.m + 1);<span style="white-space:pre"> </span>if (this.error > 0) {<span style="white-space:pre"> </span>return this.error;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>for (int i = 1; i <= this.m; i++) {<span style="white-space:pre"> </span>if (this.basic[i] > this.n + this.m1 + this.m3) {<span style="white-space:pre"> </span>if (this.a[i][0] > 10e-8) {<span style="white-space:pre"> </span>return 3;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>for (int j = 1; j <= this.n; j++) {<span style="white-space:pre"> </span>if (Math.abs(this.a[i][j]) >= 10e-8) {<span style="white-space:pre"> </span>pivot(i, j);<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return 0;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>public int phase2() {<span style="white-space:pre"> </span>return simplex(0);<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 函数对一般的线性规划问题执行2阶段单纯形算法<span style="white-space:pre"> </span>public int compute() {<span style="white-space:pre"> </span>if (this.error > 0)<span style="white-space:pre"> </span>return this.error;<span style="white-space:pre"> </span>if (this.m != this.m1) {<span style="white-space:pre"> </span>this.error = phase1();<span style="white-space:pre"> </span>if (this.error > 0)<span style="white-space:pre"> </span>return this.error;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return phase2();<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 函数时执行2阶段单纯形算法的共有函数<span style="white-space:pre"> </span>public double[] solve() {<span style="white-space:pre"> </span>error = compute();<span style="white-space:pre"> </span>switch (error) {<span style="white-space:pre"> </span>case 0:<span style="white-space:pre"> </span>return output();<span style="white-space:pre"> </span>case 1:<span style="white-space:pre"> </span>System.out.println("输入数据错误!");<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>case 2:<span style="white-space:pre"> </span>System.out.println("无界解!");<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>case 3:<span style="white-space:pre"> </span>System.out.println("无可行解!");<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>default:<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>return new double[0];<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// 函数输出2阶段单纯形算法的计算结果<span style="white-space:pre"> </span>public double[] output() {<span style="white-space:pre"> </span>int basicp[] = new int[n + 1];<span style="white-space:pre"> </span>for (int i = 0; i <= n; i++) {<span style="white-space:pre"> </span>basicp[i] = 0;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>for (int i = 1; i <= m; i++) {<span style="white-space:pre"> </span>if (basic[i] >= 1 && basic[i] <= n) {<span style="white-space:pre"> </span>basicp[basic[i]] = i;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>double[] ans = new double[n+1];<span style="white-space:pre"> </span>for (int i = 1; i <= n; i++) {//<span style="white-space:pre"> </span>System.out.print("x" + i + "=");<span style="white-space:pre"> </span>if (basicp[i] != 0) {<span style="white-space:pre"> </span>//System.out.print(a[basicp[i]][0]);<span style="white-space:pre"> </span>ans[i-1] = Math.ceil(a[basicp[i]][0]);<span style="white-space:pre"> </span>} else {<span style="white-space:pre"> </span>ans[i-1] = 0;<span style="white-space:pre"> </span>//System.out.print("0");<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>//System.out.println();<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>ans= Math.ceil(-1 * minmax * a[0][0]);<span style="white-space:pre"> </span>//System.out.println("最优值:" + -minmax * a[0][0]);<span style="white-space:pre"> </span>return ans;<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>// public static void main(String[] args) {<span style="white-space:pre"> </span>// double a[][] = {{1,-2,1,11},{-2,0,1,1},{-4,1,2,3}};<span style="white-space:pre"> </span>// int x[] = {-3,1,1};<span style="white-space:pre"> </span>// xx lp = new xx(-1,3,3,1,1,1,a,x);<span style="white-space:pre"> </span>// lp.solve();<span style="white-space:pre"> </span>// }}
相关文章推荐
- LaTeX多个图片显示在一行
- CUDA 纹理内存
- install cuda on ubuntu
- Gson的使用
- Spark pyspark package
- 公司内网与外网一起上
- OData V4 系列 Action 与 Function
- android传递数据bundle封装传递map对象
- ListView的多选模式
- HDU 1848 Fibonacci again and again(博弈_SG函数)
- 单例模式线程安全的实现方式
- 一条sql语句查出多个表的数据
- Windows平台下Ubuntu系统安装
- 各文件系统对单个文件大小的限制
- ptlib编译时,会自动扫描电脑系统,找出头文件以及库文件并进行引用,生成头文件ptbuildopts.h
- Swift——Command failed due to signal: Segmentation fault: 11
- powerdesigner16.5 列显示comment
- opencv笔记 3.访问图像元素的四种方法
- Objective-数组操作
- iOS之Drawing<2>