Factory maximum benefit - simple algorithm

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qq_44116998/article/details/102734251

Good luck, I studied operations research, mathematical modeling did not choose to, but I feel closer to operations research as a discipline optimization algorithms, I still prefer the following record is my first operations research use simple algorithms chapter in learning. Here not elaborate on the simple principle of algorithm, attach links ( Baidu Encyclopedia - Simple algorithm )


Bowen Reference "Fun learning algorithm" to achieve, only to learn to use, invasion deleted.


Simple arithmetic

Concept:
simplex method is an iterative algorithm, the main steps and its basic principle is: firstly try to find a (initial) group feasible solution, and then determine whether the optimal feasible solution to this group according to the optimal solution theory. If the optimal solution, then the output result, calculation is stopped; if not optimum, it managed to produce a new target better the current basic feasible solution feasible solution by re-using the optimal obtained new theory group feasible solution judge to see if the optimal solution, this constitutes an iterative algorithm. Since only a finite number of basic feasible solution, and each target have been improved, and thus will be terminated in limited steps. If the optimal solution of the original problem indeed, will be achieved within a limited step, and the amount of calculation than exhaustive; if no optimal solution of the original problem, but also to detect, according to the optimum stop counting theory, to avoid errors, and invalid operation.

Standard mathematical expression is as follows: ( picture from Baidu Encyclopedia )
Here Insert Picture Description


Title: (from the "Fun Science algorithm")
in a food processing plant, a total of three, the first plant raw material can be the N 1 processing unit 5 units 2 units of product A or product B. A direct product if sold, priced at 10 yuan, if the process continues in the second workshop, the need for additional processing fee $ 5, after processing is priced at 19 yuan. B If the product is directly sold, priced at 16 yuan, if the process continues in the third workshop, the need for additional processing fee $ 4, after processing is priced at 24 yuan. N unit purchase price of raw materials is 5 yuan per hours salary is $ 15, a processing unit of a first workshop N, required 0.05 hours, a second processing unit needs Drag 0.1 hours, a third processing unit needs workshop 0.08 hours. You can get up to 12,000 units per month of the raw material N, working hours up to 1000 hours. How to arrange the production, in order to make the plant the largest benefits of it?


1. The objective function and constraint conditions were as follows:
max Z = 10x1 + 16x3 + 12.5x2 + 18.8x4 - 5.75x5;
X3 + 4-2x5 = 0;
X5 ≤ 12000;
0.1x2 + 0.08x4 + 0.05x5 ≤ 1000;
XI ≥ 0 (i = 1,2,3, 4,5) ;
wherein
x1 represents the amount of product sold is a
x2 a represents product sold in a second amount after the processing plant
x3 B represents the amount of product sold
x4 product B represents in the sold amount after a third processing plant
x5 represents the number of the raw materials used in the first workshop

max z = 10x1 + 12.5x2 + 16x3 + 18.8x4 - 5.75x5;
represents a direct sold price + A

x1 + x2-5x5 = 0;
represents the number of products using the raw material A in the first total plant can be produced

x3 + x4-2x5 = 0;
represents a total amount of material that the use of the product B can be produced in the first workshop

x5 ≤ 12000
indicates the maximum value of the starting material

0.1x2 + 0.08x4 + 0.05x5 ≤ 1000;
represented by formula satisfies one hundred twenty-three hours in the workshop

2. converted to standard
max Z = 10x1 + 16x3 + 12.5x2 + 18.8x4 - 5.75x5;
X1 = 0 + x2-5x5;
X3 + x4-2x5 = 0;
X5 + X6 = 12000;
0.1x2 + 0.08x4 + X7 = 1000 + 0.05x5;
XI ≥ 0 (I = l, 2,3, 4,5,6,7)

3. Create simplex tableau
four expressions, requires four basic variables, view seen: x1, x3, x6, x7 as basis vectors
(x1, x3, x6, x7 );
represents the objective function may be a non-basic to give:
Z = 2.5x2 + 2.8x4, + 76.25x5;
in the simple table, the rows the variable group, nonbasic variables do columns, the number of tests to put the first line, the coefficient values as nonbasic variables, take the early initial simplex tableau;
Here Insert Picture Description
4 determines whether or not the optimal solution
1. if the number of inspection lines where c is less than zero, then the optimal solution is obtained;
2. if the presence of a number of promising positive test, but the positive column vector located the presence of each component is less than zero, then the problem solvable without boundaries;
3. If there is a positive number in the test number, and where the column vector with a positive value, then the calculation can be continued;

The variable group is selected from the
positive test a number of the largest number corresponding to the non-yl group variable variable xn, xn as the corresponding column group;

6. The variable selected from the group
smallest select "constant column element / group list of elements into" n ratio, nonbasic variables from the corresponding group of variables xm, xm corresponding to the group behavior from the line;

7. In other base change
in the group in the tableau variables xm and xn-yl conversion from variable position
Here Insert Picture Description
8. Create a new tableau
into Gilead = - original value / intersection values (not including the cross-position);
from the base line = original value / intersection values (not including the cross-position);
cross bits = taking the inverse of the original value;
cO = position + original value into peer group from the list of elements * column element from the base line / cross-bit value: 0 * 12 000 + 76.25 / 1 = 915,000;

Here Insert Picture Description
Here Insert Picture Description
= Original value in general position of the element - the peer group from the group column element row * column element / the same cross-bit value;
Here Insert Picture Description

9. The optimal solution is determined whether
, if not, proceed to step 5-8;
Analyzing have optimal solution, is less than the total number of tests equal to zero, thereby obtaining the optimal solution, c0 is the optimal solution, and the optimal solution is a group corresponding to the variable into which a constant, i.e. b columns where, nonbasic all take zero, to obtain a unique optimal solution basis vectors:
Here Insert Picture Description


Code

#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;
float kernel[100][100];//单纯形表
char FJL[100] = { };//非基变量
char JL[100] = { };//基变量
int n, m, i, j;
void Print()//输出单纯形表
{
	cout << "------------单纯形表如下------------" << endl;
	cout << "  ";
	cout << setw(7) << "b ";
	for (i = 1; i < n; i++)//非基变量输出
		cout << setw(7) << "x" << FJL[i];
	cout << endl;
	cout << "c ";
	for (i = 0; i <= n; i++)
	{
		if (i >= 1)
			cout << "x" << JL[i];
		for (j = 0; j <= m; j++)
			cout << setw(7) << kernel[i][j] << " ";
		cout << endl;
	}
	return;
}
void DCXA()
{
	float max1;//存放最大的检验数
	float max2;//存放最大正检验数对应的基变量的最大系数
	int e = -1;//记录入基列
	int k = -1;//记录离基行
	float min;
	while (true)//循环迭代,直到找到问题的解或者无解为止
	{
		max1 = 0;
		max2 = 0;
		min = 100000000;
		for (j = 1; j <= m; j++)//找入基列
		{
			if (max1 < kernel[0][j])
			{
				max1 = kernel[0][j];
				e = j;
			}
		}
		if (max1 <= 0)//最大值<=0
		{
			cout << endl;
			cout << "获得最优解: " << kernel[0][0] << endl;
			for(i = 1 ;i <= n;i++)
				cout<<"x"<<JL[i]<<"="<<kernel[i][0]<<"  "; 
			cout<<"其余变量为零"<<endl; 
			break;
			}
		for (j = 1; j <= m; j++)//判断检验数对应列的如果都小于等于零,则无解
		{
			max2 = 0;
			if (kernel[0][j] > 0)
			{
				for (i = 1; i <= n; i++)//正检验数所对应列
					if (max2 < kernel[i][j])
						max2 = kernel[i][j];
				if (max2 <= 0)
				{
					cout << "解无界" << endl;
					return;
				}
			}
		}
		for (i = 1; i <= n; i++)//找离基行
		{
			float temp = kernel[i][0] / kernel[i][e];
			if (temp > 0 && temp < min)
			{
				min = temp;
				k = i;
			}
		}
		cout << "入基变量 " << "x" << FJL[e] << " ";
		cout << "出基变量 " << "x" << JL[k] << " "<<endl<<endl;
		char temp = FJL[e];//变基变换
		FJL[e] = JL[k];
		JL[k] = temp;
		for (i = 0; i <= n; i++)//计算除入基列和出基行的所有位置的元素
		{
			if (i != k)
			{
				for (j = 0; j <= m; j++)
				{
					if (j != e)
					{
						if (i == 0 && j == 0)//特殊位置c0
							kernel[i][j] = kernel[i][j] + kernel[i][e] * kernel[k][j] / kernel[k][e];
						else//一般位置
							kernel[i][j] = kernel[i][j] - kernel[i][e] * kernel[k][j] / kernel[k][e];
					}
				}
			}
		}
		for (i = 0; i <= n; i++)//入基列元素
		{
			if (i != k)
				kernel[i][e] = -kernel[i][e] / kernel[k][e];
		}
		for (j = 0; j <= m; j++)//离基行元素
		{
			if (j != e)
				kernel[k][j] = kernel[k][j] / kernel[k][e];
		}
		kernel[k][e] = 1 / kernel[k][e];//交叉位置取倒数
		Print();
	}
	return;
}
int main()
{
	cout << "请输入非基变量个数和非基变量的下标:" << endl;
	cin >> m;
	for (i = 1; i <= m; i++)
		cin >> FJL[i];
	cout << "请输入基变量个数和基变量的下标:" << endl;
	cin >> n;
	for (i = 1; i <= n; i++)
		cin >> JL[i];
	cout << "输入约束标准型初始单纯形表的参数:" << endl;
	for (i = 0; i <= n; i++)
	{
		for (j = 0; j <= m; j++)
			cin >> kernel[i][j];
	}
	Print();
	DCXA();
	system("pause");
	return 0;
}

running result
Here Insert Picture Description

Guess you like

Origin blog.csdn.net/qq_44116998/article/details/102734251