ソルバーアドインを使用して、平方根を含む方程式のセットを最大化する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();
}