Курсовая работа: Багатокритеріальна задача лінійного програмування
sc_NoDestFuncs=': немає рядків функцій мети! Задачу не розумію…';
sc_OnlyDestFuncsPresent=': у таблиці всі рядки є записами функцій мети!..';
sc_ForDestFunc=': для функції: ';
sc_SearchingMin='шукаю мінімум';
sc_SearchingMax='шукаю максимум';
sc_CalculatingNoOptMeasures=': підраховую міри неоптимальності…';
sc_AllMeasurIsZero=': усі міри рівні нулю, додаю до них одиницю…';
sc_UniqueMeasureCantSetZero=': є тільки одна міра оптимальності (і одна'+
' функція мети). Максимальна за модулем – вона ж. Додавання цієї'+
' максимальної величини замінить її на нуль. Тому заміняю на одиницю…';
sc_WeightCoefs='Вагові коефіцієнти (Li[Func]=ui/W(U)):';
sc_ComprVarVals='Компромісні значення змінних';
sc_DestFuncComprVals='Компромісні значення функцій мети:';
Function ValSign (Const Value:TWorkFloat):TSignVal; overload;
Var Res1:TSignVal;
Begin
Res1:=bc_Zero;
If Value<0 then Res1:=bc_Negative
Else if Value>0 then Res1:=bc_Positive;
ValSign:=Res1;
End;
Function ValSign (Const Value:TValOrName):TSignVal; overload;
Var Res1:TSignVal;
Begin
If Value. ElmType=bc_Number then
Res1:=ValSign (Value. AsNumber)
Else
Begin
If Pos (sc_Minus, Value. AsVarName)=1 then Res1:=bc_Negative
Else Res1:=bc_Positive;
End;
ValSign:=Res1;
End;
Function GetValOrNameAsStr (Const Value:TValOrName):String;
Begin
If Value. ElmType=bc_Number then
GetValOrNameAsStr:=FloatToStr (Value. AsNumber)
Else GetValOrNameAsStr:=Value. AsVarName;
End;
Procedure DeleteFromArr (Var SArr:TValOrNameMas; Index, Count: Integer); overload;
{Процедура для видалення з одновимірного масиву чисел чи назв змінних
SArr одного або більше елементів, починаючи з елемента з номером Index.
Видаляється Count елементів (якщо вони були у масиві починаючи із елемента
з номером Index).}
Var CurElm: Integer;
Begin
If Count<=0 then Exit; {якщо немає елементів для видалення}
{Якщо є хоч один елемент із заданих для видалення:}
If Length(SArr)>=(Index+1) then
Begin
{Якщо у масиві немає так багато елементів, скільки холіли видалити, то
коригуємо кількість тих, що видаляємо:}
If (Index+Count)>Length(SArr) then Count:=Length(SArr) – Index;
{Зсуваємо елементи масиву вліво, що залишаються справа після видалення
заданих:}
For CurElm:=Index to (Length(SArr) – 1-Count) do
SArr[CurElm]:=SArr [CurElm+Count];
{Видаляємо з масиву зайві елементи справа:}
SetLength (SArr, Length(SArr) – Count);
End;
End;
Procedure DeleteFromArr (Var SArr:TFloatArr; Index, Count: Integer); overload;
{Процедура для видалення з одновимірного масиву дійсних чисел
SArr одного або більше елементів, починаючи з елемента з номером Index.
Видаляється Count елементів (якщо вони були у масиві починаючи із елемента
з номером Index).}
Var CurElm: Integer;
Begin
If Count<=0 then Exit; {якщо немає елементів для видалення}
{Якщо є хоч один елемент із заданих для видалення:}
If Length(SArr)>=(Index+1) then
Begin
{Якщо у масиві немає так багато елементів, скільки холіли видалити, то
коригуємо кількість тих, що видаляємо:}
If (Index+Count)>Length(SArr) then Count:=Length(SArr) – Index;
{Зсуваємо елементи масиву вліво, що залишаються справа після видалення
заданих:}
For CurElm:=Index to (Length(SArr) – 1-Count) do
SArr[CurElm]:=SArr [CurElm+Count];
{Видаляємо з масиву зайві елементи справа:}
SetLength (SArr, Length(SArr) – Count);
End;
End;
Procedure DelColsFromMatr (Var SDMatrix:TFloatMatrix; ColIndex, Count: Integer);
{Процедура для видалення із матриці дійсних чисел
SHeadArr одного або більше стовпців, починаючи зі стовпця з номером ColIndex.
Видаляється Count стовпців (якщо вони були у матриці починаючи зі стовпця
з номером ColIndex).}
Var CurRow: Integer;
Begin
If Count<=0 then Exit; {якщо немає елементів для видалення}
{Видаляємо елементи у вказаних стовпцях з кожного рядка. Так
видалимо стовпці:}
For CurRow:=0 to (Length(SDMatrix) – 1) do
Begin
DeleteFromArr (SDMatrix[CurRow], ColIndex, Count);
End;
End;
Procedure DelRowsFromMatr (Var SDMatrix:TFloatMatrix; RowIndex, Count: Integer);
{Процедура для видалення із матриці дійсних чисел
SHeadArr одного або більше рядків, починаючи з рядка з номером RowIndex.
Видаляється Count рядків (якщо вони були у матриці починаючи з рядка
з номером RowIndex).}
Var CurElm: Integer;
Begin
If Count<=0 then Exit; {якщо немає елементів для видалення}
{Якщо є хоч один рядок із заданих для видалення:}
If Length(SDMatrix)>=(RowIndex+1) then
Begin
{Якщо у матриці немає так багато рядків, скільки холіли видалити, то
коригуємо кількість тих, що видаляємо:}
If (RowIndex+Count)>Length(SDMatrix) then Count:=Length(SDMatrix) – RowIndex;
{Зсуваємо рядки матриці вгору, що залишаються знизу після видалення
заданих:}
For CurElm:=RowIndex to (Length(SDMatrix) – 1-Count) do
SDMatrix[CurElm]:=SDMatrix [CurElm+Count];
{Видаляємо з матриці зайві рядки знизу:}
SetLength (SDMatrix, Length(SDMatrix) – Count);
End;
End;
Procedure ChangeSignForValOrVarName (Var SDValOrName:TValOrName);
{Зміна знаку числа або перед іменем змінної:}
Begin
If SDValOrName. ElmType=bc_Number then {для числа:}
SDValOrName. AsNumber:=-SDValOrName. AsNumber
Else {для рядка-назви:}
Begin
If Pos (sc_Minus, SDValOrName. AsVarName)=1 then
Delete (SDValOrName. AsVarName, 1, Length (sc_Minus))
Else SDValOrName. AsVarName:=sc_Minus+SDValOrName. AsVarName;
End;
End;
{Жорданове виключення за заданим розв'язувальним елементом матриці:}
Function TGridFormattingProcs.GI (RozElmCol, RozElmRow: Integer;
Var SDHeadRow, SDHeadCol:TValOrNameMas; Var SDMatrix:TFloatMatrix;
Var DColDeleted: Boolean;
ToDoMGI: Boolean=False; {прапорець на модифіковане Жорданове виключення}
ToDelColIfZeroInHRow: Boolean=True):Boolean;
{Функція виконує Жорданове виключення для елемента матриці
SDMatrix з координатами (RozElmCol, RozElmRow). Окрім обробки матриці,
здійснюється заміна місцями елементів у рядку і стовпцю-заголовках
матриці (SDHeadRow, SDHeadCol).
Вхідні дані:
RozElmCol – номер стовпця матриці, у якому лежить розв'язувальний елемент.
нумерація з нуля;
RozElmRow – номер рядка матриці, у якому лежить розв'язувальний елемент.
нумерація з нуля.
Розв'язувальний елемент не повинен бути рівним нулю, інакше виконання
Жорданового виключення не можливе;
SDHeadRow, SDHeadCol – рядок і стовпець-заголовки матриці. Рядок-заголовок
SDHeadRow повинен мати не менше елементів, ніж є ширина матриці. Він
містить множники. Стовпець-заголовок SDHeadCol повинен бути не коротшим
за висоту матриці. Він містить праві частини рівнянь (чи нерівностей)
системи. Рівняння полягають у тому що значення елементів
стовпця-заголовка прирівнюються до суми добутків елементів відповідного
рядка матриці і елементів рядка-заголовка. Елементи у цих заголовках
можуть бути числами або рядками-іменами змінних. Якщо довжина
рядка-заголовка менша за ширину або стовпця-заголовка менша за висоту
матриці, то частина комірок матриці, що виходять за ці межі, буде
проігнорована;
SDMatrix – матриця, у якій виконується Жорданове виключення;
ToDoMGI – прапорець, що вмикає режим модифікованого Жорданового виключення
(при ToDoMGI=True здійснюється модифіковане, інакше – звичайне).
Модифіковане Жорданове виключення використовується для матриці, у якій
було змінено знак початкових елементів, і змінено знаки елементів-
множників у рядку-заголовку. Використовується для симплекс-методу.
ToDelColIfZeroInHRow – прапорець, що вмикає видалення стовпця матриці із
розв'язувальним елементом, якщо після здійснення жорданівського
виключення у рядок-заголовок зі стовпця-заголовка записується число нуль.
Вихідні дані:
SDHeadRow, SDHeadCol – змінені рядок та стовпець-заголовки. У них
міняються місцями елементи, що стоять навпроти розв'язувального елемента
(у його стовпці (для заголовка-рядка) і рядку (для заголовка-стовпця).
У заголовку-рядку такий елемент після цього може бути видалений, якщо
він рівний нулю і ToDelColIfZeroInHRow=True.
Тобто Жорданове виключення змінює ролями ці елементи (виражає один
через інший у лінійних рівняннях чи нерівностях);
SDMatrix – матриця після виконання Жорданового виключення;
DColDeleted – ознака того, що при виконанні Жорданового виключення
був видалений розв'язувальний стовпець із матриці (у його комірці
у рядку-заголовку став був нуль).
Функція повертає ознаку успішності виконання Жорданового виключення.
}
Var CurRow, CurCol, RowCount, ColCount: Integer;
SafeHeadElm:TValOrName;
MultiplierIfMGI:TWorkFloat;
CurMessage: String;
Begin
{Визначаємо кількість рядків і стовпців, які можна обробити:}
RowCount:=Length(SDMatrix);
If RowCount<=0 then Begin GI:=False; Exit; End;
ColCount:=Length (SDMatrix[0]);
If Length(SDHeadCol)<RowCount then RowCount:=Length(SDHeadCol);
If Length(SDHeadRow)<ColCount then ColCount:=Length(SDHeadRow);
If (RowCount<=0) or (ColCount<=0) then Begin GI:=False; Exit; End;
{Перевіряємо наявність розв'язуючого елемента у матриці (за координатами):}
If (RozElmCol>(ColCount-1)) or (RozElmRow>(RowCount-1)) then
Begin
CurMessage:=sc_InvCoordsOfResolvingElm+': ['+IntToStr (RozElmCol+1)+';'+
IntToStr (RozElmRow+1)+']'+sc_CrLf+
sc_MatrixSize+': ['+IntToStr(ColCount)+';'+IntToStr(RowCount)+']';
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add(CurMessage);
MessageDlg (CurMessage, mtError, [mbOk], 0);
GI:=False; Exit;
End;
{Якщо розв'язуючий елемент рівний нулю, то виконати Жорданове виключення
неможливо:}
If SDMatrix [RozElmRow, RozElmCol]=0 then
Begin
CurMessage:=sc_ZeroResolvingElm+': ['+IntToStr (RozElmCol+1)+';'+
IntToStr (RozElmRow+1)+']='+FloatToStr (SDMatrix[RozElmRow, RozElmCol]);
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add(CurMessage);
MessageDlg (CurMessage, mtError, [mbOk], 0);
GI:=False; Exit;
End;
{Виконуємо Жорданове виключення у матриці:}
{Обробляємо усі елементи матриці, що не належать до рядка і стовпця
розв'язуючого елемента:}
For CurRow:=0 to RowCount-1 do
For CurCol:=0 to ColCount-1 do
If (CurRow<>RozElmRow) and (CurCol<>RozElmCol) then
Begin
SDMatrix [CurRow, CurCol]:=
(SDMatrix [CurRow, CurCol]*SDMatrix [RozElmRow, RozElmCol] –
SDMatrix [CurRow, RozElmCol]*SDMatrix [RozElmRow, CurCol]) /
SDMatrix [RozElmRow, RozElmCol];
End;
{+1, якщо задано зробити звичайне Жорданове виключення;
-1 – якщо задано модифіковане:}
MultiplierIfMGI:=(1–2*Abs (Ord(ToDoMGI)));
{Елементи стовпця розв'язуючого елемента (окрім його самого)
ділимо на розв'язуючий елемент:}
For CurRow:=0 to RowCount-1 do
If CurRow<>RozElmRow then
SDMatrix [CurRow, RozElmCol]:=MultiplierIfMGI*SDMatrix [CurRow, RozElmCol]/
SDMatrix [RozElmRow, RozElmCol];
{Елементи рядка розв'язуючого елемента (окрім його самого)
ділимо на розв'язуючий елемент з протилежним знаком:}
For CurCol:=0 to ColCount-1 do
If CurCol<>RozElmCol then
SDMatrix [RozElmRow, CurCol]:=-MultiplierIfMGI*SDMatrix [RozElmRow, CurCol]/
SDMatrix [RozElmRow, RozElmCol];
{Заміняємо розв'язуючий елемент на обернене до нього число:}
SDMatrix [RozElmRow, RozElmCol]:=1/SDMatrix [RozElmRow, RozElmCol];
{Міняємо місцями елементи рядка і стовпця-заголовків, що стоять у
стовпці і рядку розв'язуючого елемента:}
SafeHeadElm:= SDHeadRow[RozElmCol];
SDHeadRow[RozElmCol]:=SDHeadCol[RozElmRow];
SDHeadCol[RozElmRow]:=SafeHeadElm;
{Якщо виконуємо модиівковане Жорданове виключення, то змінюють
знаки і ці елементи, що помінялись місцями:}
If ToDoMGI then
Begin
ChangeSignForValOrVarName (SDHeadRow[RozElmCol]);
ChangeSignForValOrVarName (SDHeadCol[RozElmRow]);
End;
DColDeleted:=False;
{Якщо у рядку-заголовку навпроти розв'язуючого елемента опинився нуль,
і задано видаляти у такому випадку цей елемент разом із стовпцем
розв'язуючого елемента у матриці, то видаляємо:}
If ToDelColIfZeroInHRow and (SDHeadRow[RozElmCol].ElmType=bc_Number) then
If SDHeadRow[RozElmCol].AsNumber=0 then
Begin
DeleteFromArr (SDHeadRow, RozElmCol, 1);
DelColsFromMatr (SDMatrix, RozElmCol, 1);
DColDeleted:=True;
End;
GI:=True;
End;
Procedure ChangeRowsPlaces (Var SDMatr:TFloatMatrix; Row1, Row2: Integer);
overload;
Var SafeCurRow:TFloatArr;
Begin
SafeCurRow:=SDMatr[Row1];
SDMatr[Row1]:=SDMatr[Row2];
SDMatr[Row2]:=SafeCurRow;
End;
Procedure ChangeRowsPlaces (Var SDMatr:TFloatMatrix; Var SDHeadCol:TValOrNameMas;
Row1, Row2: Integer; ToChangeInitPosNums: Boolean=False); overload;
{Процедура міняє місцями рядки у таблиці зі стовпцем-заголовком.
Вхідні дані:
SDMatr – таблиця;
SDHeadCol – стовпець-заголовок таблиці;
Row1, Row2 – рядки, що треба поміняти місцями;
ToChangeInitPosNums – вмикач зміни номерів по порядку у
стовпці-заголовку. Якщо рівний True, то рядки, що помінялися місцями,
міняються також і позначками про номер по порядку та розміщення
як рядка чи стовпця (що присвоювалися їм при створенні).
Вихідні дані:
SDMatr – таблиця;
SDHeadCol – стовпець-заголовок таблиці.}
Var SafeCurHeadCell:TValOrName;
Begin
SafeCurHeadCell:=SDHeadCol[Row1];
SDHeadCol[Row1]:=SDHeadCol[Row2];
SDHeadCol[Row2]:=SafeCurHeadCell;
If ToChangeInitPosNums then
Begin
SDHeadCol[Row2].VarInitPos:=SDHeadCol[Row1].VarInitPos;
SDHeadCol[Row2].VarInitInRow:=SDHeadCol[Row1].VarInitInRow;
SDHeadCol[Row1].VarInitPos:=SafeCurHeadCell. VarInitPos;
SDHeadCol[Row1].VarInitInRow:=SafeCurHeadCell. VarInitInRow;
End;
ChangeRowsPlaces (SDMatr, Row1, Row2);
End;
Procedure ChangePlaces (Var SDMas:TFloatArr; Elm1, Elm2: Integer);
Var SafeElm:TWorkFloat;
Begin
SafeElm:=SDMas[Elm1];
SDMas[Elm1]:=SDMas[Elm2];
SDMas[Elm2]:=SafeElm;
End;
Procedure ChangeColsPlaces (Var SDMatr:TFloatMatrix; Col1, Col2: Integer);
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14