您的位置:首页 > 理论基础 > 计算机网络

《趣学算法》 第七章线性规划网络流代码实现(Java)

2018-02-28 17:10 405 查看

7.2 单纯形算法

import java.util.Scanner;

public class Test7_1 {

static int n,m,i,j; //m表示非基本变量个数即矩阵的列数,n表示基本变量个数即矩阵的行数
static int[] FJL=new int[100]; //存放非基本变量
static int[] JL=new int[100]; //存放基本变量
static float[][] kernel=new float[100][100]; //存放单纯形表

public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("输入非基本变量个数和非基本变量下标:");
m=scanner.nextInt();
for(int i=1;i<=m;i++)
FJL[i]=scanner.nextInt();
System.out.println("输入基本变量个数和基本变量下标:");
n=scanner.nextInt();
for(int i=1;i<=n;i++)
JL[i]=scanner.nextInt();
System.out.println("输入约束标准型初始单纯形表参数:");
for(int i=0;i<=n;i++) {
for(int j=0;j<=m;j++)
kernel[i][j]=scanner.nextFloat(); //检验数放第一行,常数项放第一列,非基本变量的系数作为值
}
print(); //输出单纯形表
DCXA();
scanner.close();
}

/*输出单纯形表*/
public static void print() {
System.out.println();
System.out.println("单纯形表如下:");
System.out.print(" "+"b ");
for(i=1;i<=m;i++)
System.out.print("x"+FJL[i]+" ");
System.out.println();
System.out.println("c ");
for(i=0;i<=n;i++) {
if(i>=1)
System.out.print("x"+JL[i]+" ");
for(j=0;j<=m;j++)
System.out.print(kernel[i][j]+" ");
System.out.println();
}
}

/*求解函数*/
public static void DCXA() {
float max1; //用于存放最大的检验数
float max2; //用于存放最大正检验数对应的基本变量的最大系数
int e=-1; //记录入基列
int k=-1; //记录离基行
float min;

while(true) { //循环迭代,直到直到问题的解或无解
max1=0;
max2=0;
min=10000000;

for(j=1;j<=m;j++) { //找入基列,即正检验数中最大的为入基变量,所在列为入基列
if(max1<kernel[0][j]) {
max1=kernel[0][j];
e=j; //记录入基列的列下标
}
}
if(max1<=0) { //所有的检验值小于等于0,获得最优解
System.out.println("获得最优解:"+kernel[0][0]);
break;
}

for(i=1;i<=n;i++) { //找离基行,常数列/入基列正比值最小对应的行
if(max2<kernel[i][e]) //入基列中的最大系数
max2=kernel[i][e];

float temp=kernel[i][0]/kernel[i][e]; //常数项/入基列
temp=Math.abs(temp);
if(temp>0&&temp<min) {
min=temp; //找比值最小
k=i; //记录离基行的行下标
}
}
System.out.println("基列变量:x"+FJL[e]);
System.out.println("离基变量:x"+JL[k]);
if(max2==0) { //无解
System.out.println("解无界");
break;
}

//将入基变量和离基变量互换位置
int temp=FJL[e];
FJL[e]=JL[k];
JL[k]=temp;

//计算单纯形表
for(i=0;i<=n;i++) { //计算除入基列和离基行的所有位置的元素
if(i!=k) { //非离基行
for(j=0;j<=m;j++) {
if(j!=e) { //非入基列
if(i==0&&j==0)
kernel[i][j]=kernel[i][j]+kernel[i][e]*kernel[k][j]/kernel[k][e]; //计算特殊位置c0位
else
kernel[i][j]=kernel[i][j]-kernel[i][e]*kernel[k][j]/kernel[k][e]; //一般位置
}
}
}
}
for(i=0;i<=n;i++) { //计算入基列的元素
if(i!=k) //非交叉位
kernel[i][e]=-kernel[i][e]/kernel[k][e];
}

for(j=0;j<=m;j++) { //计算离基行的元素
if(j!=e) //非交叉位
kernel[k][j]=kernel[k][j]/kernel[k][e];
}
kernel[k][e]=1/kernel[k][e]; //计算交叉位置
print();

}
}

}
程序运行结果如下:



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