在 AnyLogic 多目标优化中引用 Non-Decision/Non-Optimization 个变量
Referencing Non-Decision/Non-Optimization Variables in AnyLogic MultiObjective Optimization
TLDR:希望从 OptQuest 解决方案中提取非决策变量的值,或者找到一个可行的解决方法来获取此信息。
我目前在 AnyLogic 中 运行 进行加权多 objective 优化(自定义)实验,处理分销渠道中制造商、分销商和零售商的利润。
我的决策变量是每个成员的再订货点 (r) 和再订货数量 (Q)。我的objective是渠道的利润(root.MultObjs)和零售商的利润(root.RObj)。
try {
// Create Engine, initialize random number generator:
Engine engine = createEngine();
engine.setStartTime(0.0);
engine.setTimeUnit(DAY);
// Set stop time:
engine.setStopTime( 365 );
// ***Create optimization variable***
final COptQuestDiscreteVariable Rr = new COptQuestDiscreteVariable();
Rr.SetLowerBound(100);
Rr.SetUpperBound(3000);
Rr.SetStepSize(100);
final COptQuestDiscreteVariable RQ = new COptQuestDiscreteVariable();
RQ.SetLowerBound(100);
RQ.SetUpperBound(3000);
RQ.SetStepSize(100);
final COptQuestDiscreteVariable Dr = new COptQuestDiscreteVariable();
Dr.SetLowerBound(100);
Dr.SetUpperBound(10000);
Dr.SetStepSize(100);
final COptQuestDiscreteVariable DQ = new COptQuestDiscreteVariable();
DQ.SetLowerBound(100);
DQ.SetUpperBound(10000);
DQ.SetStepSize(100);
final COptQuestDiscreteVariable Mr = new COptQuestDiscreteVariable();
Mr.SetLowerBound(100);
Mr.SetUpperBound(15000);
Mr.SetStepSize(100);
final COptQuestDiscreteVariable MQ = new COptQuestDiscreteVariable();
MQ.SetLowerBound(100);
MQ.SetUpperBound(15000);
MQ.SetStepSize(100);
// add parameters
final COptQuestContinuousVariable R_Inv = new COptQuestContinuousVariable();
// ***Create objectives***
final COptQuestObjective obj1 = new COptQuestUserControlledObjective(); //Retailer
obj1.SetMaximize();
final COptQuestObjective obj2 = new COptQuestUserControlledObjective(); //Chain
obj2.SetMaximize();
//weighted coefficients starts here
final COptQuestWeightedMultiObjective weightedMultiObjective = new COptQuestWeightedMultiObjective();
weightedMultiObjective.AddObjective(obj1,0);
weightedMultiObjective.AddObjective(obj2,1);
//set requirements
COptQuestUpperRequirement ReqROverstock= new COptQuestUpperRequirement(0);
COptQuestUpperRequirement ReqDOverstock= new COptQuestUpperRequirement(0);
COptQuestUpperRequirement ReqMOverstock= new COptQuestUpperRequirement(0);
// Create optimization engine
final COptQuestOptimization opt = ExperimentOptimization.createOptimization(engine, new OptimizationCallback()
{
@Override
public void evaluate(COptQuestOptimization optimization,
COptQuestSolution solution, Engine engine)
{
// Create new root object:
Main root = new Main( engine, null, null );
// Setup parameters of root object here
//set default values of vars
root.setParametersToDefaultValues();
//set decision variables
//***left side model*** ***right side*** optimization
root.Rr = (int)solution.GetVariableValue(Rr);
root.RQ = (int)solution.GetVariableValue(RQ);
root.Dr = (int)solution.GetVariableValue(Dr);
root.DQ = (int)solution.GetVariableValue(DQ);
root.Mr = (int)solution.GetVariableValue(Mr);
root.MQ = (int)solution.GetVariableValue(MQ);
// Prepare Engine for simulation:
root.getDefaultRandomGenerator().setSeed(1);
engine.start( root );
// Start simulation in fast mode:
engine.runFast();
// Process results of simulation here
//***left side method expression*** ***right side model objective****
solution.SetObjectiveValue( obj1, root.RObj );
solution.SetObjectiveValue( obj2, root.MultObjs );
//set requirements here
solution.SetRequirementValue(ReqROverstock,root.ROverstock);
solution.SetRequirementValue(ReqDOverstock,root.DOverstock);
solution.SetRequirementValue(ReqMOverstock,root.MOverstock);
// Destroy the model:
engine.stop();
}
});
// ***Setup optimization engine***
//add decision variables
opt.AddVariable(Rr);
opt.AddVariable(RQ);
opt.AddVariable(Dr);
opt.AddVariable(DQ);
opt.AddVariable(Mr);
opt.AddVariable(MQ);
// add constraints
opt.AddRequirement(ReqROverstock);
opt.AddRequirement(ReqDOverstock);
opt.AddRequirement(ReqMOverstock);
// add objective
opt.AddObjective(weightedMultiObjective);
// Set the number of iterations to run
opt.SetMaximumIterations(500);
// Perform optimization
opt.Optimize();
//setup for printout
traceln(" Lambda : Param Rr : Param RQ : Param Dr : Param DQ : Param Mr : Param MQ: : Best obj1(R) : Best obj2(Chain) : DProfit : MProfit : feasible?");
traceln("-----------------------------------------------------------------------------------------------------------------------------------------------------------");
double nLambda=10; //sets resolution of weighted multi-objective search
for (int i=0; i <=nLambda; i++)
{
double lweight=i/nLambda;
weightedMultiObjective.SetObjectiveCoefficient(obj1, lweight);
weightedMultiObjective.SetObjectiveCoefficient(obj2, (1- lweight));
opt.Recalculate();
COptQuestSolution bestSolution = opt.GetBestSolution();
//COptQuestSolution currentSolution=opt.GetIterationSolution(500);
// Output results
traceln(String.format(" %1.2f : %7.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8s",
lweight, bestSolution.GetVariableValue(Rr),bestSolution.GetVariableValue(RQ),
bestSolution.GetVariableValue(Dr),bestSolution.GetVariableValue(DQ),,
bestSolution.GetVariableValue(Mr),bestSolution.GetVariableValue(MQ),
bestSolution.GetObjectiveValue(obj1),
bestSolution.GetObjectiveValue(obj2),
null,
null,
bestSolution.IsFeasible()));
}
}
catch (COptQuestException e) {
traceln(e.Description());
}
我通过 OptQuest 文档选择了自己的方式,并设法获得了一个可执行模型,该模型在实验结束时打印我的决策变量和 objectives。我真正想做的是从最优解中提取非决策变量(root.RBackOrderCost、root.RCarryingCost)的实例,并将它们包含在输出中。我 运行 遇到的问题是 OptQuestSolution Class 似乎只关心决策变量的输入和 objective 的输出,到我们已经弄清楚了,引擎已经被破坏了,所以我不能只从根目录中提取一个值。
我扔了几个冰雹玛丽无济于事:
- 我试图创建一个虚拟决策变量(甚至是一个虚拟 objective)来在引擎被销毁之前将值存储在其中,但这没有用。
- 我还尝试将模拟回调中的变量值存储到回调外部的数组中。也不走运。
不幸的是,没有简单的方法让 COptQuestSolution
携带额外的变量。我之前这样做的方法是在 root
对象被销毁之前保存额外的信息。要做到这一点:
- 在
evaluate
之外创建一个 Map<Integer, Map<String, Double>> extraVars
- 然后在调用
engine.stop()
之前在 evaluate
方法中填充 extraVars
使用 solution.getIteration
作为键
TLDR:希望从 OptQuest 解决方案中提取非决策变量的值,或者找到一个可行的解决方法来获取此信息。
我目前在 AnyLogic 中 运行 进行加权多 objective 优化(自定义)实验,处理分销渠道中制造商、分销商和零售商的利润。 我的决策变量是每个成员的再订货点 (r) 和再订货数量 (Q)。我的objective是渠道的利润(root.MultObjs)和零售商的利润(root.RObj)。
try {
// Create Engine, initialize random number generator:
Engine engine = createEngine();
engine.setStartTime(0.0);
engine.setTimeUnit(DAY);
// Set stop time:
engine.setStopTime( 365 );
// ***Create optimization variable***
final COptQuestDiscreteVariable Rr = new COptQuestDiscreteVariable();
Rr.SetLowerBound(100);
Rr.SetUpperBound(3000);
Rr.SetStepSize(100);
final COptQuestDiscreteVariable RQ = new COptQuestDiscreteVariable();
RQ.SetLowerBound(100);
RQ.SetUpperBound(3000);
RQ.SetStepSize(100);
final COptQuestDiscreteVariable Dr = new COptQuestDiscreteVariable();
Dr.SetLowerBound(100);
Dr.SetUpperBound(10000);
Dr.SetStepSize(100);
final COptQuestDiscreteVariable DQ = new COptQuestDiscreteVariable();
DQ.SetLowerBound(100);
DQ.SetUpperBound(10000);
DQ.SetStepSize(100);
final COptQuestDiscreteVariable Mr = new COptQuestDiscreteVariable();
Mr.SetLowerBound(100);
Mr.SetUpperBound(15000);
Mr.SetStepSize(100);
final COptQuestDiscreteVariable MQ = new COptQuestDiscreteVariable();
MQ.SetLowerBound(100);
MQ.SetUpperBound(15000);
MQ.SetStepSize(100);
// add parameters
final COptQuestContinuousVariable R_Inv = new COptQuestContinuousVariable();
// ***Create objectives***
final COptQuestObjective obj1 = new COptQuestUserControlledObjective(); //Retailer
obj1.SetMaximize();
final COptQuestObjective obj2 = new COptQuestUserControlledObjective(); //Chain
obj2.SetMaximize();
//weighted coefficients starts here
final COptQuestWeightedMultiObjective weightedMultiObjective = new COptQuestWeightedMultiObjective();
weightedMultiObjective.AddObjective(obj1,0);
weightedMultiObjective.AddObjective(obj2,1);
//set requirements
COptQuestUpperRequirement ReqROverstock= new COptQuestUpperRequirement(0);
COptQuestUpperRequirement ReqDOverstock= new COptQuestUpperRequirement(0);
COptQuestUpperRequirement ReqMOverstock= new COptQuestUpperRequirement(0);
// Create optimization engine
final COptQuestOptimization opt = ExperimentOptimization.createOptimization(engine, new OptimizationCallback()
{
@Override
public void evaluate(COptQuestOptimization optimization,
COptQuestSolution solution, Engine engine)
{
// Create new root object:
Main root = new Main( engine, null, null );
// Setup parameters of root object here
//set default values of vars
root.setParametersToDefaultValues();
//set decision variables
//***left side model*** ***right side*** optimization
root.Rr = (int)solution.GetVariableValue(Rr);
root.RQ = (int)solution.GetVariableValue(RQ);
root.Dr = (int)solution.GetVariableValue(Dr);
root.DQ = (int)solution.GetVariableValue(DQ);
root.Mr = (int)solution.GetVariableValue(Mr);
root.MQ = (int)solution.GetVariableValue(MQ);
// Prepare Engine for simulation:
root.getDefaultRandomGenerator().setSeed(1);
engine.start( root );
// Start simulation in fast mode:
engine.runFast();
// Process results of simulation here
//***left side method expression*** ***right side model objective****
solution.SetObjectiveValue( obj1, root.RObj );
solution.SetObjectiveValue( obj2, root.MultObjs );
//set requirements here
solution.SetRequirementValue(ReqROverstock,root.ROverstock);
solution.SetRequirementValue(ReqDOverstock,root.DOverstock);
solution.SetRequirementValue(ReqMOverstock,root.MOverstock);
// Destroy the model:
engine.stop();
}
});
// ***Setup optimization engine***
//add decision variables
opt.AddVariable(Rr);
opt.AddVariable(RQ);
opt.AddVariable(Dr);
opt.AddVariable(DQ);
opt.AddVariable(Mr);
opt.AddVariable(MQ);
// add constraints
opt.AddRequirement(ReqROverstock);
opt.AddRequirement(ReqDOverstock);
opt.AddRequirement(ReqMOverstock);
// add objective
opt.AddObjective(weightedMultiObjective);
// Set the number of iterations to run
opt.SetMaximumIterations(500);
// Perform optimization
opt.Optimize();
//setup for printout
traceln(" Lambda : Param Rr : Param RQ : Param Dr : Param DQ : Param Mr : Param MQ: : Best obj1(R) : Best obj2(Chain) : DProfit : MProfit : feasible?");
traceln("-----------------------------------------------------------------------------------------------------------------------------------------------------------");
double nLambda=10; //sets resolution of weighted multi-objective search
for (int i=0; i <=nLambda; i++)
{
double lweight=i/nLambda;
weightedMultiObjective.SetObjectiveCoefficient(obj1, lweight);
weightedMultiObjective.SetObjectiveCoefficient(obj2, (1- lweight));
opt.Recalculate();
COptQuestSolution bestSolution = opt.GetBestSolution();
//COptQuestSolution currentSolution=opt.GetIterationSolution(500);
// Output results
traceln(String.format(" %1.2f : %7.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8.2f : %8s",
lweight, bestSolution.GetVariableValue(Rr),bestSolution.GetVariableValue(RQ),
bestSolution.GetVariableValue(Dr),bestSolution.GetVariableValue(DQ),,
bestSolution.GetVariableValue(Mr),bestSolution.GetVariableValue(MQ),
bestSolution.GetObjectiveValue(obj1),
bestSolution.GetObjectiveValue(obj2),
null,
null,
bestSolution.IsFeasible()));
}
}
catch (COptQuestException e) {
traceln(e.Description());
}
我通过 OptQuest 文档选择了自己的方式,并设法获得了一个可执行模型,该模型在实验结束时打印我的决策变量和 objectives。我真正想做的是从最优解中提取非决策变量(root.RBackOrderCost、root.RCarryingCost)的实例,并将它们包含在输出中。我 运行 遇到的问题是 OptQuestSolution Class 似乎只关心决策变量的输入和 objective 的输出,到我们已经弄清楚了,引擎已经被破坏了,所以我不能只从根目录中提取一个值。 我扔了几个冰雹玛丽无济于事:
- 我试图创建一个虚拟决策变量(甚至是一个虚拟 objective)来在引擎被销毁之前将值存储在其中,但这没有用。
- 我还尝试将模拟回调中的变量值存储到回调外部的数组中。也不走运。
不幸的是,没有简单的方法让 COptQuestSolution
携带额外的变量。我之前这样做的方法是在 root
对象被销毁之前保存额外的信息。要做到这一点:
- 在
evaluate
之外创建一个 - 然后在调用
engine.stop()
之前在evaluate
方法中填充extraVars
使用solution.getIteration
作为键
Map<Integer, Map<String, Double>> extraVars