⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 单纯形法(指导书改进1).c

📁 这是一种改进的单纯型法
💻 C
字号:
#include <iostream.h>
#include<stdio.h>
#include<math.h>
#define M 20
#define N 20
float matrix[M][N],x[M],c[N],b[N],Zm; 
          //单纯形表系数数组,解的数组,目标函数数组,常数项数组,目标函数值
int a[N],rg[N]; //记录基变量的数组与人工变量的数组
int m,n,s,type; //原问题变量数,约束方程数,LP问题的类型,用0表示最小化,1表示最大化
int indexe,indexl,indexg;  //记录剩余变量,松弛变量与人工变量的个数

void Jckxj()  //构造基本可行解
{
	int i;
    for(i=0;i<=s;i++) x[i]=0;
	for(i=0;i<n;i++) x[a[i]]=b[i];
}

int RjMin()  //检验数状态判别
{
  int i,temp=0;
  float min;
  min=matrix[n][0];
  for(i=1;i<=s;i++)
  {   
     if(min>matrix[n][i])
     {
       min=matrix[n][i];
       temp=i;
     }
  }
  return temp;
}
 
void JustArtificial() //判断解中是否存在非零的人工变量
{
  int i,j;
  for(i=0;i<n;i++)
	  for(j=1;j<=indexg;j++)
       if(a[i]==rg[j])
       {
	     printf("No Answer\n");
	     return;
       }
}

int Check(int in)  //检查无界解情况(参数in对应入基列)
{
  int i;
  float maxl=-1;
  for(i=0;i<n;i++)
     if(fabs(matrix[i][in])>=0.000001&&maxl<b[i]/matrix[i][in])
	      maxl=b[i]/matrix[i][in];
     if(maxl<0)	 return 1;  //无界解
     return 0;
}

int SearchOut(int *temp,int in)  //寻找出基变量
{
  int i;
  float min=10000;
  for(i=0;i<n;i++)
     if(fabs(matrix[i][in])>=0.00001&&(b[i]/matrix[i][in]>=0)
		   &&min>b[i]/matrix[i][in])
       {
	     min=b[i]/matrix[i][in];
	     *temp=i;
       }
  return *temp;
};

void MtoBe(int temp,int in)  //基变换
{
  int i,j;float cs;
  Zm=0;
  for(i=0;i<=s;i++)  //对主元行(出基变量行)进行处理
  {
	  if(i!=in)
	      matrix[temp][i]=matrix[temp][i]/matrix[temp][in];
  }
  b[temp]=b[temp]/matrix[temp][in];
  matrix[temp][in]=1;
  for(i=0;i<=n;i++)
  {
    cs=matrix[i][in];  
    if(i!=temp)    //对非主元行进行系数变换
	{
		for(j=0;j<=s;j++)
	     matrix[i][j]=matrix[i][j]-matrix[temp][j]*cs;
	    b[i]=b[i]-b[temp]*cs;
	}
  }
}

void InitPrint()   //输出初始单纯形表(头)
{
  int i;
  printf("———————————————————————————————————\n");
  printf(" Cj");
  for(i=0;i<=s;i++)
      printf("%8.2f",c[i]);
  printf("\n———————————————————————————————————\n");
  printf(" X");
  for(i=0;i<=s;i++)
      printf("    x[%d]",i);
  printf("    b[]\n");
  printf("———————————————————————————————————\n");
}

void Print()  //输出单纯形表函数
{
   int i,j,temp=0;
   for(i=0;i<n;i++)
   {      
      printf("X%d",a[i]);//基变量标识输出
	 for(j=0;j<=s;j++)  
	   printf("%8.2f",matrix[i][j]);
	 printf("%8.2f\n",b[i]);
   }
   printf("Rj");
    for(j=0;j<=s;j++)    //输出检验数(在数组的第n行中)
       printf("%8.2f",matrix[n][j]);
    printf("\n");
}

void Result()  //输出当前解与目标函数值
{
  int i;
  printf(" (");
  for(i=0;i<=s;i++)
     printf("%8.2f",x[i]);
  printf(")    ");
  for(i=0;i<=s;i++) Zm=Zm+c[i]*x[i];  //计算目标函数值
  if(type==1)
      printf("Zmax=%f\n\n",-Zm);
  else printf("Zmin=%f\n\n",Zm);
}

void PrintResult()  //输出最终结果
{
  if(type==1)printf("The Minimal:%f\n",-Zm);
  else printf("The Maximum:%f\n",Zm);
}

void Input(float b[],int code[])  //LP问题原始数据录入函数
{
  int i=0,j=0;
  printf(" 输入变量与约束方程的个数:");
     cin>>m>>n;
  for(i=0;i<n;i++)  //输入各方程的常数项、约束类型(<=,=,>=)、与变量系数
  {
     printf(" 输入第 %d 个方程常数项与约束类型 ( 0:<= 1:= 2:>= )\n  ",i+1);
       cin>>b[i]>>code[i];
     printf(" 方程各变量系数\n  ");
     for(j=0;j<m;j++)
	   cin>>matrix[i][j];
   }
  printf(" 问题的类型 ( 0:Min 1:Max ): ");  //LP问题的类型(极大化或极小化)
  do{
     cin>>type;
     if(type!=0&&type!=1) printf("Error,ReInput\n");
     }while(type!=0&&type!=1);
  printf(" 输入目标函数Z的系数:  "); //输入目标函数系数
  for(i=0;i<m;i++)
     cin>>c[i];
  if(type==1)  //若极大化转化为极小化
    for(i=0;i<m;i++)
       c[i]=-c[i];
}

void Sstart(float b[],int code[]) //根据约束类型,增加剩余变量、松弛变量与人工变量的信息
{
   int i,j;
   s=m-1; 
   indexe=indexl=indexg=0;
   for(i=0;i<n;i++)  
   {
     if(code[i]==2)  //处理剩余变量
	  {
	    indexg++;indexe++;s=s+2;rg[indexg]=s; //记录人工变量所处的列号
        for(j=0;j<n;j++)  
			if(i!=j) { matrix[j][s-1]=0; matrix[j][s]=0;}
			else { matrix[j][s-1]=-1; matrix[j][s]=1;}
	  }
	   

	 if(code[i]==0) //处理松弛变量
	 {
		 indexl++;s++; 
	     for(j=0;j<n;j++) 
		 {
			 if(i!=j)matrix[j][s]=0;
	         else matrix[j][s]=1; 
		 }
	 }

     if(code[i]==1) //处理人工变量
	 {
		 indexg++;s++;rg[indexg]=s; 
	     for(j=0;j<n;j++)    
	     if(i!=j)matrix[j][s]=0;
	      else matrix[j][s]=1;
	 }
	 a[i]=s;
	}
    for(i=m;i<=s;i++) c[i]=0; //对目标函数系数进行处理
    for(i=1;i<=indexg;i++)  c[rg[i]]=100;  //再对人工变量的系数进行处理
    //for(i=0;i<=s;i++) matrix[n][i]=c[i];  
	float sum;
    for(i=0;i<=s;i++)
	{   sum=0.0;
	  for(j=0;j<n;j++)
		  {sum+=matrix[j][i]*c[a[j]];}
       matrix[n][i]=c[i]-sum;
	}  //检验数行进行初始化
    InitPrint(); //输出初始单纯形表(头)
}

void Simplix()  //单纯形法
{
  int in,out,temp=0;
  while(1)
  {
    Jckxj();  //处理基本可行解
    in=RjMin(); //计算检验数及确定换入基
    Print();  //打印单纯形表
    Result();  //输出解与目标函数值
	if(matrix[n][in]>=0)   
	{
	       if(indexg!=0)JustArtificial(); //判断人工变量非零
	        PrintResult();  //打印最终结果
	        return;
	}
	printf("———————————————————————————————————\n");
    if(Check(in))  //判断无界解情况
	{
	  printf("No Delimition\n");
	  return;
	}
    out=SearchOut(&temp,in);  //求换出基
    MtoBe(temp,in);  //初等变换
    a[out]=in;  //调整基变量数组a[]的值
   } 
} 

void main()
{
  int code[M];  //约束方程类型标识数组
  Input(b,code);  //录入原始数据
  Sstart(b,code);  //化标准型
  Simplix();    //单纯形算法
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -