在 AnyLogic 多目标优化中引用非决策/非优化变量
Posted
技术标签:
【中文标题】在 AnyLogic 多目标优化中引用非决策/非优化变量【英文标题】:Referencing Non-Decision/Non-Optimization Variables in AnyLogic MultiObjective Optimization 【发布时间】:2021-12-12 05:41:18 【问题描述】:TLDR:希望从 OptQuest 解决方案中提取非决策变量的值,或找到可行的解决方法来获取此信息。
我目前正在 AnyLogic 中运行加权多目标优化(自定义)实验,该实验处理分销渠道中制造商、分销商和零售商的利润。 我的决策变量是每个成员的再订货点 (r) 和再订货数量 (Q)。我的目标是渠道的利润 (root.MultObj) 和零售商的利润 (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 文档选择了自己的方式,并设法获得了一个可执行模型,该模型在实验结束时打印了我的决策变量和目标。我真正想做的是从最佳解决方案中提取非决策变量(root.RBackOrderCost、root.RCarryingCost)的实例,并将它们包含在输出中。我遇到的问题是 OptQuestSolution 类似乎只关心决策变量的输入和目标的输出,当我们弄清楚这些时,引擎已经被破坏了,所以我不能只从根中提取一个值。 我扔了几个冰雹-玛丽无济于事:
-
我尝试创建一个虚拟决策变量(甚至是虚拟目标)来在引擎被销毁之前在其中存储值,但这没有奏效。
我还尝试将模拟回调中的变量值存储到回调之外的数组中。那里也没有运气。
【问题讨论】:
请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。 【参考方案1】:不幸的是,没有简单的方法让COptQuestSolution
携带额外的变量。我之前这样做的方法是在 root
对象被销毁之前保存额外的信息。这样做:
-
在
evaluate
之外创建一个Map<Integer, Map<String, Double>> extraVars
然后在evaluate
方法中填充extraVars
,然后使用solution.getIteration
作为键调用engine.stop()
【讨论】:
1.好点子! 2. 工作完美非常感谢! 优秀。您能否将问题标记为“已回答”?以上是关于在 AnyLogic 多目标优化中引用非决策/非优化变量的主要内容,如果未能解决你的问题,请参考以下文章