Курсовая работа: Багатокритеріальна задача лінійного програмування
If Self. CopyHeadCol[Row].ElmType=bc_DestFuncToMin then
st1:=st1+sc_SearchingMin
Else st1:=st1+sc_SearchingMax;
st1:=st1+sc_TriSpot+sc_TextMarkRow;
Self. CurOutConsole. Lines. Add(st1);
End;
{Формуємо умову однокритеріальної задачі максимізації:}
If Not (Self. PrepareDestFuncInMultiDFuncLTask (Row, FirstDestFuncRow)) then
Begin
Res1:=False; Break;
End;
If Self. Stop then Break;
{Ховаємо розв'язувальну комірку у екранній таблиці (її нема тут):}
Self. CurGridSolveCol:=0; Self. CurGridSolveRow:=0;
{Відображаємо підготовану однокритеріальну задачу:}
WaitForNewStep (Self.CHeadColNum, Self.CHeadRowNum);
If Self. Stop then Break;
{Запускаємо вирішування однокритеріальної задачі максимізації лінійної
форми (так як поточна функція є функцією максимізації, або зведена
до такої):}
Self. WasNoRoots:=False; Self. WasManyRoots:=False; Self. SolWasFound:=False;
If Not (Self. SolveLTaskToMax(False)) then
Begin
Res1:=False; Break;
End;
{Якщо функція мети необмежена або система умов несумісна:}
If Not (Self. SolWasFound) then
Begin
{Якщо функцій мети більше одної, то так як компромісний вектор
через необмеженість принаймні одної з функцій мети знайти неможливо:}
If (FirstDestFuncRow+1)<CurHeight then Res1:=False
Else Res1:=True;
Goto LFinish;
End;
If Self. Stop then Break;
{Читаємо вектор значень змінних та оптимальне значення функції мети
з таблиці:}
Self. ReadCurFuncSolution (OptimXVecs, OptimFuncVals, Row-FirstDestFuncRow,
False, False);
End;
If Not(Res1) then Goto LFinish;
If Self. Stop then Goto LStopLabel;
{############ Шукаємо міри неоптимальності і будуємо задачу: ############}
{######## пошуку компромісних вагових коефіцієнтів, вирішуємо її: ########}
If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_TextMarkRow);
BuildPaymentTaskOfOptim (OptimXVecs, OptimFuncVals, FirstDestFuncRow);
If Self. Stop then Goto LStopLabel;
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_TextMarkRow);
{Готуємо задачу до максимізації симплекс-методом:}
Res1:=Self. PrepareDFuncForSimplexMaximize;
If Not(Res1) then Goto LFinish;
{Запускаємо вирішування цієї задачі:}
Self. WasNoRoots:=False; Self. WasManyRoots:=False; Self. SolWasFound:=False;
{«True» – з відображенням значень двоїстої:}
If Not (Self. SolveLTaskToMax(True)) then
Begin
Res1:=False; Goto LFinish;
End;
{Якщо функція мети необмежена або система умов несумісна:}
If Not (Self. SolWasFound) then
Begin
Res1:=False; Goto LFinish;
End;
If Self. Stop then Goto LStopLabel;
{############ Обчислюємо вагові коефіцієнти: ############}
{Якщо задача-інтерпретація гри вирішена і знайдено оптимальне
значення функції, то читаємо це значення і значення змінних
двоїстої задачі:}
SetLength (OptGTaskVal, 1); {для запису значення функції мети}
SetLength (DualUVec, 1, DestFuncCount); {для запису значень змінних}
Self. ReadCurFuncSolution (DualUVec, OptGTaskVal, 0, False, True);
{Обчислюємо вагові коефіцієнти:}
For Row:=0 to DestFuncCount-1 do
DualUVec [0, Row]:=(DualUVec [0, Row]/OptGTaskVal[0]); {Li=ui/(W(U))}
If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_TextMarkRow);
ShowWeightCoefs (DualUVec[0], FirstDestFuncRow);
{############ Обчислюємо компромісний вектор: ############}
Self. CalcComprVec (OptimXVecs, DualUVec[0], ComprXVec);
ShowComprVarVec(ComprXVec);
ShowDFuncVals (ComprXVec, FirstDestFuncRow);
Goto LFinish;
LStopLabel: {Якщо вирішування було перервано:}
{Повертаємо початкову умову на попереднє місце:}
Self. CurHeadRow:=Self. CopyHeadRow;
Self. CurHeadCol:=Self. CopyHeadCol;
Self. CurTable:=Self. CopyTable;
LFinish:
{Обнуляємо посилання на копію умови. Так як це динамічні масиви і
щодо них йде відлік кількості посилань, то для них не створюватимуться
зайві копії у пам'яті, і при роботі з CurHeadRow, CurHeadCol, CurTable
пам'ять буде виділена завжди тільки для їхніх поточних даних:}
Self. CopyHeadRow:=Nil;
Self. CopyHeadCol:=NIl;
Self. CopyTable:=Nil;
SolveMultiCritLTask:=Res1;
End;
Procedure TGridFormattingProcs. ChangeSignsInRow (CurRowNum: Integer);
{Зміна знаків у рядку таблиці і відповідній комірці у стовпці-заголовку.}
Var CurColNum: Integer;
Begin
For CurColNum:=0 to Length (Self. CurHeadRow) – 1 do
CurTable [CurRowNum, CurColNum]:=-CurTable [CurRowNum, CurColNum];
ChangeSignForValOrVarName (Self. CurHeadCol[CurRowNum]);
End;
Procedure TGridFormattingProcs. ChangeSignsInCol (CurColNum: Integer);
{Зміна знаків у стовпці таблиці і відповідній комірці у рядку-заголовку.}
Var CurRowNum: Integer;
Begin
For CurRowNum:=0 to Length (Self. CurHeadCol) – 1 do
CurTable [CurRowNum, CurColNum]:=-CurTable [CurRowNum, CurColNum];
ChangeSignForValOrVarName (Self. CurHeadRow[CurColNum]);
End;
Function TGridFormattingProcs. ShiftRowsUp (SHeadColElmTypes:THeadLineElmTypes;
ToChangeInitPosNums: Boolean=False):Integer;
{Функція переміщує рядки таблиці CurTable (разом із відповідними
комірками у стовпці-заголовку CurHeadCol) з заданими типами комірок
стовпця-заголовка вгору.
Вхідні дані:
SHeadColElmTypes – множина типів комірок, що мають бути переміщені вгору
(у стовпці-заголовку);
ToChangeInitPosNums – вмикач зміни позначок номера по порядку та
позначки розташування в таблиці як рядка чи стовпця.
Якщо рівний True, то рядки при переміщенні змінюють ці позначки
на позначки тих рядків, що були в тих місцях, на які рядки переміщені;
Self. CurTable – таблиця коефіцієнтів;
Self. CurHeadCol – стовпець-заголовок.
Вихідні дані:
Self. CurTable і Self. CurHeadCol – таблиця коефіцієнтів і
стовпець-заголовок з перенесеними вгору рядками і комірками;
функція повертає номер найвищого рядка із тих, що не було задано
переміщувати вгору (вище нього – ті, що переміщені вгору).}
Var HiNotInSetRow, CurRowToUp, CurRowNum: Integer;
Begin
{Номер найвищого рядка, що не є в множині тих, які переміщуються вгору.
Спочатку ставимо тут номер неіснуючого рядка:}
HiNotInSetRow:=-1;
{Йдемо по рядкам згори вниз:}
For CurRowNum:=0 to Length (Self. CurHeadCol) – 1 do
Begin {Шукаємо перший рядок з типом комірки, що не має переміщуватися вгору:}
If Not (Self. CurHeadCol[CurRowNum].ElmType in SHeadColElmTypes) then
Begin
HiNotInSetRow:=CurRowNum;
{шукаємо найнижчий рядок, який портібно переміщувати вгору:}
For CurRowToUp:=Length (Self. CurHeadCol) – 1 downto CurRowNum+1 do
Begin
If Self. CurHeadCol[CurRowToUp].ElmType in SHeadColElmTypes then Break;
End;
{Якщо таких рядків не знайдено, то усі вони вже вгорі:}
If CurRowToUp<=CurRowNum then Break
Else {Міняємо місцями рядок, що має бути вгорі, і рядок, що не має,
але розташований вище:}
ChangeRowsPlaces (Self. CurTable, Self. CurHeadCol, CurRowNum,
CurRowToUp, ToChangeInitPosNums);
End;
End;
ShiftRowsUp:=HiNotInSetRow;
End;
Function TGridFormattingProcs. ShiftRowsDown (
SHeadColElmTypes:THeadLineElmTypes;
ToChangeInitPosNums: Boolean=False):Integer;
{Функція переміщує рядки таблиці CurTable (разом із відповідними
комірками у стовпці-заголовку CurHeadCol) з заданими типами комірок
стовпця-заголовка вниз.
Вхідні дані:
SHeadColElmTypes – множина типів комірок, що мають бути переміщені вниз
(у стовпці-заголовку);
ToChangeInitPosNums – вмикач зміни позначок номера по порядку та
позначки розташування в таблиці як рядка чи стовпця.
Якщо рівний True, то рядки при переміщенні змінюють ці позначки
на позначки тих рядків, що були в тих місцях, на які рядки переміщені;
Self. CurTable – таблиця коефіцієнтів;
Self. CurHeadCol – стовпець-заголовок.
Вихідні дані:
Self. CurTable і Self. CurHeadCol – таблиця коефіцієнтів і
стовпець-заголовок з перенесеними донизу рядками і комірками;
функція повертає номер найвищого рядка із тих, що переміщені вниз
(вище нього – рядки тих типів, що не було задано переміщувати донизу).}
Var AllOtherHeadTypes:THeadLineElmTypes;
Begin
{Отримуємо протилежну множину типів комірок:}
AllOtherHeadTypes:=[bc_IndependentVar..bc_OtherType] – SHeadColElmTypes;
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24