Багатокритеріальна задача лінійного програмування
Розв’язок багатокритеріальної задачі лінійного програмування з отриманням компромісного рішення (для задач з кількома функціями мети) за допомогою теоретико-ігрового підходу. Матриця мір неоптимальності та рядок функції мети. Модуль опису класу.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 15.05.2011 |
Размер файла | 588,8 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
(AllowNegatCellIfZero or
(CurTable [CurRowNum, Length (Self. CurHeadRow) - 1]<>0) or
(CurTable [CurRowNum, CurColNum]>0)) and
((ValSign (CurTable[CurRowNum, Length (Self. CurHeadRow) - 1])*
ValSign (CurTable[CurRowNum, CurColNum]))>=0) then
Begin
CurRelat:=CurTable [CurRowNum, Length (Self. CurHeadRow) - 1]/
CurTable [CurRowNum, CurColNum];
{Якщо знайшли менше, або знайшли перше значення:}
If (CurRelat<MNN) or (FoundRow=-1) then
Begin
MNN:=CurRelat; FoundRow:=CurRowNum;
End;
End;
End;
If (Self. CurOutConsole<>Nil) and (FoundRow<0) then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_NoMNN+sc_Space+
IntToStr (CurColNum+1)+sc_Space+sc_TriSpot);
DRowNum:=FoundRow;
End;
Label LStopLabel;
Begin
If Self. TaskWidth<=0 then {Якщо таблиця пуста, то задача пуста:}
Begin
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName + sc_EmptyTable);
SolveLTaskToMax:=False;
Exit;
End;
HeadRowNum:=Self.CHeadRowNum;
HeadColNum:=Self.CHeadColNum;
If Self. CurOutConsole<>Nil then
Begin
Self. CurOutConsole. Lines. Add (sc_CurProcName + sc_StartSolving);
Self. CurOutConsole. Lines. Add (sc_CurProcName + sc_ExcludingFreeVars);
End;
{############## Виключаємо незалежні змінні: ##############}
CurRowNum:=0;
Repeat
WasNothingToDo:=True; AllExcluded:=True;
CurColNum:=0;
While CurColNum<(Length (Self. CurHeadRow) - 1) do {усі стовпці окрім останнього}
Begin
ColDeleted:=False;
{Координати розв'язувальної комірки для помітки кольором в екранній
таблиці:}
Self. CurGridSolveCol:=CurColNum+HeadColNum+bc_LTaskColsBeforeVars;
Self. CurGridSolveRow:=CurRowNum+HeadRowNum+bc_LTaskRowsBeforeVars;
{Якщо поточна змінна незалежна:}
If Self. CurHeadRow[CurColNum].ElmType=bc_IndependentVar then
Begin {Перевіряємо, чи не дійшли до рядка функції
(або взагалі за низ таблиці):}
If CurRowNum<(Length (Self. CurHeadCol) - 1) then
Begin {якщо рядки для виключення ще залишились:}
{Шукаємо ненульову комірку серед коефіцієнтів поточної
незалежної змінної (окрім останнього рядка, що є
рядком поточної функції мети):}
If SearchNozeroSolveCell (CurRowNum, CurColNum,
Length (Self. CurHeadCol) - 2, Length (Self. CurHeadRow) - 2,
HeadRowNum, HeadColNum, False) then
Begin {якщо змінну можна виключити:}
WaitForNewStep (HeadColNum, HeadRowNum);
If Self. Stop then Goto LStopLabel;
{Обробляємо таблицю модифікованим Жордановим виключенням:}
If Not (Self.GI (CurColNum, CurRowNum, Self. CurHeadRow,
Self. CurHeadCol, Self. CurTable, ColDeleted, True,
True)) then
Begin
SolveLTaskToMax:=False; Exit;
End;
WasNothingToDo:=False;
{Переходимо до наступного рядка, бо даний рядок тепер вже є
рядком виключеної вільної змінної (і змінна виражена як
функція-нерівність):}
Inc(CurRowNum);
End
Else {якщо для незалежної змінної усі коефіцієнти обмежень - нулі}
Begin {то змінна зовсім незалежна:}
{І якщо в рядку функції мети теж нуль, то:}
If Self. CurTable [Length(Self. CurHeadCol) - 1, CurColNum]=0 then
Begin {хоч змінна й незалежна, від неї теж нічого тут не залежить:}
If Self. CurOutConsole<>Nil then
Begin
st1:=sc_CurProcName+sc_FreeVar;
If Self. CurHeadRow[CurColNum].ElmType=bc_Number then
st1:=st1+sc_Space+
FloatToStr (Self. CurHeadRow[CurColNum].AsNumber)
Else st1:=st1+sc_Space+sc_DoubleQuot+
Self. CurHeadRow[CurColNum].AsVarName+sc_DoubleQuot;
Self. CurOutConsole. Lines. Add(st1);
End;
WaitForNewStep (HeadColNum, HeadRowNum);
If Self. Stop then Goto LStopLabel;
{Видаляємо стовпець цієї змінної:}
DeleteFromArr (Self. CurHeadRow, CurColNum, 1);
DelColsFromMatr (Self. CurTable, CurColNum, 1);
ColDeleted:=True;
WasNothingToDo:=False;
End
Else AllExcluded:=False; {не усі вільні вдалося виключити}
End;
End
Else AllExcluded:=False; {не усі вільні вдалося виключити}
End;
If Not(ColDeleted) then Inc(CurColNum);
End; {While (CurColNum<(Length (Self. CurHeadRow) - 1)) do…}
Until AllExcluded or WasNothingToDo;
If Not(AllExcluded) then
Begin
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_CantExcludeFreeVars);
Self. WriteTableToGrid (HeadColNum, HeadRowNum, True);
SolveLTaskToMax:=True; Exit;
End;
{Переміщаємо рядки з усіма незалежними змінними вгору:}
HiNoIndepRow:=Self. ShiftRowsUp([bc_IndependentVar], False);
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_AllFreeVarsExcluded);
{Ховаємо розв'язувальну комірку у екранній таблиці:}
Self. CurGridSolveCol:=0; Self. CurGridSolveRow:=0;
WaitForNewStep (HeadColNum, HeadRowNum);
If Self. Stop then Goto LStopLabel;
{Якщо усі рядки є рядками незалежних змінних, то номер найвищого рядка
іншого типу вважаємо нижче таблиці (бо нема таких рядків):}
If HiNoIndepRow<0 then HiNoIndepRow:=Length (Self. CurHeadCol);
{Якщо після виключення незалежних змінних не залишилося рядків, окрім
рядка функції:}
If HiNoIndepRow>=(Length (Self. CurHeadCol) - 1) then
Begin
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_NoTableAreaToWork);
End;
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_ExcludingZeroRows);
{############## Виключаємо 0-рядки. Шукаємо їх: ##############}
CurRowNum:=HiNoIndepRow;
While CurRowNum<=(Length (Self. CurHeadCol) - 2) do
Begin
RowDeleted:=False;
If Self. CurHeadCol[CurRowNum].ElmType=bc_Number then
Begin
If Self. CurHeadCol[CurRowNum].AsNumber=0 then {якщо знайшли 0-рядок:}
Begin {Для помітки 0-рядка на екранній таблиці:}
Self. CurGridSolveCol:=HeadColNum;
Self. CurGridSolveRow:=CurRowNum+HeadRowNum+bc_LTaskRowsBeforeVars;
WaitForNewStep (HeadColNum, HeadRowNum);
If Self. Stop then Goto LStopLabel;
{Перевіряємо вільний член рядка, чи він невід'ємний.
Якщо від'ємний, то множимо обидві частини рівняння на -1:}
If CurTable [CurRowNum, Length (Self. CurHeadRow) - 1]<0 then
ChangeSignsInRow(CurRowNum);
{Шукаємо у рядку перший додатний коефіцієнт:}
For CurColNum:=0 to Length (Self. CurHeadRow) - 2 do
If CurTable [CurRowNum, CurColNum]>0 then Break;
If CurColNum>(Length (Self. CurHeadRow) - 2) then {Якщо усі недодатні:}
Begin
If CurTable [CurRowNum, Length (Self. CurHeadRow) - 1]=0 then
Begin {Якщо вільний член рівний нулю, то помножимо рівняння на -1:}
ChangeSignsInRow(CurRowNum);
{Шукаємо у рядку перший додатний коефіцієнт:}
For CurColNum:=0 to Length (Self. CurHeadRow) - 2 do
If CurTable [CurRowNum, CurColNum]>0 then Break;
{Якщо знову додатних нема, значить усі нулі. Видаляємо рядок:}
If CurColNum>(Length (Self. CurHeadRow) - 2) then
Begin
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_AllZeroInRow+
sc_Space+IntToStr (CurRowNum+1));
DelRowsFromMatr (CurTable, CurRowNum, 1);
DeleteFromArr (Self. CurHeadCol, CurRowNum, 1);
System. Continue; {переходимо одразу до наступного рядка}
End;
End
Else {Якщо вільний член додатній, а коефіцієнти недодатні, то
система несумісна:}
Begin
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_DoubleSpot+
sc_Space+sc_NoVals);
Self. WasNoRoots:=True;
Self. WriteTableToGrid (HeadColNum, HeadRowNum, True);
SolveLTaskToMax:=True; Exit;
End;
End;
{Якщо додатний коефіцієнт у 0-рядку обрано, шукаємо МНВ
(мінімальне невід'ємне серед відношень вільних членів до членів
стовпця, у якому обрали цей коефіцієнт):}
SearchMNNCellForCol (CurColNum, HiNoIndepRow, Length (Self. CurHeadCol) - 2,
CurRow2N, False);
If CurRow2N<0 then {Якщо МНВ не знайдено:}
Begin
Self. WriteTableToGrid (HeadColNum, HeadRowNum, True);
SolveLTaskToMax:=False; Exit;
End;
{Якщо МНВ знайдено:}
Self. CurGridSolveCol:=CurColNum + HeadColNum+bc_LTaskColsBeforeVars;
Self. CurGridSolveRow:=CurRow2N + HeadRowNum+bc_LTaskRowsBeforeVars;
WaitForNewStep (HeadColNum, HeadRowNum);
If Self. Stop then Goto LStopLabel;
{Обробляємо таблицю модифікованим Жордановим виключенням:}
If Not (Self.GI (CurColNum, CurRow2N, Self. CurHeadRow,
Self. CurHeadCol, Self. CurTable, ColDeleted, True,
True)) then
Begin
SolveLTaskToMax:=False; Exit;
End;
If CurRow2N<>CurRowNum then {Якщо виключили не цей 0-рядок:}
System. Continue; {продовжуємо працювати з цим рядком}
End; {If Self. CurHeadCol[CurRowNum].AsNumber=0 then…}
End; {If Self. CurHeadCol[CurRowNum].ElmType=bc_Number then…}
If Not(RowDeleted) then Inc(CurRowNum);
End; {While CurRowNum<=(Length (Self. CurHeadCol) - 2) do…}
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_AllZeroRowsExcluded);
{Ховаємо розв'язувальну комірку у екранній таблиці:}
Self. CurGridSolveCol:=0; Self. CurGridSolveRow:=0;
WaitForNewStep (HeadColNum, HeadRowNum); {відмічаємо новий крок}
If Self. Stop then Goto LStopLabel;
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_SearchingBaseSolve);
{############## Шукаємо опорний розв'язок задачі: ##############}
CurRowNum:=HiNoIndepRow;
While CurRowNum<=(Length (Self. CurHeadCol) - 2) do
Begin
{Якщо знайшли від'ємний елемент у стовпці вільних членів:}
If Self. CurTable [CurRowNum, Length (Self. CurHeadRow) - 1]<0 then
Begin
{Для помітки поточного рядка на екранній таблиці:}
Self. CurGridSolveCol:=HeadColNum;
Self. CurGridSolveRow:=CurRowNum+HeadRowNum+bc_LTaskRowsBeforeVars;
WaitForNewStep (HeadColNum, HeadRowNum);
If Self. Stop then Goto LStopLabel;
{Шукаємо у рядку перший від'ємний коефіцієнт:}
For CurColNum:=0 to Length (Self. CurHeadRow) - 2 do
If CurTable [CurRowNum, CurColNum]<0 then Break;
If CurColNum>(Length (Self. CurHeadRow) - 2) then {Якщо усі невід'ємні:}
Begin
{Якщо вільний член від'ємний, а коефіцієнти невід'ємні, то
система несумісна:}
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_DoubleSpot+sc_Space+
sc_NoVals);
Self. WasNoRoots:=True;
Self. WriteTableToGrid (HeadColNum, HeadRowNum, True);
SolveLTaskToMax:=True; Exit;
End;
{Якщо від'ємний коефіцієнт у рядку обрано, шукаємо МНВ
(мінімальне невід'ємне серед відношень вільних членів до членів
стовпця, у якому обрали цей коефіцієнт):}
SearchMNNCellForCol (CurColNum, HiNoIndepRow, Length (Self. CurHeadCol) - 2,
CurRow2N, False);
If CurRow2N<0 then {Якщо МНВ не знайдено:}
Begin
Self. WriteTableToGrid (HeadColNum, HeadRowNum, True);
SolveLTaskToMax:=False; Exit;
End;
{Якщо МНВ знайдено:}
Self. CurGridSolveCol:=CurColNum + HeadColNum+bc_LTaskColsBeforeVars;
Self. CurGridSolveRow:=CurRow2N + HeadRowNum+bc_LTaskRowsBeforeVars;
WaitForNewStep (HeadColNum, HeadRowNum);
If Self. Stop then Goto LStopLabel;
{Обробляємо таблицю модифікованим Жордановим виключенням:}
If Not (Self.GI (CurColNum, CurRow2N, Self. CurHeadRow,
Self. CurHeadCol, Self. CurTable, ColDeleted, True,
True)) then
Begin
SolveLTaskToMax:=False; Exit;
End;
If CurRow2N<>CurRowNum then {Якщо виключили не цей рядок:}
System. Continue; {продовжуємо працювати з цим рядком}
End; {If Self. CurTable [CurRowNum, Length (Self. CurHeadRow) - 1]<0 then…}
Inc(CurRowNum);
End; {While CurRowNum<=(Length (Self. CurHeadCol) - 2) do…}
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_BaseSolveFound);
{Ховаємо розв'язувальну комірку у екранній таблиці:}
Self. CurGridSolveCol:=0; Self. CurGridSolveRow:=0;
WaitForNewStep (HeadColNum, HeadRowNum); {відмічаємо новий крок}
If Self. Stop then Goto LStopLabel;
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_SearchingOptimSolve);
{############## Шукаємо оптимальний розв'язок задачі: ##############}
CurColNum:=0;
While CurColNum<=(Length (Self. CurHeadRow) - 2) do
Begin
ColDeleted:=False;
{Якщо знайшли від'ємний коефіцієнт у рядку функції мети:}
If CurTable [Length(Self. CurHeadCol) - 1, CurColNum]<0 then
Begin
{Шукаємо МНВ (мінімальне невід'ємне серед відношень вільних членів
до членів стовпця, у якому обрали цей коефіцієнт) серед усіх рядків
умов, окрім рядків вільних змінних і рядка функції мети:}
SearchMNNCellForCol (CurColNum, HiNoIndepRow, Length (Self. CurHeadCol) - 2,
CurRow2N, False);
If CurRow2N<0 then {Якщо МНВ не знайдено:}
Begin {то функція мети не обмежена зверху, максимальне значення безмежне:}
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_DoubleSpot+sc_Space+
sc_UnlimitedFunc);
Self. WasManyRoots:=True;
Self. WriteTableToGrid (HeadColNum, HeadRowNum, True);
SolveLTaskToMax:=True; Exit;
End;
{Якщо МНВ знайдено:}
Self. CurGridSolveCol:=CurColNum + HeadColNum+bc_LTaskColsBeforeVars;
Self. CurGridSolveRow:=CurRow2N + HeadRowNum+bc_LTaskRowsBeforeVars;
WaitForNewStep (HeadColNum, HeadRowNum);
If Self. Stop then Goto LStopLabel;
{Обробляємо таблицю модифікованим Жордановим виключенням:}
If Not (Self.GI (CurColNum, CurRow2N, Self. CurHeadRow,
Self. CurHeadCol, Self. CurTable, ColDeleted, True,
True)) then
Begin
SolveLTaskToMax:=False; Exit;
End;
CurColNum:=0; {після виключення могли з'явитися нові від'ємні комірки}
System. Continue;
End;
If Not(ColDeleted) then Inc(CurColNum);
End;
{Якщо назва функції мети вказана зі знаком «-», то це протилежна
функція мети. Змінимо знаки у її рядку, і отримаємо шукану
мінімізацію функції:}
CurRowNum:=Length (Self. CurHeadCol) - 1;
If ValSign (Self. CurHeadCol[CurRowNum])=bc_Negative then
Begin
ChangeSignsInRow(CurRowNum);
Self. CurHeadCol[CurRowNum].ElmType:=bc_DestFuncToMin;
End;
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_DoubleSpot+sc_Space+
sc_ValFound);
Self. ShowLTaskResultCalc(DualTaskVals);
Self. SolWasFound:=True;
SolveLTaskToMax:=True;
{Ховаємо розв'язувальну комірку у екранній таблиці:}
Self. CurGridSolveCol:=0; Self. CurGridSolveRow:=0;
WaitForNewStep (HeadColNum, HeadRowNum);
Exit;
LStopLabel:
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName + sc_SolvingStopped);
Self. CurGridSolveCol:=0; Self. CurGridSolveRow:=0;
SolveLTaskToMax:=False;
Exit;
End;
procedure TGridFormattingProcs. EditLineEqsOnNewRow (Sender: TObject;
NewRows: array of Integer);
{Підтримує форматування стовпця нумерації таблиці у такому вигляді:
1
2
3
4
5
…
m}
Var CurNum: Integer; CurGrid:TStringGrid;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnNewRow<>Nil then Self. OldOnNewRow (Sender, NewRows);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
For CurNum:=0 to Length(NewRows) - 1 do
Begin
{Нумерація з третього рядка, бо два перших - заголовки:}
If NewRows[CurNum]>=(Self.CHeadRowNum+1) then
Begin
CurGrid. Cells [0, NewRows[CurNum]]:=IntToStr (NewRows[CurNum]-
Self.CHeadRowNum);
End;
End;
End;
End;
procedure TGridFormattingProcs. EditLineEqsOnNewCol (Sender: TObject;
NewCols: array of Integer);
{Підтримує форматування рядка нумерації та рядка-заголовка таблиці у
такому вигляді:
1 2 3 4 5… n n+1
x1 x2 x3 x4 x5… xn 1
}
Var CurNum: Integer; CurGrid:TStringGrid;
CurColNumStr: String;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnNewCol<>Nil then Self. OldOnNewCol (Sender, NewCols);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
For CurNum:=0 to Length(NewCols) - 1 do
Begin
{Заголовки лише для комірок, які можна редагувати:}
If NewCols[CurNum]>=(Self.CHeadColNum+1) then
Begin
CurColNumStr:=IntToStr (NewCols[CurNum] - Self.CHeadColNum);
CurGrid. Cells [NewCols[CurNum], 0]:=CurColNumStr;
{Останній стовпець - числа у правих частинах рівнянь:}
If (NewCols[CurNum]+1)=CurGrid. ColCount then
CurGrid. Cells [NewCols[CurNum], 1]:=sc_RightSideValsHdr
{в усіх інших - коефіцієнти при змінних X1…Xn:}
Else
CurGrid. Cells [NewCols[CurNum], 1]:=sc_XVarName+CurColNumStr;
End;
End;
If Length(NewCols)>0 then
Begin
{Якщо перед оновленими або новими стовпцями були інші стовпці, то
в останному з них оновлюємо підпис: тепер він буде з іменем змінної
(«xn»), а не з іменем стовпця правих частин рівнянь (a).
(Тут покладаємося на те, що номери оновлених стовпців сортовані
за зростанням):}
If NewCols[0]>(Self.CHeadColNum+1) then
CurGrid. Cells [NewCols[0] - 1, 1]:=sc_XVarName+IntToStr (NewCols[0]-
(Self.CHeadColNum+1));
End
Else {Якщо нових стовпців немає (тобто кількість стовпців зменшилася):}
Begin {Оновлюємо підпис останнього стовпця (праві частини рівнянь):}
CurGrid. Cells [CurGrid. ColCount-1, 1]:=sc_RightSideValsHdr;
End;
End;
End;
procedure TGridFormattingProcs. EditLineEqsOnDrawCell (Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
{Процедура виконується при малюванні кожної комірки StringGrid
у режимі набору вхідних даних системи лінійних рівнянь.
Зафарбовує в інший колір останній стовпець - стовпець
правих частин рівнянь.}
Var CurGrid:TStringGrid; SafeBrushColor:TColor;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnDrawCell<>Nil then Self. OldOnDrawCell (Sender, ACol, ARow, Rect,
State);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
SafeBrushColor:=CurGrid. Canvas. Brush. Color;
{Комірки останнього стовпця є стовпцем правих сторін рівнянь.
Фарбуємо їх у блакитний колір (окрім комірок заголовка):}
If (ACol>=(CurGrid. ColCount-bc_LineEqM2ColsAfterVars)) and
(Not (gdFixed in State)) then
Begin
CurGrid. Canvas. Brush. Color:=lwc_RightSideColColor;
{Малюємо текст на фоні з кольором Brush:}
CurGrid. Canvas. TextRect (Rect, Rect. Left, Rect. Top,
CurGrid. Cells [ACol, ARow]);
End;
CurGrid. Canvas. Brush. Color:=SafeBrushColor;
End;
End;
procedure TGridFormattingProcs. SolveLineEqsM1OrM2OnDrawCell (Sender: TObject;
ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
{Процедура фарбує комірки (їхній фон) таблиці вирішування системи лінійних
рівнянь у стовпці правих частин (вільних членів). У залежності від
методу розв'язання цей стопець може бути першим стовпцем-заголовком
(1-ий спосіб, з отриманням оберненої матриці коефіцієнтів), або останнім
стовпцем (2-ий спосіб, з отриманням нулів у рядку-заголовку і видаленням
стовпців цих нулів).}
Var CurGrid:TStringGrid; SafeBrushColor:TColor; CurColor:TColor;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnDrawCell<>Nil then Self. OldOnDrawCell (Sender, ACol, ARow, Rect,
State);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
SafeBrushColor:=CurGrid. Canvas. Brush. Color;
CurColor:=bc_NotColored;
If Not (gdFixed in State) then {якщо комірка не у заголовках StringGrid}
Begin
{У режимі розв'язування способом 1 відмічаємо перший стовпець
кольором, а у режимі способу 2 - відмічаємо останній
(стовпець правих частин - вільних членів):}
If ((Self. CurFormatState=fs_SolvingEqsM1) and
(ACol<(Self.CHeadColNum+bc_LineEqM1ColsBeforeVars))) or
((Self. CurFormatState=fs_SolvingEqsM2) and
(ACol>=(CurGrid. ColCount-bc_LineEqM2ColsAfterVars))) then
CurColor:=lwc_RightSideColColor
{Якщо це комірка коефіцієнта при змінній, і задача у ході вирішування:}
Else if InSolving then
Begin
If Self. CurGridSolveCol=ACol then {якщо це розв'язувальний стовпець:}
Begin
If Self. CurGridSolveRow=ARow then {якщо це розв'язувальна комірка:}
CurColor:=lwc_SolveCellColor
Else CurColor:=lwc_SolveColColor;
End {Якщо це розв'язувальний рядок (але не розв'язувальна комірка):}
Else if Self. CurGridSolveRow=ARow then CurColor:=lwc_SolveRowColor;
End;
End;
If CurColor<>bc_NotColored then {якщо комірку треба пофарбувати:}
Begin {Малюємо текст на фоні з кольором CurColor:}
CurGrid. Canvas. Brush. Color:=CurColor;
CurGrid. Canvas. TextRect (Rect, Rect. Left, Rect. Top,
CurGrid. Cells [ACol, ARow]);
End;
CurGrid. Canvas. Brush. Color:=SafeBrushColor;
End;
End;
procedure TGridFormattingProcs. EdLineTaskOnNewRow (Sender: TObject;
NewRows: array of Integer);
{Процедура працює при виникненні події оновлення рядка чи додавання нового
рядка у GrowingStringGrid.
Підтримує форматування стовпця нумерації і стовпця-заголовка таблиці у
такому вигляді:
1 y1
2 y2
3 y3
4 y4
5 y5
…
m ym
Стовпець-заголовок (нові комірки стовпця-заголовка за змовчуванням
заповнюються значеннями типу «функції-нерівності»).}
Var CurNum, CurTableRow: Integer; CurGrid:TStringGrid;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnNewRow<>Nil then Self. OldOnNewRow (Sender, NewRows);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
{Освіжаємо масив стовпця-заголовка відповідно до висоти таблиці:}
UpdateLTaskHeadColToStrGrid (CurGrid, NewRows);
{Відображаємо заголовки оновлених або нових рядків:}
For CurNum:=0 to Length(NewRows) - 1 do
Begin
{Нумерація з першого рядка, що не є рядком заголовків:}
If NewRows[CurNum]>=(Self.CHeadRowNum+1) then
Begin {Нумерація рядків:}
CurGrid. Cells [Self.CHeadColNum-1, NewRows[CurNum]]:=
IntToStr (NewRows[CurNum] - Self.CHeadRowNum);
{Заголовки із масиву стовпця-заголовка:}
CurTableRow:=NewRows[CurNum] - Self.CHeadRowNum-bc_LTaskRowsBeforeVars;
CurGrid. Cells [Self.CHeadColNum, NewRows[CurNum]]:=
GetValOrNameAsStr (Self. CurHeadCol[CurTableRow]);
End;
End;
{Якщо нові або змінені рядки були, то вважаємо таблицю зміненою:}
If Length(NewRows)>0 then Self. CurGridModified:=True;
End;
End;
procedure TGridFormattingProcs. EdLineTaskOnNewCol (Sender: TObject;
NewCols: array of Integer);
{Підтримує форматування рядка нумерації та рядка-заголовка таблиці у
такому вигляді:
1 2 3 4 5… n n+1
y x1 x2 x3 x4… xn 1
}
Var CurNum, CurTableCol: Integer; CurGrid:TStringGrid;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnNewCol<>Nil then Self. OldOnNewCol (Sender, NewCols);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
{Освіжаємо масив поміток залежності змінних x:}
Self. UpdateLTaskHeadRowToStrGrid(CurGrid);
{Відображаємо заголовки оновлених або нових стовпців:}
For CurNum:=0 to Length(NewCols) - 1 do
Begin
{Заголовки лише для комірок, які можна редагувати:}
If NewCols[CurNum]>=Self.CHeadColNum then
Begin {Нумерація стовпців:}
CurGrid. Cells [NewCols[CurNum], Self.CHeadRowNum-1]:=
IntToStr (NewCols[CurNum] - Self.CHeadColNum);
{Заголовки із масиву рядка-заголовка:}
CurTableCol:=NewCols[CurNum] - Self.CHeadColNum-bc_LTaskColsBeforeVars;
CurGrid. Cells [NewCols[CurNum], Self.CHeadRowNum]:=
GetValOrNameAsStr (Self. CurHeadRow[CurTableCol]);
End;
End;
If Length(NewCols)>0 then
Begin
{Якщо нові або змінені стовпці були, то вважаємо таблицю зміненою:}
Self. CurGridModified:=True;
{Якщо перед оновленими або новими стовпцями були інші стовпці, то
в останному з них оновлюємо підпис: тепер він буде з іменем змінної
(«xn») або, якщо це перший стовпець-то з підписом стовпця імен
функцій та констант рівнянь.
(Тут покладаємося на те, що номери оновлених стовпців сортовані
за зростанням):}
If NewCols[0]>Self.CHeadColNum+bc_LTaskColsBeforeVars then
Begin
CurTableCol:=NewCols[0] - 1-Self.CHeadColNum-bc_LTaskColsBeforeVars;
CurGrid. Cells [NewCols[0] - 1, Self.CHeadRowNum]:=
GetValOrNameAsStr (Self. CurHeadRow[CurTableCol]);
End;
End
Else {Якщо нових стовпців нема (кількість стовпців зменшилася):}
{відображаємо останню (найправішу) комірку}
CurGrid. Cells [CurGrid. ColCount-1, 1]:=
GetValOrNameAsStr (Self. CurHeadRow [CurGrid. ColCount-1-
Self.CHeadColNum-bc_LTaskColsBeforeVars]);
End;
End;
procedure TGridFormattingProcs. NumerationOnNewRow (Sender: TObject;
NewRows: array of Integer);
{Процедура працює при виникненні події оновлення рядка чи додавання нового
рядка у GrowingStringGrid.
Підтримує форматування стовпця нумерації таблиці у
такому вигляді:
1
2
3
4
5
…
m}
Var CurNum: Integer; CurGrid:TStringGrid;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnNewRow<>Nil then Self. OldOnNewRow (Sender, NewRows);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
For CurNum:=0 to Length(NewRows) - 1 do
Begin
{Нумерація з першого рядка, що не є рядком заголовків
GrowingStringGrid:}
If NewRows[CurNum]>=(Self.CHeadRowNum+1) then
CurGrid. Cells [0, NewRows[CurNum]]:=
IntToStr (NewRows[CurNum] - Self.CHeadRowNum);
End; {For CurNum:=0 to Length(NewRows) - 1 do…}
End; {If Sender is TStringGrid then…}
End;
procedure TGridFormattingProcs. NumerationOnNewCol (Sender: TObject;
NewCols: array of Integer);
{Процедура працює при виникненні події оновлення чи додавання нового
стовпця у GrowingStringGrid.
Підтримує форматування рядка нумерації таблиці у такому вигляді:
1 2 3 4 5… n}
Var CurNum: Integer; CurGrid:TStringGrid;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnNewCol<>Nil then Self. OldOnNewCol (Sender, NewCols);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
For CurNum:=0 to Length(NewCols) - 1 do
Begin
{Заголовки лише для нефіксованих комірок:}
If NewCols[CurNum]>=(Self.CHeadColNum+1) then
CurGrid. Cells [NewCols[CurNum], 0]:=
IntToStr (NewCols[CurNum] - Self.CHeadColNum);
End;
End;
End;
Procedure TGridFormattingProcs. UpdateLTaskHeadRowToStrGrid (SGrid:TStringGrid);
{Процедура для підтримки масиву рядка-заголовка під час редагування
таблиці. Встановлює довжину масиву відповідно до ширини екранної таблиці
і координат вписування в неї таблиці задачі, заповнює нові комірки
значеннями за змовчуванням, а також змінює останню комірку перед новими.}
Var CurLTaskVarCount, OldCount, CurVarMark: Integer;
Begin
{Кількість стовпців для коефіцієнтів змінних у таблиці:}
CurLTaskVarCount:=SGrid. ColCount-Self.CHeadColNum-
bc_LTaskColsBeforeVars {-bc_LTaskColsAfterVars};
{Якщо таблиця має надто малу ширину, то нічого тут не робимо:}
If CurLTaskVarCount<0 then Exit;
{Масив видовжуємо до кількості стовпців у StringGrid, у яких
редагуємо коєфіцієнти при змінних:}
OldCount:=Length (Self. CurHeadRow);
If OldCount<>CurLTaskVarCount then
Begin
SetLength (Self. CurHeadRow, CurLTaskVarCount); {змінюємо довжину}
{Заповнюємо нові елементи масиву значеннями за змовчуванням:
вільні змінні:}
For CurVarMark:=OldCount to CurLTaskVarCount-2 do
Begin
Self. CurHeadRow[CurVarMark].ElmType:=bc_IndependentVar;
Self. CurHeadRow[CurVarMark].VarInitInRow:=True;
Self. CurHeadRow[CurVarMark].VarInitPos:=CurVarMark;
Self. CurHeadRow[CurVarMark].AsVarName:=sc_XVarName+IntToStr (CurVarMark+1);
End;
{Останній елемент є числом, а не змінною: це множник стовпця
вільних членів (правих частин):}
If CurLTaskVarCount>0 then
Begin
Self. CurHeadRow [CurLTaskVarCount-1].ElmType:=bc_Number;
Self. CurHeadRow [CurLTaskVarCount-1].AsNumber:=1;
{Колишній останній елемент тепер буде змінною:}
If (OldCount>0) and (OldCount<CurLTaskVarCount) then
Begin
Self. CurHeadRow [OldCount-1].ElmType:=bc_IndependentVar;
Self. CurHeadRow [OldCount-1].AsVarName:=sc_XVarName+IntToStr(OldCount)
End;
End;
End;
End;
Procedure TGridFormattingProcs. UpdateLTaskHeadColToStrGrid (SGrid:TStringGrid;
NewRows: array of Integer);
{Процедура для підтримки масиву стовпця-заголовка під час редагування
таблиці. Встановлює довжину масиву відповідно до висоти екранної таблиці
і координат вписування в неї таблиці задачі, заповнює нові комірки
значеннями за змовчуванням.
Вхідні дані:
SGrid - екранна таблиця, під яку треба настроїти масив;
NewRows - масив номерів рядків таблиці, що були додані чи змінені
(що зазнали змін з часу останнього виклику цієї процедури під час
редагування).}
Var CurHeight, OldHeight, CurRow: Integer;
Procedure FillWithDefVal (SElmNum: Integer);
Begin
Self. CurHeadCol[SElmNum].ElmType:=bc_FuncVal;
Self. CurHeadCol[SElmNum].VarInitInRow:=False;
Self. CurHeadCol[SElmNum].VarInitPos:=SElmNum;
Self. CurHeadCol[SElmNum].AsVarName:=sc_YFuncName+
IntToStr (SElmNum+1);
End;
Begin {Висота таблиці за поточною висотою екранної таблиці:}
CurHeight:=SGrid. RowCount-Self.CHeadRowNum-bc_LTaskRowsBeforeVars;
OldHeight:=Length (Self. CurHeadCol); {попередня висота таблиці}
If (OldHeight<>CurHeight) and (CurHeight>=0) then
Begin
{Змінюємо довжину масиву стовпця-заголовка:}
SetLength (Self. CurHeadCol, CurHeight);
For CurRow:=OldHeight to CurHeight-1 do
FillWithDefVal(CurRow); {заповнюємо нові комірки за змовчуванням}
End;
End;
procedure TGridFormattingProcs. EdLineTaskOnDrawCell (Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
{Процедура виконується при малюванні кожної комірки StringGrid.
Зафарбовує в інший колір фону комірок:
- перший стовпець комірок (стовпець-заголовок таблиці задачі лінійного
програмування). Комірки цього стовпця зафарбовуються відповідно до типів
елементів у масиві стовпця-заголовка (якщо цей масив створений для цих
комірок, інакше - за змовчуванням: кольором назв функцій умов-нерівностей,
і найнижчу комірку - кольором для назви функції мети);
- останній стовпець (стовпець значень правих сторін рівнянь або
нерівностей та комірка значення цільової функції);
- найнижчий рядок (рядок коефіцієнтів цільової функції);
- відмічає кольором комірки-заголовки стовпців коефіцієнтів змінних
за відмітками про залежність змінних (рядок-заголовок таблиці задачі ЛП).}
Var CurGrid:TStringGrid; SafeBrushColor:TColor;
CurVarColState:THeadLineElmType; CurColor:TColor;
ArrRowNum: Integer;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnDrawCell<>Nil then Self. OldOnDrawCell (Sender, ACol, ARow, Rect,
State);
ArrRowNum:=ARow - (Self.CHeadRowNum+bc_LTaskRowsBeforeVars);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
SafeBrushColor:=CurGrid. Canvas. Brush. Color;
CurColor:=bc_NotColored;
{Комірки останнього стовпця є стовпцем правих сторін рівнянь.
Фарбуємо їх у блакитний колір (окрім комірок заголовків):}
If Not (gdFixed in State) then {якщо комірка не у заголовках StringGrid}
Begin
If ACol>=(CurGrid. ColCount-bc_LTaskColsAfterVars) then {останні стовпці:}
Begin
{Якщо це комірка значення цільової функції - для неї свій колір:}
Case Self. CurHeadCol[ArrRowNum].ElmType of
bc_DestFuncToMax: CurColor:=lwc_DestFuncValColor;
bc_DestFuncToMin: CurColor:=lwc_DestFuncValColor;
Else CurColor:=lwc_RightSideColColor;
End;
End
Else if ACol<(Self.CHeadColNum+bc_LTaskColsBeforeVars) then
Begin {Якщо перші стовпці (стовпець-заголовок):}
{Якщо для цієї комірки задано елемент у масиві стовпця-заголовка,
то фарбуємо її залежно від типу цього елемента:}
If Length (Self. CurHeadCol)>
(ARow - (Self.CHeadRowNum + bc_LTaskRowsBeforeVars)) then
Begin {Тип елемента у комірці:}
CurVarColState:=Self. CurHeadCol [ARow - (Self.CHeadRowNum+
bc_LTaskRowsBeforeVars)].ElmType;
CurColor:=GetColorByElmType(CurVarColState); {колір за типом}
End
Else {Якщо масив стовпця-заголовка не визначено для комірки -
фарбуємо за змовчуванням - як назву функції умови-нерівності:}
CurColor:=lwc_HeadColColor;
End {Якщо рядок коефіцієнтів при змінних цільової функції:}
Else if (Self. CurHeadCol[ArrRowNum].ElmType=bc_DestFuncToMax) or
(Self. CurHeadCol[ArrRowNum].ElmType=bc_DestFuncToMin) then
Begin
{Якщо рядок функції виділений, то виділяємо кольором:}
If InSolving and (Self. CurGridSolveRow=ARow) then
CurColor:=lwc_SolveRowColor
Else CurColor:=lwc_FuncRowColor; {інакше - колір рядка функції мети}
End {Якщо це розв'язувальна комірка, чи рядок або стовпець з такою
коміркою, і треба відображати хід вирішування задачі:}
Else if InSolving then
Begin
If Self. CurGridSolveCol=ACol then {якщо це розв'язувальний стовпець:}
Begin
If Self. CurGridSolveRow=ARow then {якщо це розв'язувальна комірка:}
CurColor:=lwc_SolveCellColor
Else CurColor:=lwc_SolveColColor;
End {Якщо це розв'язувальний рядок (але не розв'язувальна комірка):}
Else if Self. CurGridSolveRow=ARow then CurColor:=lwc_SolveRowColor;
End;
End;
{Зафарбовуємо комірки-заголовки стовпців коефіцієнтів при змінних
відповідно до масиву поміток про залежність:}
If (ARow=Self.CHeadRowNum) and
(Not (ACol<(Self.CHeadColNum+bc_LTaskColsBeforeVars))) then
Begin
CurVarColState:=Self. CurHeadRow [ACol - Self.CHeadColNum-
bc_LTaskColsBeforeVars].ElmType;
CurColor:=GetColorByElmType(CurVarColState)
End;
If CurColor<>bc_NotColored then {якщо комірку треба пофарбувати:}
Begin {Малюємо текст на фоні з кольором CurColor:}
CurGrid. Canvas. Brush. Color:=CurColor;
CurGrid. Canvas. TextRect (Rect, Rect. Left, Rect. Top,
CurGrid. Cells [ACol, ARow]);
End;
CurGrid. Canvas. Brush. Color:=SafeBrushColor;
End;
End;
procedure TGridFormattingProcs. EdLineTaskOnDblClick (Sender: TObject);
{Процедура реагує на подвійне натискання лівою кнопкою миші на
комірки рядка-заголовка таблиці (другий рядок StringGrid).
Редагує масив позначок про обрані стовпці (SipmlexVarsDependencyRec)
залежних змінних. Залежні змінні - це змінні, для яких є умова
невід'ємності. Тобто вони не повинні бути менше нуля.}
Var CurGrid:TStringGrid; CurCol, CurRow: Integer;
MouseCoordsInGrid:TPoint;
Begin
If Sender=Nil then Exit;
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnDblClick<>Nil then Self. OldOnDblClick(Sender);
If Sender is TStringGrid then
Begin
CurGrid:=TStringGrid(Sender);
{Пробуємо узнати, на яку комірку двічі натиснула миша:}
MouseCoordsInGrid:=CurGrid. ScreenToClient (Mouse. CursorPos);
CurCol:=-1; CurRow:=-1;
CurGrid. MouseToCell (MouseCoordsInGrid.X, MouseCoordsInGrid.Y, CurCol, CurRow);
{Якщо натиснуто на комірку-заголовок стовпця коефіцієнтів при змінній, то:}
If ((CurCol>=(Self.CHeadColNum+bc_LTaskColsBeforeVars)) and
(CurCol<(CurGrid. ColCount-bc_LTaskColsAfterVars))) and
(CurRow=Self.CHeadRowNum) then
Begin
{Змінюємо ознаку залежності відповідної змінної:}
If CurHeadRow [CurCol - Self.CHeadColNum-
bc_LTaskColsBeforeVars].ElmType=bc_IndependentVar then
CurHeadRow [CurCol - Self.CHeadColNum-
bc_LTaskColsBeforeVars].ElmType:=bc_DependentVar
Else
CurHeadRow [CurCol - Self.CHeadColNum-
bc_LTaskColsBeforeVars].ElmType:=bc_IndependentVar;
{Задаємо перемалювання комірок, щоб відобразилася зміна позначки
для змінної:}
CurGrid. Invalidate;
End;
End;
End;
Procedure TGridFormattingProcs. InitGridPopupMenu (SGrid:TStringGrid);
{Процедура перевіряє наявність об'єкта TPopupMenu. Якщо його немає
(SGrid. PopupMenu=Nil), то створює новий.
Видаляє усі пунтки (елементи, теми) з меню.}
Begin
If SGrid. PopupMenu=Nil then
Begin
SGrid. PopupMenu:=TPopupMenu. Create(Application);
End;
SGrid. PopupMenu. AutoPopup:=False;
SGrid. PopupMenu. Items. Clear;
End;
Procedure TGridFormattingProcs. ProcOnCellTypeSelInMenu (Sender: TObject);
{Обробник вибору пункту в меню типів для комірки
рядка - чи стовпця-заголовка.}
Const sc_CurProcName='ProcOnCellTypeSelInMenu';
Procedure ReportUnsupportedCell;
Begin
{Відображає координати комірки з повідомленням про те, що вона
не підтримується:}
If Self. CurOutConsole<>Nil then
Begin
Self. CurOutConsole. Lines. Add (sc_CurProcName + sc_NoCellOrNotSupported+
' ['+IntToStr (Self. CurGridSolveCol)+';'+IntToStr (Self. CurGridSolveRow)+
']… ');
End;
End;
Var CurMenuItem:TMenuItem; TypeForCell:THeadLineElmType;
Begin
If (Sender=Nil) or (Not (Sender is TMenuItem)) then
Begin
If Self. MemoForOutput<>Nil then
Self. MemoForOutput. Lines. Add (sc_CurProcName + sc_CantDetMenuItem);
Exit;
End;
{Читаємо тип, що обраний для комірки:}
CurMenuItem:=TMenuItem(Sender);
TypeForCell:=THeadLineElmType (CurMenuItem. Tag);
If (Self. CurGridSolveCol<0) and (Self. CurGridSolveRow<0) then
Begin {якщо комірка вище чи лівіше заголовків таблиці:}
ReportUnsupportedCell; Exit;
End;
{Перевіряємо координати комірки і змінюємо її тип:}
{координати комірки мають бути записані у CurGridSolveRow і CurGridSolveCol:}
If Self. CurGridSolveRow=-bc_LTaskRowsBeforeVars then
Begin {якщо це комірка рядка-заголовка:}
If Length (Self. CurHeadRow)>Self. CurGridSolveCol then {якщо комірка існує:}
Begin {задаємо тип комірки:}
Self. CurHeadRow [Self. CurGridSolveCol].ElmType:=TypeForCell;
End
Else {якщо в рядку-заголовку немає такої комірки:}
Begin
ReportUnsupportedCell; Exit;
End;
End
Else if Self. CurGridSolveCol=-bc_LTaskColsBeforeVars then
Begin {якщо це комірка стовпця-заголовка:}
If Length (Self. CurHeadCol)>Self. CurGridSolveRow then {якщо комірка існує:}
Begin {задаємо тип комірки:}
Self. CurHeadCol [Self. CurGridSolveRow].ElmType:=TypeForCell;
End
Else {якщо в стовпці-заголовку немає такої комірки:}
Begin
ReportUnsupportedCell; Exit;
End;
End
Else {якщо комірка у таблиці коефіцієнтів або правіше чи нижче неї:}
Begin
ReportUnsupportedCell; Exit;
End;
{Якщо тип комірки змінено, то перемальовуємо екранну таблицю для
відображення нового типу комірки:}
If Self. CurGrid<>Nil then Self. CurGrid. Invalidate;
End;
Procedure TGridFormattingProcs. AddCellTypeItemToMenu (SMenu:TPopupMenu;
SCaption: String; IsCurrentItem: Boolean; SAssocType:THeadLineElmType;
ToSetReactOnClick: Boolean=True);
{Додає пункт меню для вибору типу комірки в таблиці з заданим
написом SCaption і кругом того кольору, що асоційований з даним
типом SAssocType. Для нового пункту меню настроює виклик процедури обробки
комірки для задавання їй обраного типу SAssocType. Значення SAssocType
записує у поле Tag об'єкта пункту меню.
Вхідні дані:
SMenu - контекстне меню для комірки, що формується;
SCaption - підпис для пункту меню (назва типу комірки);
IsCurrentItem - ознака того, що даний пункт меню має бути поточним
(ввімкненим, відміченим) - що це поточний тип комірки;
SAssocType - тип комірки, що прив'язаний до цього пункта меню, і буде
присвоєний комірці при виборі цього пункту;
ToSetReactOnClick - вмикач настройки виклику процедури задавання нового
типу комірки (при виборі елемента меню). При ToSetReactOnClick=False
це не виконується, і натискання елемента меню не викликає ніяких дій.}
Var CurMenuItem:TMenuItem;
SAssocColor:TColor;
Begin
If SMenu=Nil then Exit; {якщо меню не задано - елемент не додаємо в нього}
{Створюємо новий тункт меню:}
CurMenuItem:=TMenuItem. Create(Application);
{Отримуємо колір для даного типу комірки:}
SAssocColor:=Self. GetColorByElmType(SAssocType);
{Біля тексту малюємо круг такого кольору, який асоційований
з типом комірки, і буде присвоєний їй у разі вибору цього пунтку
меню:}
CurMenuItem. Bitmap. Height:=bc_MenuItemColorCircleDiameter;
CurMenuItem. Bitmap. Width:=bc_MenuItemColorCircleDiameter;
CurMenuItem. Bitmap. Canvas. Pen. Color:=SAssocColor;
CurMenuItem. Bitmap. Canvas. Brush. Color:=SAssocColor;
CurMenuItem. Bitmap. Canvas. Ellipse (CurMenuItem. Bitmap. Canvas. ClipRect);
{0 - картинка задана у самому об'єкті, а не в SMenu. Images:}
CurMenuItem. ImageIndex:=0;
CurMenuItem. RadioItem:=True; {промальовувати перемикач, якщо не буде картинки}
{Текст пункту меню:}
CurMenuItem. Caption:=SCaption;
CurMenuItem. Checked:=IsCurrentItem;
If ToSetReactOnClick then {якщо обробка вибору елемента меню ввімкнена}
Begin
{Тип для комірки у випадку вибору цього пунтку меню:}
CurMenuItem. Tag:=Integer(SAssocType);
{Процедура-обробник вибору пункта меню:}
CurMenuItem. OnClick:=Self. ProcOnCellTypeSelInMenu;
CurMenuItem. AutoCheck:=True;
End;
SMenu. Items. Add(CurMenuItem);
End;
(* {Ідентифікатор для типу елемента масиву чисел та імен змінних.
Типи змінних: залежні, незалежні, функції (умови-нерівності).
Залежні змінні - це змінні, для яких діє умова невід'ємності:}
THeadLineElmType=(bc_IndependentVar, bc_DependentVar, bc_FuncVal, bc_Number,
bc_DestFuncToMax);} *)
procedure TGridFormattingProcs. EdLineTaskOnMouseUp (Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
{Процедура реагує на відпускання правої кнопки миші на
комірках рядка-заголовка та стовпця-заголовка таблиці.
Формує та відкриває контекстне меню для вибору типу комірки із можливих
типів для цієї комірки.}
Const sc_CurProcName='EdLineTaskOnMouseUp';
Var CurCol, CurRow, ArrayRow, ArrayCol: Integer; CurElmType:THeadLineElmType;
MouseScrCoords:TPoint;
Begin
{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}
If @Self. OldOnMouseUp<>Nil then Self. OldOnMouseUp (Sender, Button, Shift, X, Y);
If Sender=Nil then Exit;
{Якщо задано екранну таблицю даного об'єкта TGridFormattingProcs:}
If Sender = Self. CurGrid then
Begin
If Button=mbRight then {якщо була відпущена права кнопка миші}
Begin
{Пробуємо узнати, на яку комірку натиснула миша:}
CurCol:=-1; CurRow:=-1;
Self. CurGrid. MouseToCell (X, Y, CurCol, CurRow);
MouseScrCoords:=Self. CurGrid. ClientToScreen (Point(X, Y));
{Координати комірки у масивах таблиці і її заголовків:}
ArrayRow:=CurRow-Self.CHeadRowNum-bc_LTaskRowsBeforeVars;
ArrayCol:=CurCol-Self.CHeadColNum-bc_LTaskColsBeforeVars;
{Якщо натиснуто на комірку рядка-заголовка:}
If (CurRow=Self.CHeadRowNum) and (ArrayCol>=0) and
(ArrayCol<Length (Self. CurHeadRow)) then
Begin {очищаємо меню перед заповненням:}
Self. InitGridPopupMenu (Self. CurGrid);
{Якщо в екранній таблиці були зміни з часу останнього її читання,
то читаємо комірку, для якої треба сформувати меню:}
If Self. CurGridModified then Self. ReadHeadRowCell(ArrayCol);
{Читаємо поточний тип комірки:}
CurElmType:=Self. CurHeadRow[ArrayCol].ElmType;
{Додаємо пункти меню:}
{Якщо в комірці число-то тип комірки може бути тільки числовий:}
If CurElmType=bc_Number then
Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,
sc_ValInHeadColOrRow, True, CurElmType)
Else {якщо в комірці не число:}
Begin
{незалежна змінна:}
Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,
sc_IndependentVar,
CurElmType = bc_IndependentVar, bc_IndependentVar);
{залежна змінна:}
Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,
sc_DependentVar,
CurElmType = bc_DependentVar, bc_DependentVar);
End;
End
Else If (CurCol=Self.CHeadColNum) and (ArrayRow>=0) and
(ArrayRow<Length (Self. CurHeadCol)) then
Begin {якщо натиснуто на комірку стовпця-заголовка:}
Self. InitGridPopupMenu (Self. CurGrid);
{Якщо в екранній таблиці були зміни з часу останнього її читання,
то читаємо комірку, для якої треба сформувати меню:}
If Self. CurGridModified then Self. ReadHeadColCell(ArrayRow);
{Читаємо поточний тип комірки:}
CurElmType:=Self. CurHeadCol[ArrayRow].ElmType;
{Додаємо пункти меню:}
{Якщо в комірці число-то тип комірки може бути тільки числовий:}
If CurElmType=bc_Number then
Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,
sc_ValInHeadColOrRow, True, CurElmType)
Else {якщо в комірці не число:}
Begin
{назва фінкції - рядка нерівності:}
Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,
sc_InequalFuncName, CurElmType = bc_FuncVal, bc_FuncVal);
{назва функції мети, що максимізується:}
Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,
sc_DestFuncToMaxName, CurElmType = bc_DestFuncToMax,
bc_DestFuncToMax);
{назва функції мети, що мінімізується:}
Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,
sc_DestFuncToMinName, CurElmType = bc_DestFuncToMin,
bc_DestFuncToMin);
End;
End
Else {якщо для даної комірки вибір типу не передбачено}
Begin {ставимо в меню координати комірки
(щоб користувач взагалі помітив, що меню є…)}
Self. InitGridPopupMenu (Self. CurGrid);
Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,
sc_Row+sc_DoubleSpot+sc_Space+IntToStr (ArrayRow+1)+sc_KrKm+
sc_Space+sc_Col+sc_DoubleSpot+sc_Space+IntToStr (ArrayCol+1),
True, bc_OtherType);
End;
{Записуємо координати комірки для обробника вибору типу з меню:}
Self. CurGridSolveCol:=ArrayCol;
Self. CurGridSolveRow:=ArrayRow;
{Відображаємо меню:}
Self. CurGrid. PopupMenu. Popup (MouseScrCoords.X, MouseScrCoords.Y);
End; {If Button=mbRight then…}
End {If Sender = Self. CurGrid then…}
Else {якщо обробник викликала «чужа» таблиця або невідомий об'єкт:}
Begin
If Self. CurOutConsole<>Nil then
Self. CurOutConsole. Lines. Add (sc_CurProcName+sc_UnknownObjectCall+
sc_DoubleQuot+Sender. ClassName+sc_DoubleQuot);
End;
End;
procedure TGridFormattingProcs. ReactOnSetEditText (Sender: TObject; ACol,
ARow: Longint; const Value: string);
{Процедура для реагування на редагування вмісту комірок
під час редагування вхідних даних. Встановлює прапорець
CurGridModified:=True про те, що екранна таблиця має зміни.}
Begin
{Старий обробник теж викликаємо, якщо він є:}
If @Self. OldOnSetEditText<>Nil then
Self. OldOnSetEditText (Sender, ACol, ARow, Value);
Self. CurGridModified:=True;
End;
Procedure TGridFormattingProcs. SetNewState (Value:TTableFormatState);
Const sc_CurProcName='SetNewState';
Var StateSafe:TTableFormatState;
OldHColPos, OldHRowPos: Integer;
{Процедура для зміни режиму форматування GrowingStringGrid}
Procedure GoSolveLTask;
Begin {Вирішування задачі ЛП симплекс-методом:}
CurGrid. ColCount:=bc_FixedCols+1;
CurGrid. RowCount:=bc_FixedRows+1;
CurGrid. FixedRows:=bc_FixedRows;
Подобные документы
Задача лінійного програмування. Розв’язання задачі геометричним методом. Приведення системи рівнянь до канонічного вигляду. Розв’язання симплекс-методом. Розв’язок двоїстої задачі. Задача цілочислового програмування і дробово-лінійного програм.
контрольная работа [385,2 K], добавлен 04.06.2009Лінійне програмування як один з найбільш популярних апаратів математичної теорії оптимального управління рішень. Опис існуючих методів розв’язку задач лінійного програмування. Завдання, основні принципи, алгоритми і головна мета лінійного програмування.
курсовая работа [363,8 K], добавлен 03.12.2009Теоретичні основи та приклади економічних задач лінійного програмування. Розробка математичної моделі задачі (запис цільової функції і системи обмежень) і програмного забезпечення її вирішення за допомогою "Пошуку рішень" в Excel симплекс-методом.
курсовая работа [993,9 K], добавлен 10.12.2010Використання мови програмуванння Java при виконанні "задачі лінійного програмування": її лексична структура і типи даних. Методи розв’язання задачі. Особливості логічної структури програми, побудова її зручного інтерфейсу за допомогою симплекс методу.
курсовая работа [437,9 K], добавлен 24.01.2011Загальний вид двовимірного завдання лінійного програмування. Алгоритм рішення задач графічним методом. Максимізація (мінімізація) цільової функції. Послідовність рішення завдань лінійного програмування симплексом-методом. Принцип перетворення Гауса.
контрольная работа [149,8 K], добавлен 24.11.2010Початковий опорний план, перехід від одного до іншого. Оптимальний розв’язок, його головні критерії. Знаходження опорного плану задачі, складання симплексної таблиці. Приклад оформлення першої та другої таблиці для розв’язку задач лінійного програмування.
лекция [479,7 K], добавлен 10.10.2013Застосування симплекс-методу для розв’язання оптимізаційних задач лінійного програмування, що містять три змінні. Функції ітераційної обчислювальної процедури, що виконують приведення до зручного для розв’язання оптимального вигляду ЗЛП за кілька кроків.
курсовая работа [359,5 K], добавлен 18.09.2013Основні визначення дослідження операцій. Модель "затрати-випуск" В.В. Леонтьєва. Загальний вигляд задачі лінійного програмування. Розв'язання за допомогою симплекс-методу. Економічна інтерпретація основної та спряженої задач. Поліпшення плану перевезень.
учебное пособие [1,1 M], добавлен 27.12.2010Метод Якобі є узагальненням симплекса-методу лінійного програмування. Він використовується для дослідження чутливості оптимального значення функції до змін у правих частинах обмежень. Умови існування екстремумів функцій при відсутності обмежень.
курсовая работа [326,6 K], добавлен 09.01.2009Постановка задачі багатокритеріальної оптимізації та її та математична модель. Проблеми і класифікація методів вирішення таких задач, способи їх зведення до однокритеріальних. Метод послідовних поступок. Приклад розв'язування багатокритеріальної задачі.
курсовая работа [207,3 K], добавлен 22.12.2013