Библиографический список
1. Аттетков А.В. Методы оптимизации: учеб. для вузов / А.В. Аттетков, С.В. Галкин, В.С. Зарубин. М.: Изд-во МГТУ им. Н.Э. Баумана, 2003. 440 с.
2. Пантелеев А.В. Методы оптимизации в примерах и задачах: учеб. пособие/ А.В. Пантелеев, Т.А. Летова. М.: Высш. шк., 2002.
3. Математические методы в исследовании операций: Сб. статей / Под ред. Н.Н. Моисеева. М.: Изд-во MГУ, 1981.
4. Черногородова Г.М. Методы оптимизации: учеб. пособие/ Г.М. Черногородова. Ч.1. Екатеринбург: УГТУ, 2000. 80 с.
5 Черногородова Г.М. Теория принятия решений: учеб. пособие/ Г.М. Черногородова. Екатеринбург: УГТУ-УПИ, 2006. 183 с.
6 Черногородова Г.М. Методы оптимизации. Нелинейное программирование: учеб. пособие /Г.М. Черногородова. Екатеринбург: УГТУ-УПИ, 2007. 113 с.
Приложение
Программа Simlex-Oil
---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "sGroupBox"
#pragma link "sSkinManager"
#pragma link "sSkinProvider"
#pragma link "sStatusBar"
#pragma link "sEdit"
#pragma link "sButton"
#pragma link "sLabel"
#pragma link "sMemo"
#pragma resource "*.dfm"
TForm1 *Form1;
---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N2Click(TObject *Sender)
{
Application->Terminate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::sButton1Click(TObject *Sender)
{
//Защита от дурака
if (!Edit00->Text.Compare("") || !Edit01->Text.Compare("") || !Edit02->Text.Compare("") || !Edit03->Text.Compare("") || !Edit10->Text.Compare("") || !Edit11->Text.Compare("") || !Edit12->Text.Compare("") || !Edit13->Text.Compare("") || !Edit20->Text.Compare("") || !Edit21->Text.Compare("") || !Edit22->Text.Compare("") || !Edit23->Text.Compare("") || !Edit30->Text.Compare("") || !Edit31->Text.Compare("") || !Edit32->Text.Compare("") || !Edit33->Text.Compare("") || !Edit40->Text.Compare("") || !Edit41->Text.Compare("") || !Edit42->Text.Compare("") || !Edit43->Text.Compare("") || !Edit001->Text.Compare("") || !Edit101->Text.Compare("") || !Edit201->Text.Compare("") || !Edit301->Text.Compare("") || !Edit401->Text.Compare("") || !Edit011->Text.Compare("") || !Edit111->Text.Compare("") || !Edit211->Text.Compare("") || !Edit311->Text.Compare("") || !Edit411->Text.Compare("") || !Edit021->Text.Compare("") || !Edit121->Text.Compare("") || !Edit221->Text.Compare("") || !Edit321->Text.Compare("") || !Edit421->Text.Compare("")) {
ShowMessage("Не все поля заполнены");
}
else {
Edit04->Text=Edit00->Text;
Edit14->Text=Edit10->Text;
Edit24->Text=Edit20->Text;
Edit34->Text=Edit30->Text;
Edit44->Text=Edit40->Text;
//Расчет для первой задачи
int tmpI, tmpJ, tmpX, tmpY, tmpP;
float tmp, Price1;
float Mat[5][5], Mat1[5][5], Mat2[5][5];
// заполнение матрицы для первой задачи
for (tmpX=0; tmpX<=4; tmpX++)
for (tmpY=0; tmpY<=4; tmpY++)
Mat[tmpX][tmpY]=0;
Mat[0][0]=StrToFloat(Edit00->Text);
Mat[0][1]=StrToFloat(Edit01->Text);
Mat[0][2]=StrToFloat(Edit02->Text);
Mat[0][3]=StrToFloat(Edit03->Text);
Mat[0][4]=StrToFloat(Edit04->Text);
Mat[1][0]=StrToFloat(Edit10->Text);
Mat[1][1]=StrToFloat(Edit11->Text);
Mat[1][2]=StrToFloat(Edit12->Text);
Mat[1][3]=StrToFloat(Edit13->Text);
Mat[1][4]=StrToFloat(Edit14->Text);
Mat[2][0]=StrToFloat(Edit20->Text);
Mat[2][1]=StrToFloat(Edit21->Text);
Mat[2][2]=StrToFloat(Edit22->Text);
Mat[2][3]=StrToFloat(Edit23->Text);
Mat[2][4]=StrToFloat(Edit24->Text);
Mat[3][0]=StrToFloat(Edit30->Text);
Mat[3][1]=StrToFloat(Edit31->Text);
Mat[3][2]=StrToFloat(Edit32->Text);
Mat[3][3]=StrToFloat(Edit33->Text);
Mat[3][4]=StrToFloat(Edit34->Text);
Mat[4][0]=StrToFloat(Edit40->Text);
Mat[4][1]=StrToFloat(Edit41->Text);
Mat[4][2]=StrToFloat(Edit42->Text);
Mat[4][3]=StrToFloat(Edit43->Text);
Mat[4][4]=StrToFloat(Edit44->Text);
//Находим среди отрицательных элементов максимальное по модулю
tmp=0;
tmpP=0;
for (tmpX=0; tmpX<=4; tmpX++)
if (Mat[tmpX][4]<0)
if (fabs(tmp)<fabs(Mat[tmpX][4]))
{
tmp=Mat[tmpX][4];
tmpP=tmpX;
}
//В столце находим минимальный элемент
tmp=100;
tmpX=tmpP;
for (tmpY=0; tmpY<=4; tmpY++)
{
if ((Mat[tmpX][tmpY]!=0)&&(tmpY!=3))
if (Mat[0][tmpY]/Mat[tmpX][tmpY]<tmp)
{
tmp=Mat[0][tmpY]/Mat[tmpX][tmpY];
tmpP=tmpY;
}
}
//Делим на получившийся главный элемент
tmpY=tmpP;
for (int i = 0; i <= 4; i++)
for (int j=0; j <= 4; j++)
Mat1[i][j]=Mat[i][j];
tmp=Mat[tmpX][tmpY];
for (tmpP=0; tmpP<=4; tmpP++)
Mat1[tmpX][tmpP]=Mat1[tmpX][tmpP]/tmp;
for (tmpP=0; tmpP<=4; tmpP++)
Mat1[tmpP][tmpY]=Mat1[tmpP][tmpY]/tmp;
switch (tmpY) {
case 0: {
X5->Caption="X"+IntToStr(tmpX);
switch (tmpX) {
case 1: X1->Caption="X5"; break;
case 2: X2->Caption="X5"; break;
case 3: X3->Caption="X5"; break;
case 4: X4->Caption="X5"; break;
}
}; break;
case 1: {
X6->Caption="X"+IntToStr(tmpX);
switch (tmpX) {
case 1: X1->Caption="X6"; break;
case 2: X2->Caption="X6"; break;
case 3: X3->Caption="X6"; break;
case 4: X4->Caption="X6"; break;
}
}; break;
case 2: {
X7->Caption="X"+IntToStr(tmpX);
switch (tmpX) {
case 1: X1->Caption="X7"; break;
case 2: X2->Caption="X7"; break;
case 3: X3->Caption="X7"; break;
case 4: X4->Caption="X7"; break;
}
}; break;
}
Mat1[tmpX][4]=Mat1[tmpX][4]*(-1);
for (tmpI=0; tmpI<=4; tmpI++)
for (tmpJ=0; tmpJ<=4; tmpJ++)
if ((tmpI!=tmpX)&&(tmpJ!=tmpY) )
{
Mat1[tmpI][tmpJ]=Mat[tmpI][tmpJ]-(Mat[tmpX][tmpJ]*Mat[tmpI][tmpY])/tmp;
}
//*********************************************************
//поиск оптимального решения
for (int i = 0; i <= 4; i++)
for (int j=0; j <= 4; j++)
Mat2[i][j]=Mat1[i][j];
sMemo1->Lines->Add("Задача №1.");
sMemo1->Lines->Add("Опорное решение:");
sMemo1->Lines->Add(X5->Caption+"="+FloatToStr(Mat2[0][0])+" "+X6->Caption+"="+FloatToStr(Mat2[0][1])+" "+X7-
>Caption+"="+FloatToStr(Mat2[0][2]));
sMemo1->Lines->Add("f(x)="+FloatToStr(Mat2[0][3]));
tmp=0;
tmpP=0;
for (tmpX=0; tmpX<=4; tmpX++)
if (Mat1[tmpX][3]<0)
if (fabs(tmp)<fabs(Mat1[tmpX][3]))
{
tmp=Mat1[tmpX][3];
tmpP=tmpX;
}
//ShowMessage(FloatToStr(tmp)+" "+IntToStr(tmpP));
//В столбце находим минимальный элемент
tmp=400;
tmpX=tmpP;
tmpJ=tmpY;
for (tmpY=0; tmpY<=2; tmpY++)
{
if ((Mat1[tmpX][tmpY]!=0) && (tmpY!=tmpJ) )
if (Mat1[0][tmpY]/Mat1[tmpX][tmpY]<tmp )
{
tmp=Mat1[0][tmpY]/Mat1[tmpX][tmpY];
tmpP=tmpY;
}
}
//ShowMessage(FloatToStr(tmp)+" "+IntToStr(tmpP));
//Делим на получившийся элемент
tmpY=tmpP;
for (int i = 0; i <= 4; i++)
for (int j=0; j <= 4; j++)
Mat2[i][j]=Mat1[i][j];
tmp=Mat1[tmpX][tmpY];
for (tmpP=0; tmpP<4; tmpP++)
Mat2[tmpP][tmpY]=Mat2[tmpP][tmpY]/tmp;
for (tmpP=0; tmpP<3; tmpP++)
Mat2[tmpX][tmpP]=Mat2[tmpX][tmpP]/tmp;
switch (tmpY) {
case 0: {
X5->Caption="X"+IntToStr(tmpX);
switch (tmpX) {
case 1: X1->Caption="X5"; break;
case 2: X2->Caption="X5"; break;
case 3: X3->Caption="X5"; break;
case 4: X4->Caption="X5"; break;
}
}; break;
case 1: {
X6->Caption="X"+IntToStr(tmpX);
switch (tmpX) {
case 1: X1->Caption="X6"; break;
case 2: X2->Caption="X6"; break;
case 3: X3->Caption="X6"; break;
case 4: X4->Caption="X6"; break;
}
}; break;
case 2: {
X7->Caption="X"+IntToStr(tmpX);
switch (tmpX) {
case 1: X1->Caption="X7"; break;
case 2: X2->Caption="X7"; break;
case 3: X3->Caption="X7"; break;
case 4: X4->Caption="X7"; break;
}
}; break;
}
Mat2[tmpX][3]=Mat2[tmpX][3]*(-1);
//вывод получившегося решения
for (tmpI=0; tmpI<=4; tmpI++)
for (tmpJ=0; tmpJ<=4; tmpJ++)
if ((tmpI!=tmpX)&&(tmpJ!=tmpY) )
{
Mat2[tmpI][tmpJ]=Mat1[tmpI][tmpJ]-(Mat1[tmpX][tmpJ]*Mat1[tmpI][tmpY])/tmp;
}
Mat2[1][3]=Mat2[1][3]*(-1);
sMemo1->Lines->Add("Оптимальное решение:");
sMemo1->Lines->Add(X5->Caption+"="+FloatToStr(Mat2[0][0])+" "+X6->Caption+"="+FloatToStr(Mat2[0][1])+" "+X7->Caption+"="+FloatToStr(Mat2[0][2]));
sMemo1->Lines->Add("f(x)="+FloatToStr(Mat2[0][3]));
Edit00->Text=FloatToStr(Mat2[0][0]);
Edit01->Text=FloatToStr(Mat2[0][1]);
Edit02->Text=FloatToStr(Mat2[0][2]);
Edit03->Text=FloatToStr(Mat2[0][3]);
Edit04->Text=FloatToStr(Mat2[0][4]);
Edit10->Text=FloatToStr(Mat2[1][0]);
Edit11->Text=FloatToStr(Mat2[1][1]);
Edit12->Text=FloatToStr(Mat2[1][2]);
Edit13->Text=FloatToStr(Mat2[1][3]);
Edit14->Text=FloatToStr(Mat2[1][4]);
Edit20->Text=FloatToStr(Mat2[2][0]);
Edit21->Text=FloatToStr(Mat2[2][1]);
Edit22->Text=FloatToStr(Mat2[2][2]);
Edit23->Text=FloatToStr(Mat2[2][3]);
Edit24->Text=FloatToStr(Mat2[2][4]);
Edit30->Text=FloatToStr(Mat2[3][0]);
Edit31->Text=FloatToStr(Mat2[3][1]);
Edit32->Text=FloatToStr(Mat2[3][2]);
Edit33->Text=FloatToStr(Mat2[3][3]);
Edit34->Text=FloatToStr(Mat2[3][4]);
Edit40->Text=FloatToStr(Mat2[4][0]);
Edit41->Text=FloatToStr(Mat2[4][1]);
Edit42->Text=FloatToStr(Mat2[4][2]);
Edit43->Text=FloatToStr(Mat2[4][3]);
Edit44->Text=FloatToStr(Mat2[4][4]);
Price1=Mat2[0][3];
//Расчет для второй задачи
for (tmpX=0; tmpX<=4; tmpX++)
for (tmpY=0; tmpY<=2; tmpY++)
Mat[tmpX][tmpY]=0;
Mat[0][0]=StrToFloat(Edit001->Text);
Mat[0][1]=StrToFloat(Edit011->Text);
Mat[0][2]=StrToFloat(Edit021->Text);
Mat[1][0]=StrToFloat(Edit101->Text);
Mat[1][1]=StrToFloat(Edit111->Text);
Mat[1][2]=StrToFloat(Edit121->Text);
Mat[2][0]=StrToFloat(Edit201->Text);
Mat[2][1]=StrToFloat(Edit211->Text);
Mat[2][2]=StrToFloat(Edit221->Text);
Mat[3][0]=StrToFloat(Edit301->Text);
Mat[3][1]=StrToFloat(Edit311->Text);
Mat[3][2]=StrToFloat(Edit321->Text);
Mat[4][0]=StrToFloat(Edit401->Text);
Mat[4][1]=StrToFloat(Edit411->Text);
Mat[4][2]=StrToFloat(Edit421->Text);
//Находим среди отрицательных максимальное по модулю
tmp=0;
tmpP=0;
for (tmpX=0; tmpX<=4; tmpX++)
if (Mat[tmpX][2]<0)
if (fabs(tmp)<fabs(Mat[tmpX][2])) {
tmp=Mat[tmpX][2];
tmpP=tmpX;
}
//В столбце находим минимальный элемент
tmp=100;
tmpX=tmpP;
for (tmpY=0; tmpY<=1; tmpY++)
{
if (Mat[tmpX][tmpY]!=0)
if (Mat[0][tmpY]/Mat[tmpX][tmpY]<tmp)
{
tmp=Mat[0][tmpY]/Mat[tmpX][tmpY];
tmpP=tmpY;
}
}
//Делим на получившийся главный элемент
tmpY=tmpP;
for (int i = 0; i <= 4; i++)
for (int j=0; j <= 4; j++)
Mat1[i][j]=Mat[i][j];
for (tmpP=0; tmpP<= 2; tmpP++)
tmp=Mat[tmpX][tmpY];
Mat1[tmpX][tmpP]=Mat1[tmpX][tmpP]/tmp;
for (tmpP=0; tmpP<= 4; tmpP++)
Mat1[tmpP][tmpY]=Mat1[tmpP][tmpY]/tmp;
switch (tmpY){
case 0: {
X51->Caption="X"+IntToStr(tmpX);
switch (tmpX) {
case 1: X11->Caption="X5"; break;
case 2: X21->Caption="X5"; break;
case 3: X31->Caption="X5"; break;
case 4: X41->Caption="X5"; break;
}
}; break;
case 1: {
X61->Caption="X"+IntToStr(tmpX);
switch (tmpX) {
case 1: X11->Caption="X6"; break;
case 2: X21->Caption="X6"; break;
case 3: X31->Caption="X6"; break;
case 4: X41->Caption="X6"; break;
}
} break;
}
Mat1[tmpX][2]=Mat1[tmpX][2]*(-1);
for (tmpI=0; tmpI<=4; tmpI++)
for (tmpJ=0; tmpJ<=2; tmpJ++)
if ((tmpI!=tmpX)&&(tmpJ!=tmpY))
{
Mat1[tmpI][tmpJ]=Mat[tmpI][tmpJ]-(Mat[tmpX][tmpJ]*Mat[tmpI][tmpY])/tmp;
}
//Вывод базового решения.
for (int i = 0; i <= 4; i++)
for (int j=0; j <= 4; j++)
Mat2[i][j]=Mat1[i][j];
sMemo1->Lines->Add("Задача №2.");
sMemo1->Lines->Add("Опорное решение:");
sMemo1->Lines->Add(X51->Caption+"="+FloatToStr(Mat2[0][0])+" "+X61->Caption+"="+FloatToStr(Mat2[0][1]));
sMemo1->Lines->Add("f(x)="+FloatToStr(Mat2[0][2]));
//*********************************************************
// поиск оптимального решения
tmp=0;
tmpP=0;
for (tmpX=0; tmpX<=4; tmpX++)
if (Mat1[tmpX][2]<0)
if (fabs(tmp)<fabs(Mat1[tmpX][2]))
{
tmp=Mat1[tmpX][2];
tmpP=tmpX;
}
//В столбце находим минимальный элемент
tmp=1000;
tmpX=tmpP;
tmpJ=tmpY;
for (tmpY=0; tmpY<=1; tmpY++)
{
if ((Mat1[tmpX][tmpY]!=0) && (tmpY!=tmpJ))
if (Mat1[0][tmpY]/Mat1[tmpX][tmpY]<tmp)
{
tmp=Mat1[0][tmpY]/Mat1[tmpX][tmpY];
tmpP=tmpY;
}
}
//Делим на получившийся элемент
tmpY=tmpP;
for (int i = 0; i <= 4; i++)
for (int j=0; j <= 4; j++)
Mat2[i][j]=Mat1[i][j];
tmp=Mat1[tmpX][tmpY];
for (tmpP=0; tmpP<=4; tmpP++)
Mat2[tmpP][tmpY]=Mat2[tmpP][tmpY]/tmp;
for (tmpP=0; tmpP<=2; tmpP++)
Mat2[tmpX][tmpP]=Mat2[tmpX][tmpP]/tmp;
switch (tmpY){