0

当我在 C# 中运行下面的优化代码时遇到了一些麻烦。该程序在前三个约束条件下运行良好。但是一旦我添加了第四个,代码就需要更长的时间才能运行。为了提高性能,这里有一些我的想法:

  1. 改进我构建约束的方式
  2. 以精度或采样大小换取运行时间。

我不确定如何实现这些。任何帮助/建议将不胜感激。

// Create solver context and model
SolverContext context = SolverContext.GetContext();
context.ClearModel();
Model model = context.CreateModel();

// Add decisions, validList has 8 items
var decisions = validList.Select(it => new Decision(Domain.RealNonnegative, "wt" + it.ToString()));
model.AddDecisions(decisions.ToArray());

// Add goal: Min Variance
var objective = new SumTermBuilder(8 * 8);
for (int i = 0; i < 8; i++)
{
    var wtDecisioni = model.Decisions.First(it => it.Name == "wt" + i);
    for (int j = 0; j <8; j++)
    {
        var wtDecisionj = model.Decisions.First(it => it.Name == "wt" + j);
        objective.Add(wtDecisioni * wtDecisionj * this._covarMatrix[i, j]);
    }
}
model.AddGoal("MinVariance", GoalKind.Minimize, objective.ToTerm());

// Add constraints
//constraint 1: total weight is 1
var wtComponents = new SumTermBuilder(8);
foreach (int sID in validList)
{
    var wtDecision = model.Decisions.First(it => it.Name == "wt" + sID.ToString());
    wtComponents.Add(wtDecision);
}
Term wtConstraint;
wtConstraint = wtComponents.ToTerm() == 1d; ;
model.AddConstraint("Total_Weight", wtConstraint);

//constraint 2: min and max weight
foreach (int sID in validList)
{
    var wtDecision = model.Decisions.First(it => it.Name == "wt" + sID.ToString());
    model.AddConstraint("bound" + sID.ToString(), this._minWeight[sID] <= wtDecision <= this._maxWeight[sID]);
}

//constraint 3: desired return
var wtComponents3 = new SumTermBuilder(8);
foreach (int sID in validList)
{
    var wtDecision = model.Decisions.First(it => it.Name == "wt" + sID.ToString());
    wtComponents3.Add(wtDecision * this._returns[sID]);
}
Term wtConstraint3;
wtConstraint3 = wtComponents3.ToTerm() == desiredReturn; ;
model.AddConstraint("Desired_Return", wtConstraint3);

//constraint 4: total allowable shift from the original weights
var wtComponents4 = new SumTermBuilder(decisions.Count());
foreach (int sID in validList)
{
    var wtDecision = model.Decisions.First(it => it.Name == "wt" + sID.ToString());
    wtComponents4.Add(Model.Abs(wtDecision - originalWt[sID]));
}
Term wtConstraint4;
wtConstraint4 = wtComponents4.ToTerm() <= movablePortion; ;
model.AddConstraint("Movable_Portion", wtConstraint4);

// Solve problem
var solution = context.Solve();
4

0 回答 0