您的位置:首页 > 其它

线性规划 单纯性法

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>// }}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: