Retrospective: Array;
The Retrospective property determines variable values before optimization start.
To determine a variable value, use the INonLinearExplanatory.Series property.
To execute the example, add a link to the Cp system assembly.
Sub UserProc;
Var
Optima: NonLinearOptimization;
Vars: INonLoVariables;
Vrbl: INonLoVariable;
VarConstr: IVarConstraint;
VarConstrs: IVarConstraints;
Expl: INonLinearExplanatory;
Res: INonLoResults;
Constr : INonLoConstraint;
RetroA, RetroX, RetroZ: Array[1] Of Double;
explar: Array[4] Of Double;
Funstions: Array[2] Of String;
TimeInterval, i, j: Integer;
Val: Double;
s: String;
Trajectory: Array Of Double;
Begin
Optima := New NonLinearOptimization.Create;
RetroA[0] := 2000;
RetroX[0] := 0;
RetroZ[0] := 0;
// Variables and constraints
Vars := Optima.Variables;
Vars.Clear;
Vrbl := Vars.Add("A");
Vrbl.Retrospective := RetroA;
Vrbl.CoefficientsOrder := "a[t];a[t-1];a[t-2];a[t-3]";
Vrbl := Vars.Add("Z");
Vrbl.Retrospective := RetroZ;
Vrbl.CoefficientsOrder := "z[t];z[t-1];z[t-2];z[t-3]";
VarConstrs := Vrbl.Constraints;
// Controlling variable
Vrbl := Vars.Add("X");
Vrbl.Retrospective := RetroX;
Vrbl.ControlVariable := True;
Vrbl.CoefficientsOrder := "x[t];x[t-1];x[t-2];x[t-3]";
VarConstrs := Vrbl.Constraints;
// Constraint for variable
TimeInterval := 4;
For i:=0 To TimeInterval-1 Do
VarConstr := VarConstrs.Add;
VarConstr.LowerBound := 0;
VarConstr.UpperBound := 1000;
VarConstr.Lag := i;
End For;
// Explanatory variable
Optima.Explanatories.Clear;
Expl := Optima.Explanatories.Add;
Expl.VariableName := "scen";
Expl.Series := explar;
Expl.CoefficientsOrder := "scen[t];scen[t-1]";
For i:=0 To explar.Length-1 Do
explar[i]:=0;
End For;
Expl.Retrospective := explar;
// Non-linear optimization equation
Funstions := New string[2];
Funstions[0] := "0.5 * a[t-1]-0.4*x[t-1]+scen[t-1]";
Funstions[1] := "z[t-1]+2*a[t]+x[t]";
Optima.Equations := Funstions;
// Non-linear optimization constraints
Optima.Constraints.Clear;
Constr:=Optima.Constraints.Add;
Constr.Expression :="a[t]-x[t]";
Constr.LowerBound :="0";
// Criterion function
Optima.CriterionFunction := "z[t]";
// Number of intervals
Optima.NodesCount := 8;
// Maximum number of iterations
Optima.MaxIterationsCount := 150;
// Solution search method
Optima.MethodType := CpNonLinearMethodType.SequentialQP;
// Parameters of differential revolution method
Optima.DifferEvolutionParams.PopulationSize := 100;
Optima.DifferEvolutionParams.MaxGeneration := 200;
Optima.DifferEvolutionParams.CrossProb := 0.60;
Optima.DifferEvolutionParams.DiffScale := 0.50;
Optima.DifferEvolutionParams.EvolutionStrategy := DiffEvolutionStrategyType.Best1Bin;
// Accuracy of solution
Optima.Tolerance := 0.001;
// Extremum type
Optima.Extremum := ExtremumType.Maximum;
// Model calculation:
Res := Optima.Evaluate(TimeInterval) As INonLoResults;
Debug.WriteLine("Status : " + Res.Status.ToString);
Debug.WriteLine("Error : " + Res.ErrorMsg);
Debug.WriteLine("Optimal value: " + Res.OptimalValue.ToString);
Debug.WriteLine("Optimal value by iterations:");
If res.Status = 0 Then
For i := 0 To Res.ObjValByIter.Length - 1 Do
Debug.WriteLine(Res.ObjValByIter[i]);
End For;
End If;
s := " ";
For j := 1 To Vars.Count Do
Vrbl := Vars.Item(j - 1);
s := s + Vrbl.Id + " ";
End For;
s:= s + "Trajectory";
Debug.WriteLine(s);
If Res.Status = 0 Then
For i := 1 To TimeInterval Do
s := "t=" + i.ToString + ", ";
For j := 1 To Vars.Count Do
Vrbl := Vars.Item(j - 1);
Val := Res.VarValues(Vrbl.Id)[i - 1];
s := s + Val.ToString + ", ";
End For;
Trajectory := res.CriterionFunctionTrajectory;
s:= s + Trajectory[i-1].ToString;
Debug.WriteLine(s);
End For;
End If;
End Sub UserProc;
After executing the example the console window displays the following:
Status : 0
Error : No error
Optimal value: 3875.00000000001
Optimal value by iterations:
3750
3870,36758872495
3870,40603555176
3874,99999253258
3875,00000000001
A Z X Trajectory
t=1, 1000, 2000, 0, 2000
t=2, 500, 3000, 0, 3000
t=3, 250, 3500, 0, 3500
t=4, 125, 3875.00000001261, 125.000000000008, 3875.00000000001
See also: