//开始运行搜索目标函数的最小值和灵敏度分析
public void Run()
{
X=new double[M];
Y=new double[M];
Delta=new double[N-M];
P=new double[M];
PF=new double[M];
int flag=1;
do{
_B=Reverse(B);
X=Multiply(_B,b);
Y=Multiply(cb,_B);
Delta=Minus(Multiply(Y,NN),cn);
xin=Max(Delta);
if(Delta[xin]<=0)break;
for(int i=0;i<M;i++)
{
P[i]=A[i][Xoutcount[xin]];
}
PF=Multiply(_B,P);
if(PF[Max(PF)]<=0)
{
System.out.println("...Cann't find out the minimum value!");
System.exit(1);
}
xout=Min(X,PF);
for(int i=0;i<M;i++)
{
double t=B[i][xout];
B[i][xout]=NN[i][xin];
NN[i][xin]=t;
}
int r=Xincount[xout];
Xincount[xout]=Xoutcount[xin];
Xoutcount[xin]=r;
double t=cb[xout];
cb[xout]=cn[xin];
cn[xin]=t;
}while(true);
getAreab();
getAreac();
getAreaA();
}
//取得结果中x的值(n维列向量)
public double[] getX()
{
double[] Result=new double[N];
for(int i=0;i<N;i++)
{
boolean flag=false;
for(int j=0;j<Xincount.length;j++)
{
if(Xincount[j]==i)
{
Result[i]=X[j];
flag=true;
break;
}
}
if(!flag)Result[i]=0;
}
return Result;
}
//取得函数的最小值
public double getValue()
{
return Multiply(cb,X);
}
//取得最优化情况下基变量的序号(m维行向量)
public int[] getRadix()
{
return Sort(Xincount);
}
//计算b的灵敏度
public void getAreab()
{
Maxb=new double[M];
Minb=new double[M];
double max,min;
for(int i=0;i<b.length;i++)
{
max=-Infinite;min=Infinite;
for(int j=0;j<M;j++)
{
double tmp=Infinite;
//System.out.println(X[i]+" "+_B[j][i]);
if(_B[j][i]!=0)tmp=-X[j]/_B[j][i];
if(_B[j][i]>0)
{
if(max<tmp)
{
max=tmp;
}
}
if(_B[j][i]<0)
{
if(min>tmp)
{
min=tmp;
}
}
}
if(min==Infinite)
{
Maxb[i]=Infinite;
}else
{
Maxb[i]=b[i]+min;
}
if(max==-Infinite)
{
Minb[i]=-Infinite;
}else{
Minb[i]=b[i]+max;
}
}
}
//取得b的最大值数组
public double[] getMaxb()
{
return Maxb;
}
//取得b的最小值数组
public double[] getMinb()
{
return Minb;
}
//计算c的灵敏度
private void getAreac()
{
Maxc=new double[N];
Minc=new double[N];

double max,min;
double[][] AN=Multiply(_B,NN);
for(int i=0;i<N;i++)
{
if(getIndex(Xincount,i)!=-1)
{
max=-Infinite;min=Infinite;
int l=getIndex(Xincount,i);
for(int j=0;j<N-M;j++)
{
double tmp=Infinite;
if(AN[l][j]!=0)tmp=-Delta[j]/AN[l][j];
if(AN[l][j]>0)
{
if(max<tmp)
{
max=tmp;
}
}
if(AN[l][j]<0)
{
if(min>tmp)
{
min=tmp;
}
}
}
if(min==Infinite)
{
Maxc[i]=Infinite;
}else{
Maxc[i]=-(c[i]+min);
}
if(max==-Infinite)
{
Minc[i]=-Infinite;
}else{
Minc[i]=-(c[i]+max);
}
if(Math.abs(Maxc[i])==0.0)Maxc[i]=0.0;
if(Math.abs(Minc[i])==0.0)Minc[i]=0.0;
}else{
Maxc[i]=Infinite;
Minc[i]=c[i]+Delta[getIndex(Xoutcount,i)];
}
}
}
//搜索k在向量M中的序号,如果没有则返回-1
private int getIndex(int[] M,int k)
{
int r=-1;
for(int i=0;i<M.length;i++)
{
if(M[i]==k)
{
r=i;
break;
}
}
return r;
}
//取得c的最大值数组
public double[] getMaxc()
{
return Maxc;
}
//取得c的最小值数组
public double[] getMinc()
{
return Minc;
}
//计算系数矩阵A的灵敏度
private void getAreaA()
{
MaxA=new double[M][N];
MinA=new double[M][N];

for(int j=0;j<N;j++)
{
if(getIndex(Xincount,j)!=-1)
{
for(int i=0;i<M;i++)
{
MaxA[i][j]=A[i][j];
MinA[i][j]=A[i][j];
}
}else{
for(int i=0;i<M;i++)
{
MaxA[i][j]=Infinite;
if(Y[i]==0)
{
MinA[i][j]=-Infinite;
}else{
MinA[i][j]=A[i][j]-Delta[getIndex(Xoutcount,j)]/Y[i];
}
}
}
}
}
//取得A的最大值数组
public double[][] getMaxA()
{
return MaxA;
}
//取得A的最小值数组
public double[][] getMinA()
{
return MinA;
}
}