Improve optimization running time. (using c# SolverFoundation)

118 views Asked by At

I am having some trouble when I run the optimization code below in C#. The program ran well with the first three constraints. But once I added the fourth, it took the code a much longer time to run. To increase performance here are some of my thoughts:

  1. improve the way I structure the constraints
  2. trade the accuracy or the sampling size for the running time.

I am not sure how to achieve these. Any help/advice will be greatly appreciated.

// 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();
0

There are 0 answers