Багатокритеріальна задача лінійного програмування

Розв’язок багатокритеріальної задачі лінійного програмування з отриманням компромісного рішення (для задач з кількома функціями мети) за допомогою теоретико-ігрового підходу. Матриця мір неоптимальності та рядок функції мети. Модуль опису класу.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 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 5n n+1

x1 x2 x3 x4 x5xn 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

{в усіх інших - коефіцієнти при змінних X1Xn:}

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 5n n+1

y x1 x2 x3 x4xn 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 5n}

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

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.