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… nn+1
x1 x2 x3 x4 x5… xn1
}
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
у режимі набору вхідних даних системи лінійних рівнянь.
Зафарбовує в інший колір останній стовпець – стовпець
правих частин рівнянь.}
VarCurGrid: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
…
mym
Стовпець-заголовок (нові комірки стовпця-заголовка за змовчуванням
заповнюються значеннями типу «функції-нерівності»).}