最优化理论—单纯形法的C++实现(大M法)

#include<iostream>
#include<vector>
#include<string>
using namespace std;             //大M法   输入时 110代表>=  101代表<=  111代表= 
#define M 100000                 /* 输入格式   eg: 3X(1)+2X(2)-X(3)<=20  -->  3 1 2 2 -1 3 101 20
                               数字之间加空格,每输一行回车进入下一行,结束时 回车进入新行按ctrl+z 再回车 
								eg:	题1输入  
									min 3 1 2.5 2
									2 1 4 2 110 40
									3 1 2 2 110 50     
								*/
float Get_Cb(vector<float> &v,float k){
	for(int i=2;i<v.size();){
		if(v[i]==k)
			return v[i-1];                               
		i+=2;
	}
	return 0;
}

vector<float> Input_f(){
	vector<float> v;
	string s;
	float n;
	cin>>s;
	if(s=="max")
		v.push_back(0); 
	else if(s=="min")
		v.push_back(1); 
	getchar();
	while(cin>>n){
		v.push_back(n);
		if(getchar()=='\n')
			break; 
	}
	return v;
}

float** Input_st(vector<float> &v,int* Data){
	vector<vector<float>> vec;
	int l=0,max=0;
	float n;
	int GreaterThan_sign=0;
	int Equal_sign=0;
	vector<float> r;
	while(cin>>n){
		if(n!=0){
			if(n==101 || n==110 || n==111){
				if(n==110)
					GreaterThan_sign++;
				if(n==111)
					Equal_sign++;
				if(r[l-1]>max)
					max=r[l-1];
			}
			r.push_back(n);
			l++;
		}
		if(getchar()=='\n'){
			vec.push_back(r);
			vector<float> temp;
			r=temp;
			l=0;
		}
	}
	int row=vec.size()+1;
	int column=max+vec.size()+GreaterThan_sign+2;
	float** array;
	array=(float**)malloc(sizeof(float*)*row);
	for(int i=0;i<row;i++){
		array[i]=(float*)malloc(sizeof(float)*column);
		for(int j=0;j<column;j++)
			array[i][j]=0; 
	} 
	int mark=1,mark2=0;
	for(int i=0;i<vec.size();i++){
		for(int j=0;j<vec[i].size();){
			if(vec[i][j]==101 || vec[i][j]==110 ||vec[i][j]==111){
				if(vec[i][j]==101){
					array[i][max+1+mark2]=1;
					array[i][column-1]=vec[i][j+1];
					array[i][0]=max+1+i;
					mark2++;
					break;
				}else if(vec[i][j]==110){
					array[i][max+1+mark2]=-1;
					array[i][max+vec.size()-Equal_sign+mark]=1;
					v.push_back(M);
					v.push_back(max+vec.size()-Equal_sign+mark);
					array[i][0]=max+vec.size()-Equal_sign+mark;
					mark++,mark2++;
					array[i][column-1]=vec[i][j+1];  
					break;
				}else if(vec[i][j]==111){
					array[i][max+vec.size()-Equal_sign+mark]=1;
					v.push_back(M);
					v.push_back(max+vec.size()-Equal_sign+mark);
					array[i][0]=max+vec.size()-Equal_sign+mark;
					mark++;
					array[i][column-1]=vec[i][j+1]; 
					break;	
				}
			}
			else{
				array[i][(int)vec[i][j+1]]=vec[i][j];
				j+=2;
			}
		}
	}
	array[row-1][0]=max+vec.size()-Equal_sign;
	for(int i=1;i<column-1;i++){
		for(int j=0;j<row-1;j++)
			array[row-1][i]+=Get_Cb(v,array[j][0])*array[j][i];
		array[row-1][i]=array[row-1][i]-Get_Cb(v,i);
	}
	for(int i=0;i<row-1;i++)
		array[row-1][(int)array[i][0]]=0;
	for(int i=0;i<row-1;i++)
		array[row-1][column-1]+=Get_Cb(v,array[i][0])*array[i][column-1];
	Data[0]=row;
	Data[1]=column; 
			for(int i=0;i<row;i++){                //输出矩阵 
				for(int j=0;j<column;j++)
					cout<<array[i][j]<<' ';
				cout<<endl;
			}
			cout<<endl;	
	return array;
}

int Get_min(float* b,int k){
	int min=b[1];
	int i=2;
	int temp=1;
	while(i<=k){
		if(b[i]<min){
			min=b[i];
			temp=i;
		}
		i++;
	}
	return temp;
}
int Get_max(float* b,int k){
	int max=b[1];
	int i=2;
	int temp=1;
	while(i<=k){
		if(b[i]>max){
			max=b[i];
			temp=i;
		}
		i++;
	}
	return temp;
}

float** Eliminate(float** array,int r,int t,int row,int column){
	float s=array[r][t];
	for(int i=1;i<column;i++){
		array[r][i]=array[r][i]/s;
	}
	for(int i=0;i<row;i++){
		float k=array[i][t];
		if(i!=r)
			for(int j=1;j<column;j++){
				array[i][j]=array[i][j]-k*array[r][j];
			}
	}
	return array;
}

void Print(float** array,vector<float> &v,int row,int column){
	int s=array[row-1][0];
	float a[s]={};
	for(int i=0;i<row-1;i++){
		a[(int)array[i][0]-1]=array[i][column-1];
	}
	cout<<"最优可行解X=(";
	for(int i=0;i<s;i++){
		cout<<"x"<<i+1;
		if(i!=s-1)
			cout<<",";
	}
	cout<<")"<<"=(";
	for(int i=0;i<s;i++){
		cout<<a[i];
		if(i!=s-1)
			cout<<",";
	}
	cout<<")"<<endl;
	if(v[0]==1)
		cout<<"最小值f(min)="<<array[row-1][column-1]<<endl;
	else cout<< "最大值f(max)="<<array[row-1][column-1]<<endl;
}

void Function(float** array,vector<float> &v,int* Data){
	int row=Data[0];
	int column=Data[1];
	if(v[0]==1){
		if(array[row-1][Get_max(array[row-1],(int)array[row-1][0])]<=0){
			Print(array,v,row,column);
		}else{
			int k=Get_max(array[row-1],(int)array[row-1][0]);
			float min=M,m;
			int temp=-1;
			for(int i=0;i<row-1;i++){
				if(array[i][k]>0){
					m=array[i][column-1]/array[i][k];
					if(m<min){
						min=m;
						temp=i;
					}
				}
			}
			if(temp==-1){
				cout<<"无可行解";
				exit(0); 
			}else{
				array=Eliminate(array,temp,k,row,column);
				array[temp][0]=k;
			}	
			for(int i=0;i<row;i++){                //输出矩阵 
				for(int j=0;j<column;j++)
					cout<<array[i][j]<<' ';
				cout<<endl;
			}
			cout<<endl;		
			Function(array,v,Data);	
		}
	}else if(v[0]==0){
		if(array[row-1][Get_min(array[row-1],(int)array[row-1][0])]>=0){
			Print(array,v,row,column);
		}else{
			int k=Get_min(array[row-1],(int)array[row-1][0]);
			float min=M,m;
			int temp=-1;
			for(int i=0;i<row-1;i++){
				if(array[i][k]>0){
					m=array[i][column-1]/array[i][k];
					if(m<min){
						min=m;
						temp=i;
					}
				}
			}
			if(temp==-1){
				cout<<"无可行解";
				exit(0); 
			}else{
				array=Eliminate(array,temp,k,row,column);
				array[temp][0]=k;
			}	
			for(int i=0;i<row;i++){                //输出矩阵 
				for(int j=0;j<column;j++)
					cout<<array[i][j]<<' ';
				cout<<endl;
			}
			cout<<endl;		
			Function(array,v,Data);	
		}
	}
}

void LP(){
	int a[2]={};
	vector<float> v=Input_f();
	float** array=Input_st(v,a);
	Function(array,v,a);
}

int main(){
	LP();
}
题1输入
min 3 1 2.5 2
2 1 4 2 110 40
3 1 2 2 110 50

题2输入
min -2 1 -3 2 
1 1 -1 2 1 3 111 2
-3 1 1 2 1 4 111 4

题3输入
max 5 1 2 2
30 1 20 2 101 160
5 1 1 2 101 15
1 1 101 5

题4输入
max 0.375 1 0.302 2 0.4 3 0.401 4 0.328 5 0.426 6 0.65 7 0.862 8 0.684 9
5 1 5 2 5 3 10 7 101 6000
7 4 7 5 7 6 9 8 12 9 101 10000
6 1 6 4 8 7 8 8 101 4000
4 2 4 5 11 9 101 7000
7 3 7 6 101 4000

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值