在 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&lt;Integer, Map&lt;String, Double&gt;&gt; extraVars 然后在evaluate 方法中填充extraVars,然后使用solution.getIteration 作为键调用engine.stop()

【讨论】:

1.好点子! 2. 工作完美非常感谢! 优秀。您能否将问题标记为“已回答”?

以上是关于在 AnyLogic 多目标优化中引用非决策/非优化变量的主要内容,如果未能解决你的问题,请参考以下文章

AnyLogic:有没有办法在优化实验中指定决策变量数组?

有没有办法在运行时确定 AnyLogic 中 ResourcePool 的容量?

多目标优化问题和遗传算法学习

如何设置 Anylogic 优化实验?

多目标优化示例 Pyomo

在模拟中优化决策的最佳算法