<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][n]; <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[n] = 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>// } }