Курсовая работа: Багатокритеріальна задача лінійного програмування
{Тепер це протилежна функція для максимізації:}
Self. CurHeadCol[Row].ElmType:=bc_DestFuncToMax;
End;
PrepareDFuncForSimplexMaximize:=True;
End;
Function TGridFormattingProcs. PrepareDestFuncInMultiDFuncLTask (
SFuncRowNum, MinDestFuncRowNum: Integer):Boolean;
{Готує таблицю для розв'язування задачі ЛП відносно одної заданої функції
мети із багатокритеріальної задачі.
Вхідні дані:
SFuncRowNum – номер рядка у таблиці Self. CopyTable (і комірки у
стовпці-заголовку Self. CopyHeadCol), в якому записана портібна
функція мети;
DestFuncMinRowNum – номер найвищого (з найменшим номером) рядка
функції мети. Усі функції мети мають бути зібрані внизу таблиці;
Self. CopyTable – таблиця коефіцієнтів та вільних членів;
Self. CopyHeadRow – рядок-заголовок зі змінними та одиницею-множником
стовпця вільних членів (має бути останнім);
Self. CopyHeadCol – стовпець-заголовок з іменами функцій-нерівностей,
нулями (заголовки рядків-рівнянь), іменами функцій мети
(що максимізуються (тип комірки bc_DestFuncToMax) або мінімізуються
(тип bc_DestFuncToMin)).
Вихідні дані:
Умова для одної функції:
Self. CurTable – таблиця коефіцієнтів та вільних членів з одною
функцією мети в останньому рядку, для максимізації симплекс-методом;
Self. CurHeadRow – рядок-заголовок;
Self. CurHeadCol – стовпець-заголовок з іменами функцій-нерівностей,
нулями (заголовки рядків-рівнянь), і одною коміркою функції мети
(остання, найнижча комірка), яку треба максимізувати. Якщо у цій
комірці перед назвою функції стоїть знак «–», то після максимізації
її треба замінити на протилежну функцію (і отримати мінімізацію
тої функції, яка була задана в умові).
Підпрограма повертає ознаку успішності підготовки умови із одною
заданою функцією мети.}
Var Row, Col, CurWidth, CurHeight: Integer;
Const sc_CurProcName='PrepareDestFuncInMultiDFuncLTask';
Label LStopLabel;
Begin
If Not (Self. GoToEnd) then
Begin {Демонструємо функцію мети у таблиці, з якою будемо працювати:}
{Таблиця багатокритеріальної задачі для відображення:}
Self. CurHeadRow:=Self. CopyHeadRow; Self. CurHeadCol:=Self. CopyHeadCol;
Self. CurTable:=Self. CopyTable;
{Координати рядка функції для помітки його кольором:}
Self. CurGridSolveCol:=Self.CHeadColNum;
Self. CurGridSolveRow:=SFuncRowNum+Self.CHeadRowNum+bc_LTaskRowsBeforeVars;
{Відображаємо і чекаємо реакції користувача:}
WaitForNewStep (Self.CHeadColNum, Self.CHeadRowNum);
If Self. Stop then Goto LStopLabel;
End;
CurWidth:=Length (Self. CopyHeadRow);
CurHeight:=Length (Self. CopyHeadCol);
If (SFuncRowNum<0) or (MinDestFuncRowNum<0) or
(SFuncRowNum>=CurHeight) or (MinDestFuncRowNum>=CurHeight) then
Begin
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_RowNumsIsOutOfTable);
PrepareDestFuncInMultiDFuncLTask:=False; Exit;
End;
{Формуємо умову однокритеріальної задачі лінійного програмування із
копії умови багатокритеріальної задачі:}
{Копіюємо заголовки і таблицю коефіцієнтів:}
SetLength (Self. CurHeadRow, CurWidth); {довжина для рядка заголовка така сама}
For Col:=0 to CurWidth-1 do Self. CurHeadRow[Col]:=Self. CopyHeadRow[Col];
{Стовпець-заголовок і висота таблиці мають усі рядки умов (рівнянь
та нерівностей) і один рядок функції мети:}
SetLength (Self. CurHeadCol, MinDestFuncRowNum+1);
SetLength (Self. CurTable, MinDestFuncRowNum+1, CurWidth);
For Row:=0 to MinDestFuncRowNum-1 do {копіюємо рядки умов:}
Begin
Self. CurHeadCol[Row]:=Self. CopyHeadCol[Row];
For Col:=0 to CurWidth-1 do
Self. CurTable [Row, Col]:=Self. CopyTable [Row, Col];
End;
{В останній рядок таблиці однокритеріальної задачі копіюємо заданий
рядок функції мети із багатокритеріальної задачі:}
Row:=MinDestFuncRowNum; {номер останнього рядка у однокритеріальній задачі}
Self. CurHeadCol[Row]:=Self. CopyHeadCol[SFuncRowNum];
For Col:=0 to CurWidth-1 do
Self. CurTable [Row, Col]:=Self. CopyTable [SFuncRowNum, Col];
PrepareDestFuncInMultiDFuncLTask:=Self. PrepareDFuncForSimplexMaximize;
Exit;
LStopLabel:
PrepareDestFuncInMultiDFuncLTask:=False; Exit;
End;
Procedure TGridFormattingProcs. ShowLTaskResultCalc (DualTaskVals: Boolean);
{Процедура зчитує значення функції мети у таблиці розв'язаної
однокритеріальної задачі, і значення усіх змінних або функцій в цьому
розв'язку. Відображає значення цих змінних, функцій-нерівностей, і
функції мети в Self. CurOutConsole.
Вхідні дані:
DualTaskVals – вмикач режиму відображення значень двоїстої задачі:
читаються значення змінних і функцій двоїстої задачі. Їхні
значення розміщені не на місці стовпця вільних членів, а у рядку
коефіцієнтів функції мети (функції мети прямої задачі). Вони є
значеннями змінних чи функцій, імена яких у рядку-заголовку.
Змінні чи функції-нерівності двоїстої задачі з іменами у
стовпці-заголовку є рівними нулю.
Таблиця розв'язаної однокритеріальної (з одною функцією мети) задачі:
Self. CurTable – таблиця коефіцієнтів та вільних членів;
Self. CurHeadRow – рядок-заголовок з іменами змінних, іменами
функцій-нерівностей (що перейшли в рядок-заголовок) та
одиницею-множником стовпця вільних членів (має бути останнім);
Self. CurHeadCol – стовпець-заголовок з іменами функцій-нерівностей,
іменами змінних (виключених), іменем функції мети.}
Const DestFuncsTypes=[bc_DestFuncToMax, bc_DestFuncToMin];
Var st1: String; CurColNum, CurRowNum, LastColNum, LastRowNum: Integer;
Begin
If Self. CurOutConsole<>Nil then
Begin
LastColNum:=Length (Self. CurHeadRow) – 1;
LastRowNum:=Length (Self. CurHeadCol) – 1;
st1:=sc_ResultIs;
If DualTaskVals then
st1:=st1+sc_ForDualTask
Else st1:=st1+sc_ForDirectTask;
Self. CurOutConsole. Lines. Add(st1);
Self. CurOutConsole. Lines. Add (sc_InHeadRow);
{Показуємо значення змінних (або функцій) у рядку-заголовку:}
For CurColNum:=0 to LastColNum-1 do
Begin
st1:='';
If Self. CurHeadRow[CurColNum].ElmType=bc_Number then
st1:=st1+FloatToStr (Self. CurHeadRow[CurColNum].AsNumber)
Else st1:=st1+Self. CurHeadRow[CurColNum].AsVarName;
st1:=st1 + sc_Space+sc_Equal+sc_Space;
{Усі змінні прямої задачі (або функції) у рядку-заголовку в точці
задачі рівні нулю, а змінні двоїстої – у рядку коефіцієнтів функції
мети:}
If DualTaskVals then
st1:=st1+ FloatToStr (Self. CurTable [LastRowNum, CurColNum])
Else st1:=st1+'0';
st1:=st1+sc_KrKm;
Self. CurOutConsole. Lines. Add(st1);
End;
Self. CurOutConsole. Lines. Add (sc_InHeadCol);
For CurRowNum:=0 to LastRowNum do
Begin
st1:='';
If Self. CurHeadCol[CurRowNum].ElmType=bc_Number then
st1:=st1+FloatToStr (Self. CurHeadCol[CurRowNum].AsNumber)
Else st1:=st1+Self. CurHeadCol[CurRowNum].AsVarName;
st1:=st1 + sc_Space+sc_Equal+sc_Space;
{Усі змінні прямої задачі (або функції) у стовпці-заголовку в точці
задачі мають свої значення у стовпці вільних членів,
а змінні двоїстої – рівні нулю:}
If (Self. CurHeadCol[CurRowNum].ElmType in DestFuncsTypes) or
Not(DualTaskVals) then
st1:=st1+ FloatToStr (Self. CurTable [CurRowNum, LastColNum])
Else st1:=st1+'0';
If (Self. CurHeadCol[CurRowNum].ElmType in DestFuncsTypes) then
st1:=sc_ResFunc+sc_Space+st1;
If CurRowNum=LastRowNum then st1:=st1+sc_Spot
Else st1:=st1+sc_KrKm;
Self. CurOutConsole. Lines. Add(st1);
End;
End;
End;
Procedure TGridFormattingProcs. ReadCurFuncSolution (Var SDValVecs:TFloatMatrix;
Var SDDestFuncVals:TFloatArr; SVecRow: Integer;
ToReadFuncVals: Boolean; DualTaskVals: Boolean);
{Процедура зчитує значення функції мети у таблиці розв'язаної
однокритеріальної задачі, і значення усіх змінних або функцій в цьому
розв'язку.
Вхідні дані:
SVecRow – номер поточної функції мети (нумерація з нуля) у масивах
SDValVecs і SDDestFuncVals;
ToReadFuncVals – перемикач: якщо рівний False, то зчитуються значення
змінних (і значення функції мети); True – зчитуються значення
функцій-нерівностей (і значення функції мети);
DualTaskVals – вмикач режиму читання змінних двоїстої задачі:
читаються значення змінних і функцій двоїстої задачі. Їхні
значення розміщені не на місці стовпця вільних членів, а у рядку
коефіцієнтів функції мети (функції мети прямої задачі). Вони є
значеннями змінних чи функцій, імена яких у рядку-заголовку.
Змінні чи функції-нерівності двоїстої задачі з іменами у
стовпці-заголовку є рівними нулю.
Таблиця розв'язаної однокритеріальної (з одною функцією мети) задачі:
Self. CurTable – таблиця коефіцієнтів та вільних членів;
Self. CurHeadRow – рядок-заголовок з іменами змінних, іменами
функцій-нерівностей (що перейшли в рядок-заголовок) та
одиницею-множником стовпця вільних членів (має бути останнім);
Self. CurHeadCol – стовпець-заголовок з іменами функцій-нерівностей,
іменами змінних (виключених), іменем функції мети. Функція мети
має бути в останньому рядку, і бути одна;
SDValVecs – масив для запису векторів значень змінних;
SDDestFuncVals – масив для запису значень функцій мети
(для цих двох останніх масивів пам'ять має бути вже виділеною).
Вихідні дані:
SDValVecs – масив векторів значень змінних із заповненим вектором
номер SVecRow. Змінні, яких немає в таблиці розв'язку, вважаються
такими що можуть мати будь-яке значення, і приймаються рівними нулю;
SDDestFuncVals – масив значень функцій мети з поточни значенням
у комірці номер SVecRow.}
Var CurColNum, CurRowNum, LastColNum, LastRowNum: Integer;
WorkCellTypes:THeadLineElmTypes;
Begin
{Ініціюємо нулями поточний вектор значень.
Змінні чи функції, імена яких у рядку-заголовку, рівні нулю
для прямої задачі (для двоїстої – у стовпці-заголовку).
Змінні і функції, яких немає в таблиці, теж вважаємо рівними нулю:}
For CurColNum:=0 to Length (SDValVecs[SVecRow]) – 1 do
SDValVecs [SVecRow, CurColNum]:=0;
{Читаємо стовпець-заголовок і значення із останнього стовпця таблиці:}
LastColNum:=Length (Self. CurHeadRow) – 1;
LastRowNum:=Length (Self. CurHeadCol) – 1;
{Значення функції мети:}
SDDestFuncVals[SVecRow]:=Self. CurTable [LastRowNum, LastColNum];
{Функції-нерівності прямої задачі відповідають змінним двоїстої задачі
за позиціюванням в заголовках (не за значеннями, значення різні!),
змінні прямої – функціям двоїстої:}
If (ToReadFuncVals) xor (DualTaskVals) then
WorkCellTypes:=[bc_FuncVal]
Else WorkCellTypes:=[bc_IndependentVar, bc_DependentVar];
{Читаємо змінні або функції-нерівності (в залежності від того, що
задано прочитати):}
If DualTaskVals then
Begin
For CurColNum:=0 to LastColNum-1 do {усі стовпці крім стовпця вільних членів}
Begin {значення записуємо у заданий вектор (SVecRow):}
If (Self. CurHeadRow[CurColNum].ElmType in WorkCellTypes) then
SDValVecs [SVecRow, Self. CurHeadRow[CurColNum].VarInitPos]:=
Self. CurTable [LastRowNum, CurColNum];
End
End
Else
Begin
For CurRowNum:=0 to LastRowNum-1 do {усі рядки крім рядка функції мети}
Begin {значення записуємо у заданий вектор (SVecRow):}
If (Self. CurHeadCol[CurRowNum].ElmType in WorkCellTypes) then
SDValVecs [SVecRow, Self. CurHeadCol[CurRowNum].VarInitPos]:=
Self. CurTable [CurRowNum, LastColNum];
End
End;
End;
Procedure TGridFormattingProcs. BuildPaymentTaskOfOptim (
Const SOptimXVecs:TFloatMatrix; Const SOptimFuncVals:TFloatArr;
SFirstDFuncRow: Integer);
{Будує однокритеріальну задачу максимізації для пошуку вагових
коефіцієнтів і компромісного вектора значень змінних для
усіх заданих функцій мети.
Вхідні дані:
SOptimXVecs – масив векторів оптимальних значень змінних для
кожної з фунуцій мети;
SOptimFuncVals – масив оптимальних значень функцій мети;
SFirstDFuncRow – номер першої (найвищої) функції мети
у Self. CopyTable і Self. CopyHeadCol;
Self. CopyTable – матриця коефіцієнтів умови багатокритеріальної задачі;
Вихідні дані:
Однокритеріальна задача ЛП для максимізації:
Self. CurTable – матриця коефіцієнтів оптимальності,
вільних членів і коефіцієнтів функції мети;
Self. CurHeadCol – імена змінних двоїстої задачі (як
функції-нерівності прямої задачі);
Self. CurHeadRow – імена функцій-нерівностей двоїстої задачі
(як залежні (тільки більше нуля) змінні прямої задачі).}
Var jCol, iRow, FuncCount, FuncRow: Integer; MinQ, CurQ:TWorkFloat;
Const sc_CurProcName='BuildPaymentTaskOfOptim';
Function CalcQ (ZjFuncRow: Integer; Const XiVals:TFloatArr;
Const ZjXj:TWorkFloat):TWorkFloat;
{Підраховує міру неоптимальності.
Вхідні дані:
ZjFuncRow – номер рядка j-ої функції мети у таблиці Self. CopyTable;
Self. CopyTable – таблиця коефіцієнтів умови багатокритеріальної
задачі ЛП;
XiVals – оптимальні значення змінних для i-ої функції мети
(для формування i-го рядка матриці неоптимальності);
ZjXj – значення j-ої функції мети за j-го набору оптимальних
значень змінних (тобто оптимальне значення цієї функції). Для
формування j-го стовпця матриці неоптимальності.
Вихідні дані: міра неоптимальності.}
Var VarNum: Integer; ZjXi:TWorkFloat;
Begin
ZjXi:=0;
{Шукаємо суму добутків значень змінних і коефіцієнтів при них –
значення функції у точці, координатами якої є подані значення змінних:}
For VarNum:=0 to Length(XiVals) – 1 do
ZjXi:=ZjXi + Self. CopyTable [ZjFuncRow, VarNum]*XiVals[VarNum];
CalcQ:=-Abs((ZjXi/ZjXj) – 1); qij=-
End;
{Заповнення імен змінних – імен фукнцій двоїстої задачі у рядку-заголовку:}
Procedure FillHRowVarName (SCol: Integer);
Begin
Self. CurHeadRow[SCol].VarInitPos:=SCol;
Self. CurHeadRow[SCol].VarInitInRow:=True;
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14