CalcWithNonLinConstraints: Boolean;
CalcWithNonLinConstraints: boolean;
Свойство CalcWithNonLinConstraints определяет, использовать ли в расчете нелинейные ограничения.
Возможные значения:
True. Значение по умолчанию. В расчете используются нелинейные ограничения, заданные свойством ICpTargetAdjustment.Constraints;
False. В расчете не используются нелинейные ограничения.
Добавьте ссылку на системную сборку Cp.
Sub UserProc;
Var
TargetAdj: ICpTargetAdjustment;
T: Integer;
RetroX1, RetroX2, RetroU, RetroV: Array Of Double;
InitApproximation, ValuesI, ValuesJ: Array Of Double;
i, j: Integer;
VarsP: ITargetPhaseVariablesArray;
VrblP: ITargetPhaseVariable;
VarConstrs: IVarTargetConstraintsArray;
VarConstr: IVarTargetConstraint;
VarsC: ITargetControlVariablesArray;
VrblC: ITargetControlVariable;
Ser: Array[4] Of Double;
Res: ITargetResults;
Val: Double;
Begin
TargetAdj := New TargetAdjustment.Create;
// Задаем период
T := 6;
// Создаем переменные с ретроспективой
RetroX1 := New Double[T];
RetroX2 := New Double[T];
RetroU := New Double[T];
RetroV := New Double[T];
// Создаем массив начальных приближений
InitApproximation := New Double[T];
// Задаем начальные значения переменных
For i := 0 To T - 1 Do
RetroX1[i] := 0.8 + i / 5;
RetroX2[i] := 0.85 + i / 4;
RetroU[i] := 0.9 + i / 10;
RetroV[i] := 0.95 + i / 10;
End For;
// Получаем фазовые переменные
VarsP := TargetAdj.PhaseVariables;
// Добавляем фазовую переменную x1
VrblP := VarsP.Add("x1");
VrblP.Name := "x1";
// Задаем ретроспективные значения
VrblP.Retrospective := RetroX1;
// Задаем порядок переменных
VrblP.CoefficientsOrder := "x1[t];x1[t-1]";
// Получаем ограничения фазовой переменной
VarConstrs := VrblP.Constraints;
For i := 0 To T - 1 Do
// Создаём новое ограничение
VarConstr := VarConstrs.Add;
// Задаем границы
VarConstr.LowerBound := -10 - i / 100;
VarConstr.UpperBound := 10 + i / 100;
// Указываем текущий момент времени
VarConstr.TimeMoment := i;
End For;
// Задаем уравнение динамики
VrblP.FunctionExpression := "0.3 * x1[t-1] + 0.1 * x2[t-1] + u[t-1] * x1[t-1] *x2[t-1]";
// Добавляем фазовую переменную x2
VrblP := VarsP.Add("x2");
VrblP.Name := "x2";
VrblP.Retrospective := RetroX2;
VrblP.CoefficientsOrder := "x2[t];x2[t-1]";
VarConstrs := VrblP.Constraints;
For i := 0 To T - 1 Do
VarConstr := VarConstrs.Add;
VarConstr.LowerBound := -100-i;
VarConstr.UpperBound := 100+i;
VarConstr.TimeMoment := i;
End For;
VrblP.FunctionExpression := "(-0.2) * x1[t-1] + 0.4 *x2[t-1] + (x1[t-1] * x2[t-1])/(v[t]+1)";
// Получаем управляющие переменные
VarsC := TargetAdj.ControlVariables;
// Добавляем управляющую переменную u
VrblC := VarsC.Add("u");
VrblC.Name := "u";
// Задаем ретороспективные значения
VrblC.Retrospective := RetroU;
// Задаем порядок коэффициентов
VrblC.CoefficientsOrder := "u[t];u[t-1]";
// Задаем значения начальных приближений
For i := 0 To T - 1 Do
InitApproximation[i] := 1.2 + (i + 1) / 100;
End For;
VrblC.InitApproximation := InitApproximation;
// Получаем ограничения управляющей переменной
VarConstrs := VrblC.Constraints;
For i := 0 To T - 1 Do
// Добавляем ограничение
VarConstr := VarConstrs.Add;
// Задаем границы ограничения
VarConstr.LowerBound := 1;
VarConstr.UpperBound := 2;
// Задаем текущий момент времени
VarConstr.TimeMoment := i;
End For;
// Добавляем управляющую переменную v
VrblC := VarsC.Add("v");
VrblC.Name := "v";
VrblC.Retrospective := RetroV;
VrblC.CoefficientsOrder := "v[t];v[t-1]";
For i:=0 To T-1 Do
InitApproximation[i] := 1.5+ (i+1)/100;
End For;
VrblC.InitApproximation := InitApproximation;
VarConstrs := VrblC.Constraints;
For i := 0 To T - 1 Do
VarConstr := VarConstrs.Add;
VarConstr.LowerBound := 0.8;
VarConstr.UpperBound := 7;
VarConstr.TimeMoment := i;
End For;
// Задаем целевую траекторию
ser[0] := 1;
ser[1] := 2;
ser[2] := 3;
ser[3] := 4;
TargetAdj.TargetTrajectory := Ser;
// Задаем целевую функцию
TargetAdj.CriterionFunction := "x1[t] + x2[t-1] - u[t]";
// Задаем количество итераций
TargetAdj.MaxIterationsCount := 25000;
// Задаем точность решения
TargetAdj.Tolerance := 0.00001;
// Указываем, что в расчете не используем нелинейные ограничения
TargetAdj.CalcWithNonLinConstraints := False;
// Задаем тип задачи
TargetAdj.AutoSearchType := TargetAutoSearchType.MinError;
// Задаем количество циклов
TargetAdj.AutoAdjustMaxIter := 10;
// Задаем приемлемую точность
TargetAdj.AutoAdjustSatisfactoryTolerance := 1.01;
// Задаем число ограничений удалённых за одну итерацию
TargetAdj.AutoAdjustRemoveCount := 2;
// Выполняем расчет
Res := TargetAdj.Evaluate(T) As ITargetResults;
// Если расчет прошёл без ошибок, то выводим результаты в консоль
If res.Status = 0 Then
// Выводим оптимальное значение
Debug.WriteLine("Оптимальное значение:");
Debug.Indent;
Debug.WriteLine(res.OptimalValue);
Debug.Unindent;
// Выводим значения управляющих переменных
For j := 1 To VarsC.Count Do
VrblC := VarsC.Item(j - 1);
Debug.WriteLine("Значения управляющей переменной '" + VrblC.Id + "':");
Debug.Indent;
For i := 1 To T Do
Val := Res.VarValues(VrblC.Id)[i - 1];
Debug.WriteLine(i.ToString + ": " + Val.ToString);
End For;
Debug.Unindent;
End For;
// Выводим значения фазовых переменных
For j := 1 To VarsP.Count Do
VrblP := VarsP.Item(j - 1);
Debug.WriteLine("Значения фазовой переменной '" + VrblP.Id + "':");
Debug.Indent;
For i := 1 To T Do
Val := Res.VarValues(VrblP.Id)[i - 1];
Debug.WriteLine(i.ToString + ": " + Val.ToString);
End For;
Debug.Unindent;
End For;
// Выводим оптимальную траекторию целевой функции
Debug.WriteLine("Оптимальная траектория целевой функции:");
Debug.Indent;
For i := 0 To Res.CriterionFunctionTrajectory.Length - 1 Do
Debug.WriteLine(Res.CriterionFunctionTrajectory[i]);
End For;
Debug.Unindent;
// Если расчёт завершился с ошибкой, то выводим её текст
Else
Debug.WriteLine(res.ErrorMsg);
End If;
End Sub UserProc;
В результате выполнения примера будут заданы параметры расчета задачи оптимизации, задача будет рассчитана, результаты выведены в окно консоли.
Необходимые требования и результат выполнения примера Fore.NET совпадают с примером Fore.
Imports Prognoz.Platform.Interop.Cp;
…
Public Shared Sub Main(Params: StartParams);
Var
TargetAdj: ICpTargetAdjustment;
T: Integer;
RetroX1, RetroX2, RetroU, RetroV: Array Of Double;
InitApproximation, ValuesI, ValuesJ: Array Of Double;
i, j: Integer;
VarsP: ITargetPhaseVariablesArray;
VrblP: ITargetPhaseVariable;
VarConstrs: IVarTargetConstraintsArray;
VarConstr: IVarTargetConstraint;
VarsC: ITargetControlVariablesArray;
VrblC: ITargetControlVariable;
Ser: Array[4] Of Double;
Res: ITargetResults;
Val: Double;
Begin
TargetAdj := New TargetAdjustment.Create();
// Задаем период
T := 6;
// Создаем переменные с ретроспективой
RetroX1 := New Double[T];
RetroX2 := New Double[T];
RetroU := New Double[T];
RetroV := New Double[T];
// Создаем массив начальных приближений
InitApproximation := New Double[T];
// Задаем начальные значения переменных
For i := 0 To T - 1 Do
RetroX1[i] := 0.8 + i / 5;
RetroX2[i] := 0.85 + i / 4;
RetroU[i] := 0.9 + i / 10;
RetroV[i] := 0.95 + i / 10;
End For;
// Получаем фазовые переменные
VarsP := TargetAdj.PhaseVariables;
// Добавляем фазовую переменную x1
VrblP := VarsP.Add("x1");
VrblP.Name := "x1";
// Задаем ретроспективные значения
VrblP.Retrospective := RetroX1;
// Задаем порядок переменных
VrblP.CoefficientsOrder := "x1[t];x1[t-1]";
// Получаем ограничения фазовой переменной
VarConstrs := VrblP.Constraints;
For i := 0 To T - 1 Do
// Создаём новое ограничение
VarConstr := VarConstrs.Add();
// Задаем границы
VarConstr.LowerBound := -10 - i / 100;
VarConstr.UpperBound := 10 + i / 100;
// Указываем текущий момент времени
VarConstr.TimeMoment := i;
End For;
// Задаем уравнение динамики
VrblP.FunctionExpression := "0.3 * x1[t-1] + 0.1 * x2[t-1] + u[t-1] * x1[t-1] *x2[t-1]";
// Добавляем фазовую переменную x2
VrblP := VarsP.Add("x2");
VrblP.Name := "x2";
VrblP.Retrospective := RetroX2;
VrblP.CoefficientsOrder := "x2[t];x2[t-1]";
VarConstrs := VrblP.Constraints;
For i := 0 To T - 1 Do
VarConstr := VarConstrs.Add();
VarConstr.LowerBound := -100-i;
VarConstr.UpperBound := 100 + i;
VarConstr.TimeMoment := i;
End For;
VrblP.FunctionExpression := "(-0.2) * x1[t-1] + 0.4 *x2[t-1] + (x1[t-1] * x2[t-1])/(v[t]+1)";
// Получаем управляющие переменные
VarsC := TargetAdj.ControlVariables;
// Добавляем управляющую переменную u
VrblC := VarsC.Add("u");
VrblC.Name := "u";
// Задаем ретороспективные значения
VrblC.Retrospective := RetroU;
// Задаем порядок коэффициентов
VrblC.CoefficientsOrder := "u[t];u[t-1]";
// Задаем значения начальных приближений
For i := 0 To T - 1 Do
InitApproximation[i] := 1.2 + (i + 1) / 100;
End For;
VrblC.InitApproximation := InitApproximation;
// Получаем ограничения управляющей переменной
VarConstrs := VrblC.Constraints;
For i := 0 To T - 1 Do
// Добавляем ограничение
VarConstr := VarConstrs.Add();
// Задаем границы ограничения
VarConstr.LowerBound := 1;
VarConstr.UpperBound := 2;
If (0 = i) Then
VarConstr.UpperBoundFixed := True;
End If;
// Задаем текущий момент времени
VarConstr.TimeMoment := i;
End For;
// Добавляем управляющую переменную v
VrblC := VarsC.Add("v");
VrblC.Name := "v";
VrblC.Retrospective := RetroV;
VrblC.CoefficientsOrder := "v[t];v[t-1]";
For i:=0 To T-1 Do
InitApproximation[i] := 1.5+ (i+1)/100;
End For;
VrblC.InitApproximation := InitApproximation;
VarConstrs := VrblC.Constraints;
For i := 0 To T - 1 Do
VarConstr := VarConstrs.Add();
VarConstr.LowerBound := 0.8;
If (0 = i) Then
VarConstr.LowerBoundFixed := True;
End If;
VarConstr.UpperBound := 7;
VarConstr.TimeMoment := i;
End For;
// Задаем целевую траекторию
ser[0] := 1;
ser[1] := 2;
ser[2] := 3;
ser[3] := 4;
TargetAdj.TargetTrajectory := Ser;
// Задаем целевую функцию
TargetAdj.CriterionFunction := "x1[t] + x2[t-1] - u[t]";
// Задаем количество итераций
TargetAdj.MaxIterationsCount := 25000;
// Задаем точность решения
TargetAdj.Tolerance := 0.00001;
// Указываем, что в расчете не используем нелинейные ограничения
TargetAdj.CalcWithNonLinConstraints := False;
// Задаем тип задачи
TargetAdj.AutoSearchType := TargetAutoSearchType.tastMinError;
// Задаем количество циклов
TargetAdj.AutoAdjustMaxIter := 10;
// Задаем приемлемую точность
TargetAdj.AutoAdjustSatisfactoryTolerance := 1.01;
// Задаем число ограничений удалённых за одну итерацию
TargetAdj.AutoAdjustRemoveCount := 2;
// Выполняем расчет
Res := TargetAdj.Evaluate(T) As ITargetResults;
// Если расчет прошёл без ошибок, то выводим результаты в консоль
If res.Status = 0 Then
// Выводим оптимальное значение
System.Diagnostics.Debug.WriteLine("Оптимальное значение:");
System.Diagnostics.Debug.Indent();
System.Diagnostics.Debug.WriteLine(res.OptimalValue);
System.Diagnostics.Debug.Unindent();
// Выводим значения управляющих переменных
For j := 1 To VarsC.Count Do
VrblC := VarsC.Item[j - 1];
System.Diagnostics.Debug.WriteLine("Значения управляющей переменной '" + VrblC.Id + "':");
System.Diagnostics.Debug.Indent();
For i := 1 To T Do
Val := Res.VarValues[VrblC.Id].GetValue(i - 1) As double;
System.Diagnostics.Debug.WriteLine(i.ToString() + ": " + Val.ToString());
End For;
System.Diagnostics.Debug.Unindent();
End For;
// Выводим значения фазовых переменных
For j := 1 To VarsP.Count Do
VrblP := VarsP.Item[j - 1];
System.Diagnostics.Debug.WriteLine("Значения фазовой переменной '" + VrblP.Id + "':");
System.Diagnostics.Debug.Indent();
For i := 1 To T Do
Val := Res.VarValues[VrblP.Id].GetValue(i - 1) As double;
System.Diagnostics.Debug.WriteLine(i.ToString() + ": " + Val.ToString());
End For;
System.Diagnostics.Debug.Unindent();
End For;
// Выводим оптимальную траекторию целевой функции
System.Diagnostics.Debug.WriteLine("Оптимальная траектория целевой функции:");
System.Diagnostics.Debug.Indent();
For i := 0 To Res.CriterionFunctionTrajectory.Length - 1 Do
System.Diagnostics.Debug.WriteLine(Res.CriterionFunctionTrajectory.GetValue(i));
End For;
System.Diagnostics.Debug.Unindent();
// Если расчёт завершился с ошибкой, то выводим её текст
Else
System.Diagnostics.Debug.WriteLine(res.ErrorMsg);
End If;
End Sub;
См. также: