МІНІСТЕРСТВО ОСВІТИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ
“ЛЬВІВСЬКА ПОЛІТЕХНІКА”
АВТОМАТИЗОВАНІ СИСТЕМИ УПРАВЛІННЯ
Лабораторна робота №1
ОПТИМАЛЬНЕ КЕРУВАННЯ ПРОЦЕСАМИ З ЗАСТОСУВАННЯМ
МЕТОДУ ЛІНІЙНОГО ПРОГРАМУВАННЯ
Мета роботи
Вивчення і застосування методу лінійного програмування для рішення задач оптимального керування, у яких цільова функція, модель процесу й обмеження є лінійними функціями.
Хід роботи
ознайомитися з теоретичними зведеннями і прикладами використання методу лінійного програмування для рішення задач оптимального керування;
представити цільову функцію і систему обмежень у вигляді функцій змінних керування шляхом заміни змінних стану змінних керування;
скласти програму рішення задачі на мові С#;
вивести на друк максимальне і мінімальне значення цільової функції, значення змінних керування;
Індивідуальне завдання
Варіант 4
Цільова функція
Модель процесу
Обмеження
Код програми
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Lab1
{
public partial class Form1 : Form
{
public int[,] A = { { 1, 0, 0 }, { 5, 1, 10 }, { 0, 1, 0 }, { -4, 3, -48 }, { -1, 0, -17 }, { -1, -4, -58 } };
public int[,] B = new int[6,2];
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Graphics g = pictureBox1.CreateGraphics();
int maxx1 = 0, maxx2 = 0, minx1 = 0, minx2 = 0;
int cx = 250, cy = 250, k =4;
Pen MyPen = new Pen(Color.Black);
//Створення осей координат
g.DrawLine(MyPen, cx, 0, cx, 500);
g.DrawLine(MyPen, 1, cx, 500, cy);
//Створення стрілок на кінцях осей
SolidBrush MyBrush = new SolidBrush(Color.Black);
Point p1 = new Point(250, 0);
Point p2 = new Point(246, 15);
Point p3 = new Point(254, 15);
Point p4 = new Point(500, 250);
Point p5 = new Point(485, 246);
Point p6 = new Point(485, 254);
Point[] Pt1 = { p1, p2, p3 };
Point[] Pt2 = { p4, p5, p6 };
FillMode FM = FillMode.Winding;
g.FillPolygon(MyBrush, Pt1, FM);
g.FillPolygon(MyBrush, Pt2, FM);
//позначення точок на осі (по 10 значень в одному відрізку)
for(int i=0;i<6;i++)
{
Rectangle Rect = new Rectangle(cx - 1 + i * k * 10, cy - 2, 5, 5);
g.FillEllipse(MyBrush, Rect);
Rectangle Rect1 = new Rectangle(cx + 1 - i * k*10, cy - 2, 5, 5);
g.FillEllipse(MyBrush, Rect1);
}
// 0 <= x1 <= 17
minx1 = 0;
maxx1 = 17;
Brush CrossBrush = new HatchBrush(HatchStyle.ForwardDiagonal, Color.Red, Color.Transparent);
g.FillRectangle(CrossBrush, cx, minx1, maxx1 * k, 500);
Pen RedPen = new Pen(Color.Red);
g.DrawLine(RedPen, cx + k * maxx1, minx1, cx + k * maxx1, 500);
//5x1+x2>=10 =>x2=10-5x1
maxx2 = 100;
maxx1 = (10 - maxx2) / 5;
minx1 = 20;
minx2 = 10 - 5 * minx1;
Pen GreenPen = new Pen(Color.Green, 3);
g.DrawLine(GreenPen, cx + maxx1 * k, cy - maxx2 * k, cx + minx1 * k, cy - minx2 * k);
Brush GreenCrossBrush = new HatchBrush(HatchStyle.BackwardDiagonal, Color.Green, Color.Transparent);
Point Gp1 = new Point(cx + maxx1 * k, cy - maxx2 * k);
Point Gp2 = new Point(cx + minx1 * k, cy - minx2 * k);
Point Gp3 = new Point(cx + ( minx1 + 30 * k ), cy - ( minx2 - 20 * k ) );
Point Gp4 = new Point(cx + ( maxx1 + 30 * k ), cy - ( maxx2 - 20 * k ) );
Point[] Gpt1 = { Gp1, Gp2, Gp3, Gp4 };
g.FillPolygon(GreenCrossBrush, Gpt1, FM);
//-4x1+3x2>=-48
minx2 = -30;
minx1 = (-48 - 3 * minx2) / -4;
maxx1 = 30;
maxx2 = (-48 + 4 * maxx1) / 3;
Pen BluePen = new Pen(Color.Blue, 2);
g.DrawLine(BluePen, cx + minx1 * k, cy - minx2 * k, cx + maxx1 * k, cy - maxx2 * k);
Brush BlueCrossBrush = new HatchBrush(HatchStyle.Horizontal, Color.Blue, Color.Transparent);
Point Bp1 = new Point(cx + minx1 * k, cy - minx2 * k);
Point Bp2 = new Point(cx + maxx1 * k, cy - maxx2 * k);
Point Bp3 = new Point(cx - (maxx1 - 30) * k, cy - (maxx2 + 30) * k);
Point Bp4 = new Point(cx + (minx1 - 30) * k, cy - (minx2 + 30) * k);
Point[] Bpt1 = { Bp1, Bp2, Bp3, Bp4 };
g.FillPolygon(BlueCrossBrush, Bpt1, FM);
//x1+4x2<=58
minx1 = -20;
minx2 = (58 - minx1) / 4;
maxx2 = 0;
maxx1 = 58 - 4 * maxx2;
Pen YellowPen = new Pen(Color.Yellow,2);
g.DrawLine(YellowPen, cx + minx1 * k, cy - minx2 * k, cx + maxx1 * k, cy - maxx2 * k);
Brush YellowcrossBrush = new HatchBrush(HatchStyle.Vertical, Color.Yellow, Color.Transparent);
Point Yp1 = new Point(cx + minx1 * k, cy - minx2 * k);
Point Yp2 = new Point(cx + maxx1 * k, cy - maxx2 * k);
Point Yp3 = new Point(cx + (maxx1 - 30) * k, cy - (maxx2 - 30) * k);
Point Yp4 = new Point(cx + (minx1 - 30) * k, cy - (minx2 - 30) * k);
Point[] Ypt1 = { Yp1, Yp2, Yp3, Yp4 };
g.FillPolygon(YellowcrossBrush, Ypt1, FM);
//x2>=0
minx1 = -20;
maxx1 = 20;
minx2 = 0;
maxx2 = 0;
Pen VioletPen = new Pen(Color.Violet, 3);
g.DrawLine(VioletPen, cx + minx1 * k, cy + minx2 * k, cx + maxx1 * k, cy + maxx2 * k);
//точки перетину
g.FillEllipse(MyBrush, cx - 0 * k - 3, cy - 10 * k - 3, 7, 7);
g.FillEllipse(MyBrush, cx - 0 * k - 3, cy - 14.5F * k - 3, 7, 7);
g.FillEllipse(MyBrush, cx + 2 * k - 3, cy - 0 * k - 3, 7, 7);
g.FillEllipse(MyBrush, cx + 12 * k - 3, cy - 0 * k - 3, 7, 7);
g.FillEllipse(MyBrush, cx + 17 * k - 3, cy - 6.6F * k - 3, 7, 7);
g.FillEllipse(MyBrush, cx + 17 * k - 3, cy - 10.25F * k - 3, 7, 7);
//головна функція
//G(x)=21x1+5x2 => x2=-4.25x1
Pen BoldPen = new Pen(Color.Black, 3);
minx1 = -15;
minx2 = - 21 * minx1 / 5;
maxx1 = 15;
maxx2 = - 21 * maxx1 / 5;
g.DrawLine(BoldPen, cx + minx1 * k, cy - minx2 * k, cx + maxx1 * k, cy - maxx2 * k);
//градієнт
minx2 = 0;
minx1 = 0;
maxx1 = 21;
maxx2 = 5;
Pen Pen2 = new Pen(Color.Black, 2);
g.DrawLine(Pen2, cx + minx1 * k, cy - minx2 * k, cx + maxx1 * k, cy - maxx2 * k);
//напрям градієнта
Point Pl1 = new Point(cx + maxx1 * k, cy - maxx2 * k);
Point Pl2 = new Point(cx + maxx1 * k - 13, cy - maxx2 * k - 3);
Point Pl3 = new Point(cx + maxx1 * k - 11, cy - maxx2 * k + 9);
Point[] P = { Pl1, Pl2, Pl3 };
g.FillPolygon(MyBrush, P, FM);
int Delta = 0, d1 = 0, d2 = 0, x1 = 0, x2 = 0, i1 = 0;
for(int i = 0; i < 5; i++)
for(int j = i+1;j < 6; j++)
{
Delta = A[i,0] * A[j,1] - A[i,1] * A[j,0];
d1 = A[i,2] * A[j,1] - A[j,2] * A[i,1];
d2 = A[i,0] * A[j,1] - A[i,2] * A[j,0];
if (Delta != 0)
{
x1 = d1 / Delta;
x2 = d2 / Delta;
if (((A[0, 0] * x1 + A[0, 1] * x2) >= A[0, 2]) & ((A[1, 0] * x1 + A[1, 1] * x2) >= A[1, 2]) & ((A[2, 0] * x1 + A[2, 1] * x2) >= A[2, 2]) & ((A[3, 0] * x1 + A[3, 1] * x2) >= A[3, 2]) & ((A[4, 0] * x1 + A[4, 1] * x2) >= A[4, 2]) & ((A[5, 0] * x1 + A[5, 1] * x2) >= A[5, 2]))
{
B[i1,0] = x1;
B[i1,1] = x2;
i1++;
}
}
}
int mx1 = 0, mx2 = 0, nx1 = 0, nx2 = 0;
int max = 21 * B[0, 0] + 5 * B[0, 1];
mx1 = B[0, 0];
mx2 = B[0, 1];
for (int i = 1; i < i1; i++)
{
if (21 * B[i, 0] + 5 * B[i, 1] > max)
{
max = 21 * B[i, 0] + 5 * B[i, 1];
mx1 = B[i, 0];
mx2 = B[i, 1];
}
}
int min = 21 * B[0, 0] + 5 * B[0, 1];
nx1 = B[0, 0];
nx2 = B[0, 1];
for (int i = 1; i < i1; i++)
{
if (21 * B[i, 0] + 5 * B[i, 1] < min)
{
min = 21 * B[i, 0] + 5 * B[i, 1];
nx1 = B[i, 0];
nx2 = B[i, 1];
}
}
label15.Text = Convert.ToString(mx1);
label16.Text = Convert.ToString(mx2);
label18.Text = Convert.ToString(nx1);
label19.Text = Convert.ToString(nx2);
}
}
}
Результати роботи
/
Висновок: На даній лабораторній роботі я навчився запрограмовувати задачі оптимального керування, у яких цільова функція, модель процесу й обмеження є лінійними функціями. Програмно будувати їх графік, та визначати деякі максимальні і мінімальні точки .