3

ソルバーアドインを使用して、平方根を含む方程式のセットを最大化するExcelワークブックがあります(たとえば、非線形です)。Microsoft Solver Foundationを使用してC#でこれを再実装しようとしています。いくつかの異なるディレクティブを試しましたが、Excelで取得した結果を再現するソルバーを見つけることができませんでした。

ハイブリッドローカル検索を使用してみましたが、結果がすべて間違っており、結果として得られる最大化が優れているとは言えません。内点法を使用して(ExcelとC#の両方から)平方根を削除すると、Excelの最適化にかなり近づきますが、正方形を含むExcelモデルと一致させようとしているため、これは役に立ちません。根。

ハイブリッド局所探索の問題は、グローバルな最大値が得られないことだと思います。NLPをサポートする他の組み込みディレクティブは見つかりませんでした。

ExcelソルバーはGRG2アルゴリズムを使用していると思います。MSFでExcelソルバーが使用するアルゴリズムを再現する方法はありますか?

参考までに、コメント'//#######'を前に付けて変更を加えたMSFに付属のQPの例を次に示します。

public string Solve()
        {
            /***************************
            /*Construction of the model*
            /***************************/
            SolverContext context = SolverContext.GetContext();
            //For repeating the solution with other minimum returns
            context.ClearModel();

            //Create an empty model from context
            Model portfolio = context.CreateModel();

            //Create a string set with stock names
            Set setStocks = new Set(Domain.Any, "Stocks");

            /****Decisions*****/

            //Create decisions bound to the set. There will be as many decisions as there are values in the set
            Decision allocations = new Decision(Domain.RealNonnegative, "Allocations", setStocks);
            allocations.SetBinding(StocksHistory, "Allocation", "Stock");
            portfolio.AddDecision(allocations);

            /***Parameters***/

            //Create parameters bound to Covariant matrix
            Parameter pCovariants = new Parameter(Domain.Real, "Covariants", setStocks, setStocks);
            pCovariants.SetBinding(Covariants, "Variance", "StockI", "StockJ");

            //Create parameters bound to mean performance of the stocks over 12 month period
            Parameter pMeans = new Parameter(Domain.Real, "Means", setStocks);
            pMeans.SetBinding(StocksHistory, "Mean", "Stock");

            portfolio.AddParameters(pCovariants, pMeans);

            /***Constraints***/

            //Portion of a stock should be between 0 and 1
            portfolio.AddConstraint("portion", Model.ForEach(setStocks, stock => 0 <= allocations[stock] <= 1));

            //Sum of all allocations should be equal to unity
            portfolio.AddConstraint("SumPortions", Model.Sum(Model.ForEach(setStocks, stock => allocations[stock])) == 1);


            /***Goals***/

            portfolio.AddGoal("Variance", GoalKind.Maximize,
                // ####### Include a inner product of the means and weights  to form utility curve
                Model.Sum
                (
                    Model.ForEach
                        (
                            setStocks, x =>
                                        Model.Product(
                                            allocations[x],
                                            pMeans[x])
                        )
                )
                -
                // ####### Use square root of variance to get volatility instead.  This makes the problem non-linear
                Model.Sqrt(
                    Model.Sum
                    (
                        Model.ForEach
                        (
                            setStocks, stockI =>
                            Model.ForEach
                            (
                                setStocks, stockJ =>
                                Model.Product(pCovariants[stockI, stockJ], allocations[stockI], allocations[stockJ])
                            )
                        )
                    )
                )
             );
            // ####### remove event handler        

            /*******************
            /*Solve the model  *
            /*******************/

            // ####### Use an NLP algorithm directive
            Solution solution = context.Solve(new HybridLocalSearchDirective());

            // ####### remove conditions on propagate
                context.PropagateDecisions();

            // ####### Remove save.  Can't save an NLP Model

            Report report = solution.GetReport();
            return report.ToString();
        }
4

0 に答える 0