Смекни!
smekni.com

Багатокритеріальна задача лінійного програмування (стр. 15 из 17)

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… nn+1

yx1 x2 x3 x4… xn1

}

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;

{Останній елемент є числом, а не змінною: це множник стовпця

вільних членів (правих частин):}

IfCurLTaskVarCount>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{Якщо це розв'язувальна комірка, чи рядок або стовпець з такою

коміркою, і треба відображати хід вирішування задачі:}