利用两阶段法通过寻找基可行解求线性规划问题的最优解

算法介绍:

java代码实现:

package sy1;
//标准化系数矩阵  并加上人工变量
public class BzhAndJrg {
	public double A[][];  //原矩阵的系数矩阵
	public String D[];   //原矩阵的符号矩阵
	public double b[];    //原矩阵的常数矩阵
	public double B[][];    //原矩阵标准化后的系数矩阵
	public double R[][];  //标准化矩阵添加人工变量之后的系数矩阵
	public double C[];//目标函数的初始系数向量
	public double c[];//标准化之后目标函数的系数向量
	int N,M;
	public BzhAndJrg(int m,int n,double a[][],double b1[],String d[],double C1[]){
		N=n;
		M=m;
		A=a;
		D=d;
		b=b1;
		C=C1;
		B=new double[m][n+m];
		c=new double[n+m];
		R=new double[m][n+m+m];
		for(int i=0;i<m;i++){
			for(int j=0;j<m+n+m;j++){
				R[i][j]=0;
			}
		}
		for(int i=0;i<m;i++){
			for(int j=0;j<m+n;j++){
				B[i][j]=0;
			}
		}
	}
	//标准话目标函数的系数向量
	public double[] bc(){
		for(int i=0;i<N+M;i++){
			if(i<N)
			c[i]=C[i];
			else
				c[i]=0;
		}
		return c;
	}
	//标准化系数矩阵
	public double[][] bzh(){
		for(int i=0;i<b.length;i++){
			for(int j=0;j<A[i].length;j++){
				B[i][j]=A[i][j];
				//System.out.print(B[i][j]+" ");
			}
			//System.out.println();
		}
		for(int i=0;i<b.length;i++){
			if(D[i].equals(">")){//大于则添加剩余变量
				B[i][A[i].length+i]=-1;
			}
			else if(D[i].equals("<")){//小于则添加松弛变量
				B[i][A[i].length+i]=1;
			}
			else if(D[i].equals("="))
				B[i][A[i].length+i]=0;
		}
		return B;
	}
	//对标准化系数矩阵加人共变量
	public double[][] jrgbl(){
		B=bzh();
		for(int i=0;i<b.length;i++){
			for(int j=0;j<B[i].length;j++){
				R[i][j]=B[i][j];
			}
		}
		for(int i=0;i<b.length;i++){
			R[i][B[i].length+i]=1;
		}
		return R;
	}
}


 

package sy1;

/*
 * 单纯形算法实现
 */
public class FirstStep {
	public double A[][];   //未知数的系数矩阵
	public double b[];  //约束条件的常数向量
	public double c[];  //目标函数的系数向量
	public String[] Xb; //基变量
	public boolean flag=true;
	double Cb[];//目标函数中基变量的对应系数
	int M,N;   //约束条件个数为M,未知数个数为N
	double sgma[];
	double seta[];
	public FirstStep(int m,int n,double R[][],double B[]){
		M=m;
		N=n;
		A=R;//初始化系数矩阵
		b=B;//初始化常数矩阵
	    c=new double[n+m+m];//初始化目标函数的系数向量
		Xb=new String[m];//初始化基变量
		Cb=new double[M];//初始化目标函数中基变量对应的系数向量
		sgma=new double[N+M+M];//初始化检验数
		seta=new double[M];  //初始化seta
		for(int i=0;i<m;i++){
			Xb[i]="x"+String.valueOf(n+m+i);  //初始化基变量为人工变量
			//System.out.print(Xb[i]+" ");
		}
	}
	/*
	 * 找出两阶段法中第一阶段中目标函数的系数向量c
	 */
	public double[] c(){
		for(int i=0;i<N+M+M;i++){
			if(i<N+M){
				c[i]=0;
			}
			else
				c[i]=1;
		}
		return c;
	}
	public boolean[] psegma(){
		boolean[] temp=new boolean[3];//判断线性规划问题解的存在情况
		boolean flag=true;//用来判断是否有可行解
		boolean flag1=false;//用来判断除了非基变量对应的检验数是否有负的,有为true,无为false
		boolean flag2=true;//用来判断基变量对应的换否全为负
		boolean flag3=false;//用来判断非基变量中是否有检验数为0的
		boolean flag4=true; //用来判断非基变量的检验数是否全为正
		for(int i=0;i<N+M;i++){
			if(sgma[i]<0){//当目标函数为max时改为>0
				flag=false;
				break;
			}
		}
		temp[0]=flag;//判断通过单纯形法是否找到了最优解,如果flag=true表示检验数全都小于等于0
		int t1=0;
		int t2[]=new int[Xb.length];//基变量
		int t3[]=new int[N+M];//非基变量
		for(int i=0;i<M;i++){
			t2[i]=(int)Integer.parseInt(Xb[i].substring(1));//确定基变量
		}
			//for语句用来进行flag1判断
		//寻找非基变量
		int t5=0;
		for(int j=0;j<M+N+M;j++){
			int t4=0;
			for(int i=0;i<M;i++){
				if(j==t2[i]){
					t4++;
					//System.out.println(t4);
				}//if
			}//for
			if(t4==0){
				t3[t5]=j;
				//System.out.println(t3[t5]);
				t5++;
			}//if
		}//for j
		//System.out.println(t5);
		//判断非基变量中是否有为负的检验数
		for(int i=0;i<N;i++){
			if(sgma[t3[i]]<0){//当max时改为>
				flag1=true;//有负的检验数
				t1=i;
				break;
			}//if
				}//i
		//判断非基变量为负的列中的值是否全非正
		for(int i=0;i<M;i++){
			if(A[i][t1]>0){
				flag2=false;
				break;
			}
		}
		if(flag1 && flag2){
			temp[1]=true;//表明该线性规划问题有无界解
			//System.out.println(temp[1]);
		}
		//判断非基变量中是否有为0的检验数
		for(int i=0;i<N;i++){
			if(sgma[t3[i]]<0){//当max时改为>
				flag4=false;//有负的检验数
				break;
			}//if
				}//i
		for(int i=0;i<N;i++){
			if(sgma[t3[i]]==0){//当max时改为>
				flag3=true;//有负的检验数
				break;
			}//if
				}//i
		if(flag4 && flag3){
			temp[2]=true;//表明该线性规划问题有无穷多最优解
			//System.out.println(temp[2]);
		}//if
		//System.out.println(temp[2]);
		return temp;//flag=true说明检验数全为负,flag=false说明检验数不全为负
	}
	/*
	 * 计算基变量XB
	 */
	public String[] Xb(){
			for(int i=0;i<M+N;i++){
				int count0=0,count1=0;//用来判断对应未知数的系数向量是不是除了一个1之外,其他的全为0
				for(int j=0;j<M;j++){
					if(A[j][i]==0){
						count0=count0+1;
					}
					else
					if(A[j][i]==1){
						count1=count1+1;
					}
					else
						break;
						}// for j
				if(count1==1 && count0==M-1){
		
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值