C语言实现单纯形法与对偶单纯形法

C语言实现单纯行法与对偶单纯行法

某次为了完成课程要求所做:
单纯形法代码如下,使用方法修改二位数组A[ip][jp],

#include<stdio.h>
#define ip 3
#define jp 7
int i,j,m,n,flag=1;
float max=-1,min=1000,guiyi;
float C[jp-1]={-100,-100,100,0,0,0};
float A[ip][jp]={{1,1,2,1,0,0,-1},{1,1,-1,0,1,0,-1},{-1,1,1,0,0,1,-1}};
float X[ip]={0,0,0};
float zc[jp-1]={0};
int ji[ip]={3,4,5};//第3、4、5为4.5.6前系数 
void show();
void jinji();
void chuji();
void trans();
void show_result();
int main()
{char c; 
	//初始矩阵显示 
	show();
	//计算矩阵的判别数	记录大于0的最大的判别数  确认进基变量 
	jinji();
	
while(flag==1)
{
	//确认出基变量
	chuji(); 
	//初等行变换	
	trans();
	//初等行变换后结果 
	show();	
	//计算矩阵的判别数	记录大于0的最大的判别数  确认进基变量 
	jinji();
	flag=0;
	for(j=0;j<jp-1;j++)
	{
	if(zc[j]>0)
	flag=1;
	}
}
show_result();
c=getchar();
	return 0; 
}
void show()
{
	
	printf("     ") ;
	for(j=0;j<jp-1;j++)//显示x1~x6 
	{
		printf("x%d    ",j+1);
	}
	printf("\n");
	for(i=0;i<ip;i++)
	{
		printf("x%d  ",ji[i]+1);
		for(j=0;j<jp;j++)
		{
			if(A[i][j]>=0)
			printf(" ");
			printf("%.2f ",A[i][j]);
		}
		printf("\n");
	}
}

void jinji()
{max=-1; 
	printf("Z-C ");
	for(j=0;j<jp-1;j++)
	{
		zc[j]=0;
		for(i=0;i<ip;i++)
		zc[j]=C[ji[i]]*A[i][j]+zc[j];
		zc[j]=zc[j]-C[j];
			if(zc[j]>=0)
			{
				{
					if(zc[j]>max)
					{
					max=zc[j];
					m=j;
					}
				printf(" ");
				}	
			}
			printf("%.2f ",zc[j]);
	}
	printf("%d\n",m);
}

void chuji()
{min=1000;
	for(i=0;i<ip;i++)
	if(A[i][m]>0)
	{
		if(A[i][jp-1]/A[i][m]<min)
		min=A[i][jp-1]/A[i][m];
		n=i;
	}
	printf("%d",n);
}

void trans()
{
	guiyi=1.0/A[n][m];
	for(j=0;j<jp;j++)
	A[n][j]=A[n][j]*guiyi;
	float tem[ip];
	//保留矩阵A中行变换需要归零的列 
	for(i=0;i<ip;i++)
	{
		tem[i]=A[i][m];
	 } 
	for(i=0;i<ip;i++)
	{
		if(i!=n)//保留用于变换的行,否则会被归零 
		for(j=0;j<jp;j++)
		{
			A[i][j]=A[i][j]-A[n][j]*tem[i];
		}
	}
	//改变基
	ji[n]=m;//矩阵是从0开始的
	
}

void show_result()
{
	for(n=0;n<ip;n++)
	{
		printf("%d",ji[n]);
		if(ji[n]<3)
		X[ji[n]]=A[n][jp-1];
	}
	printf("\n(x1,x2,x3)=(%.2f,%.2f,%.2f)",X[0],X[1],X[2]);
	printf("最优解为%f",C[0]*X[0]+C[1]*X[1]+C[2]*X[2]);
}

对偶单纯形法

#include<stdio.h>
#define ip 4
#define jp 8
int i,j,m,n,flag=1;
float min=0,guiyi;
float C[jp-1]={1,1,-4,0,0,0};
float A[ip][jp]={
					{ 1, -1.0/3,    0,  1.0/3,    0,  -2.0/3,    0,   1.0/3},
					{ 0,      2,    0,      0,    1,       1,    0,       6},
					{ 0,  2.0/3,    1,  1.0/3,    0,   1.0/3,    0,  13.0/3},
					{-3,      1,    6,      0,    0,       0,    1,      17}
				};
float X[3]={1.0/3,0,13.0/3};//原先最优解 
float zc[jp-1]={0};//检验数 
int ji[ip]={0,4,2,6};//基
void show();
void jinji();
void chuji();
void trans();
void trans_init();
void show_result();
int main()
{char c;//用于暂停
	for(j=0;j<3;j++)
	{
		min=A[ip-1][j]*X[j]+min;
	}
	if(min>A[ip-1][jp-1]) 	
		{
			printf("新增条件改变了原有最优解\n"); 
			show();
			trans_init();
			show();
			chuji();
			jinji();
			while(flag==1)
			{
				trans();
				show();
				chuji();
				jinji();
				flag=0;//假设全大于0 
				for(i=0;i<ip;i++)
				if(A[i][jp-1]<0)//只要有b小于0继续循环 
				flag=1;
			}
			
			show_result();//至此单纯形法结束 
		}
	else
	{
		printf("最优解未变"); 
		show_result();
	}
	min=0;
	c=getchar(); //暂停一下 
	return 0; 
}
void show()
{
	
	printf("     ") ;
	for(j=0;j<jp-1;j++)//显示x1~x6 
	{
		printf("x%d    ",j+1);
	}
	printf("\n");
	for(i=0;i<ip;i++)
	{
		printf("x%d  ",ji[i]+1);
		for(j=0;j<jp;j++)
		{
			if(A[i][j]>-0.01)
			printf(" ");
			printf("%.2f ",A[i][j]);
		}
		printf("\n");
	}
}

void jinji()
{
	printf("Z-C ");
	for(j=0;j<jp-1;j++)
	{
		zc[j]=0;
		for(i=0;i<ip;i++)
		zc[j]=C[ji[i]]*A[i][j]+zc[j];
		zc[j]=zc[j]-C[j];
			if(zc[j]>=0)
			{
				printf(" ");
			}
			printf("%.2f ",zc[j]);
	}
	printf("\n");
	min=0;
	for(j=0;j<jp-1;j++)
	{
		if((A[n][j]<0)&&(A[n][j]<min))
		{	
		min=zc[j]/A[n][j];
		m=j;
		}
	}
//	printf("%d",m);
}

void chuji()
{min=0;
	for(i=0;i<ip;i++)
	if(A[i][jp-1]<min)
	{
		min=A[i][jp-1];
		n=i;
	}
//	printf("%d",n);
}
void trans_init()
{
float tem[ip-1];
	for(i=0;i<ip-1;i++)
	{
		if(A[ip-1][ji[i]]!=0)
		tem[i]=A[ip-1][ji[i]];	
	}
	for(i=0;i<ip-1;i++)
	{for(j=0;j<jp;j++)
		{
			A[ip-1][j]=A[ip-1][j]-tem[i]*A[ji[i]][j];
		}
	}
}
void trans()
{
	guiyi=1.0/A[n][m];
	for(j=0;j<jp;j++)
	{
		A[n][j]=A[n][j]*guiyi;
		if(A[n][j]==-0.0)//修正bug 
		A[n][j]=0.0;
	}
	
	float tem[ip];
	//保留矩阵A中行变换需要归零的列 
	for(i=0;i<ip;i++)
	{
		tem[i]=A[i][m];
	 } 
	for(i=0;i<ip;i++)
	{
		if(i!=n)//保留用于变换的行,否则会被归零 
		for(j=0;j<jp;j++)
		{
			A[i][j]=A[i][j]-A[n][j]*tem[i];
		}
	}
	//改变基
	ji[n]=m;//矩阵是从0开始的
	
}

void show_result()
{
	for(n=0;n<ip;n++)
	{
	//	printf("%d",ji[n]);
		if(ji[n]<3)
		X[ji[n]]=A[n][jp-1];
	}
	printf("\n(x1,x2,x3)=(%.2f,%.2f,%.2f)",X[0],X[1],X[2]);
	printf("最优解为%f",C[0]*X[0]+C[1]*X[1]+C[2]*X[2]);
}
发布了10 篇原创文章 · 获赞 0 · 访问量 460

猜你喜欢

转载自blog.csdn.net/KEY_Init/article/details/103260538
今日推荐