![]() |
|
|
Курсовая работа: Багатокритеріальна задача лінійного програмуванняIf Self. CurHeadCol[CurRow].AsNumber=0 then {Якщо 0, заголовок рівняння:} Begin Self. CurHeadCol[CurRow].ElmType:=bc_IndependentVar; Self. CurHeadCol[CurRow].VarInitInRow:=True; {Формуємо назву змінної двоїстої задачі (залежно від назви функції мети поданої задачі):} If Pos (sc_DualDestFuncHdr, Self. CurHeadCol [Length(Self. CurHeadCol) – 1].AsVarName)>0 then Self. CurHeadCol[CurRow].AsVarName:=sc_XVarName+IntToStr (CurRow+1) Else Self. CurHeadCol[CurRow].AsVarName:=sc_DualTaskVarNameStart+ IntToStr (CurRow+1); End; End {Якщо заголовок рядка функції мети:} Else if Self. CurHeadCol[CurRow].ElmType=OldDFuncType then Begin Self. CurHeadCol[CurRow].ElmType:=bc_Number; Self. CurHeadCol[CurRow].AsNumber:=1; {буде множник стовпця вільних членів} End; End; {Міняємо рядок і стовпець-заголовки таблиці місцями:} SafeMas:=Self. CurHeadRow; Self. CurHeadRow:=Self. CurHeadCol; Self. CurHeadCol:=SafeMas; {У новому стовпці-заголовку шукаємо комірки-заголовки нерівностей «>=». Їх заміняємо на «<=» множенням рядка на -1:} For CurRow:=0 to Length (Self. CurHeadCol) – 1 do Begin If Self. CurHeadCol[CurRow].ElmType=bc_FuncVal then Begin If ValSign (Self. CurHeadCol[CurRow])=bc_Negative then Self. ChangeSignsInRow(CurRow); End; End; {У новому рядку-заголовку шукаємо комірки-заголовки залежних змінних, які мають умову «<=0». Змінюємо цю умову на «>=0» множенням стовпця на -1:} For CurCol:=0 to Length (Self. CurHeadRow) – 1 do Begin If Self. CurHeadRow[CurCol].ElmType=bc_DependentVar then Begin If ValSign (Self. CurHeadRow[CurCol])=bc_Negative then Self. ChangeSignsInCol(CurCol); End; End; {Відображаємо отриману таблицю у екранній таблиці:} Self. WriteTableToGrid (Self.CHeadColNum, Self.CHeadRowNum); MakeDualLTask:=True; End; Function TGridFormattingProcs. PrepareToSolveEqsWithM1: Boolean; Const sc_CurProcName='PrepareToSolveEqsWithM1'; Var CurRow, ColToDel: Integer; Begin If (Self. CurFormatState=fs_EnteringEqs) or (Self. CurFormatState=fs_NoFormatting) then Begin {Якщо таблиця не зчитана, то читаємо:} If (Self. CurGridModified) and (Self. CurFormatState=fs_EnteringEqs) then Begin If Not (Self. GetTask) then Begin PrepareToSolveEqsWithM1:=False; Exit; End; End; If Self. TaskHeight<=0 then {Якщо таблиця пуста:} Begin If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_EmptyTable); PrepareToSolveEqsWithM1:=False; Exit; End; If Not (Self. EqM1TaskPrepared) then Begin {Копіюємо стовпець вільних членів (правих частин рівнянь) із останнього стовпця таблиці до стовпця-заголовка:} For CurRow:=0 to Length (Self. CurHeadCol) – 1 do Begin Self. CurHeadCol[CurRow].ElmType:=bc_Number; Self. CurHeadCol[CurRow].AsNumber:= Self. CurTable [CurRow, Length (CurTable[CurRow]) – 1]; End; {Видаляємо цей останній стовпець із таблиці:} ColToDel:=Length (Self. CurTable[0]) – 1; DelColsFromMatr (Self. CurTable, ColToDel, 1); DeleteFromArr (Self. CurHeadRow, ColToDel, 1); End; {Позиціювання відображення таблиці у даному режимі вирішування:} Self.CHeadColNum:=CurGrid. FixedCols; Self.CHeadRowNum:=CurGrid. FixedRows-1; {Відображаємо таблицю, що підготована для розв'язування:} Self. WriteTableToGrid (Self.CHeadColNum, Self.CHeadRowNum); {Якщо таблиця пуста після перенесення останнього стовпця у стовпець-заголовок:} If Self. TaskHeight<=0 then Begin PrepareToSolveEqsWithM1:=False; Exit; End; Self. EqM1TaskPrepared:=True; PrepareToSolveEqsWithM1:=True; End Else Begin If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_WrongEditMode); PrepareToSolveEqsWithM1:=False; End; End; Function TGridFormattingProcs. PrepareToSolveEqsWithM2: Boolean; Const sc_CurProcName='PrepareToSolveEqsWithM2'; Var CurRow: Integer; Begin If (Self. CurFormatState=fs_EnteringEqs) or (Self. CurFormatState=fs_NoFormatting) then Begin {Якщо таблиця не зчитана, то читаємо:} If (Self. CurGridModified) and (Self. CurFormatState=fs_EnteringEqs) then Begin If Not (Self. GetTask) then Begin PrepareToSolveEqsWithM2:=False; Exit; End; End; If Self. TaskHeight<=0 then {Якщо таблиця пуста:} Begin If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_TableIsNotReady); PrepareToSolveEqsWithM2:=False; Exit; End; If Not (Self. EqM2TaskPrepared) then Begin For CurRow:=0 to Length (Self. CurHeadCol) – 1 do Begin {Заповнюємо стовпець-заголовок нулями:} Self. CurHeadCol[CurRow].ElmType:=bc_Number; Self. CurHeadCol[CurRow].AsNumber:=0; {Змінюємо знаки у останньому стовпці таблиці – стовпці вільних членів. Так як вони у правих частинах рівнянь, то знаходячись у таблиці коефіцієнтів лівих частин, повинні бути з протилежними знаками:} Self. CurTable [CurRow, Length (CurTable[CurRow]) – 1]:= – Self. CurTable [CurRow, Length (CurTable[CurRow]) – 1]; End; End; {Позиціювання відображення таблиці у даному режимі вирішування:} Self.CHeadColNum:=CurGrid. FixedCols; Self.CHeadRowNum:=CurGrid. FixedRows-1; {Відображаємо таюдицю, що підготована для розв'язування:} Self. WriteTableToGrid (Self.CHeadColNum, Self.CHeadRowNum); Self. EqM2TaskPrepared:=True; PrepareToSolveEqsWithM2:=True; End Else Begin If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_WrongEditMode); PrepareToSolveEqsWithM2:=False; End; End; {TTableFormatState=(fs_EnteringEqs, fs_EnteringLTask, fs_SolvingEqsM1, fs_SolvingEqsM2, fs_SolvingLTask, fs_NoFormatting, fs_FreeEdit);} Function TGridFormattingProcs. PrepareToSolveLTask: Boolean; Const sc_CurProcName='PrepareToSolveLTask'; Begin If (Self. CurFormatState=fs_EnteringLTask) or (Self. CurFormatState=fs_NoFormatting) then Begin {Якщо таблиця у режимі редагування задачі, і модифікована, то зчитуємо:} If (Self. CurGridModified) and (Self. CurFormatState=fs_EnteringLTask) then Begin If Not (Self. GetTask) then {зчитуємо таблицю (умову) з екранної таблиці} Begin PrepareToSolveLTask:=False; Exit; End; End; If Self. TaskHeight<=0 then {Якщо таблиця пуста:} Begin If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_TableIsNotReady); PrepareToSolveLTask:=False; Exit; End; If Not (Self.LTaskPrepared) then {якщо ця підготовка ще не виконувалася:} Begin {Зсуваємо рядки цільових функцій вниз. При цьому позначки порядку рядків залишаємо на тих самих місцях (і присвоюємо тим рядкам, які стають на ці місця):} Self. ShiftRowsDown([bc_DestFuncToMax, bc_DestFuncToMin], True); {Позиціювання відображення таблиці у даному режимі вирішування:} Self.CHeadColNum:=CurGrid. FixedCols; Self.CHeadRowNum:=CurGrid. FixedRows-1; {Відображаємо таблицю, що підготована для розв'язування:} Self. WriteTableToGrid (Self.CHeadColNum, Self.CHeadRowNum); Self.LTaskPrepared:=True; End; PrepareToSolveLTask:=True; End Else Begin If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_WrongEditMode); PrepareToSolveLTask:=False; End; End; Function TGridFormattingProcs. PrepareDFuncForSimplexMaximize: Boolean; Var ToMax: Boolean; Row, Col, CurWidth, DFuncRowNum: Integer; Const sc_CurProcName='PrepareDFuncForSimplexMaximize'; Begin CurWidth:=Length (Self. CurHeadRow); DFuncRowNum:=Length (Self. CurHeadCol) – 1; Case Self. CurHeadCol[DFuncRowNum].ElmType of {перевіряємо тип функції мети:} bc_DestFuncToMax: ToMax:=True; bc_DestFuncToMin: ToMax:=False; Else {якщо заданий рядок виявився не функцією мети:} Begin If Self. CurOutConsole<>Nil then Self. CurOutConsole. Lines. Add (sc_CurProcName+ sc_CurRowNotMarkedAsDestFunc+IntToStr (DFuncRowNum+1)); PrepareDFuncForSimplexMaximize:=False; Exit; End; End; {Готуємо умову для вирішування симплекс-методом максимізації:} {Міняємо знаки у елементів рядка-заголовка, окрім знака останньої комірки – то множник для стовпця правих частин. Це є інтерпретацією перенесення усіх доданків у праву частину, і форматом для виконання модифікованих Жорданових виключень:} For Col:=0 to CurWidth-2 do ChangeSignForValOrVarName (Self. CurHeadRow[Col]); {Якщо треба шукати максимум, то множимо коефіцієнти функції мети на -1 (окрім вільгого члена), бо помножили і усі x1…xn на -1. Якщо треба мінімум, то ці коефіцієнти не множимо (бо x1…xn вже помножені), але множимо вільний член функції. Тоді отримаємо протилежну функцію, щоб знайти її максимум (це протилежний мінімум заданої функції):} Row:=Length (Self. CurHeadCol) – 1; {рядок функції мети} If ToMax then Begin For Col:=0 to CurWidth-2 do {коефіцієнти функції мети міняють знаки:} Self. CurTable [Row, Col]:=-Self. CurTable [Row, Col]; End Else {Якщо треба знайти мінімум:} Begin {Множимо вільний член функції мети на -1:} Self. CurTable [Row, CurWidth-1]:=-Self. CurTable [Row, CurWidth-1]; {Назва функції теж міняє знак:} ChangeSignForValOrVarName (Self. CurHeadCol[Row]); {Тепер це протилежна функція для максимізації:} 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 ( Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 |
|
|||||||||||||||||||||||||||||
![]() |
|
Рефераты бесплатно, реферат бесплатно, курсовые работы, реферат, доклады, рефераты, рефераты скачать, рефераты на тему, сочинения, курсовые, дипломы, научные работы и многое другое. |
||
При использовании материалов - ссылка на сайт обязательна. |