public Tuple <List <double>, List <List <double> >, List <List <double> >, List <double> > SolveProblem(List <List <double> > numerators, List <double> denominator, List <Constraint> _constraints, List <double> ls, List <double> ws, OptDirectionEnum _optDirection) { var fs = new List <double>(); var xs = new List <List <double> >(); var zs = new List <List <double> >(); var deltas = new List <double>(); var constraints = ConvertToDualConstraints(_constraints, denominator); for (int i = 0; i < numerators.Count; i++) { List <double> func = new List <double> { 0 }; func.AddRange(numerators[i]); try { Tuple <double, List <double>, List <double> > problem1 = Solve( constraints, func, _optDirection, denominator.Count, 0); fs.Add(problem1.Item1); xs.Add(problem1.Item2); zs.Add(problem1.Item3); } catch (NoOptimumException ex) { throw ex; } catch (Y0IsNullException ex) { throw ex; } } List <double> fun = new List <double>(); for (int i = 0; i < denominator.Count + 1; i++) { fun.Add(0); } fun.AddRange(ws); try { Tuple <double, List <double>, List <double> > problem = Solve( ConvertToDualConstraintsWithZ(constraints, numerators, ls, fs, _optDirection), fun, OptDirectionEnum.min, denominator.Count, ls.Count); fs.Add(problem.Item1); xs.Add(problem.Item2); zs.Add(problem.Item3); deltas = FindDeltas(problem.Item2, numerators, denominator, fs); } catch (NoOptimumException ex) { throw ex; } catch (Y0IsNullException ex) { throw ex; } return(new Tuple <List <double>, List <List <double> >, List <List <double> >, List <double> >(fs, xs, zs, deltas)); }
private Tuple <double, List <double>, List <double> > Solve(List <Constraint> _constraints, List <double> _function, OptDirectionEnum _optDirection, int xCount, int zCount) { Solver solver = Solver.CreateSolver("GLOP"); List <Variable> variables = new List <Variable>(); //add y for (int i = 0; i < _function.Count; i++) { variables.Add(solver.MakeNumVar(0.0, double.PositiveInfinity, "y" + i)); } List <Google.OrTools.LinearSolver.Constraint> constraints = CreateConstraints(solver, _constraints); SetConstraints(constraints, _constraints, variables); //setup function Objective objective = solver.Objective(); for (int i = 0; i < _function.Count; i++) { objective.SetCoefficient(variables[i], _function[i]); } if (_optDirection == OptDirectionEnum.max) { objective.SetMaximization(); } else { objective.SetMinimization(); } Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. if (resultStatus != Solver.ResultStatus.OPTIMAL) { throw new NoOptimumException(); //Console.WriteLine("The problem does not have an optimal solution!"); } if (variables[0].SolutionValue() == 0) { throw new Y0IsNullException(); } List <double> ys = new List <double>(); for (int i = 0; i < xCount + 1; i++) { ys.Add(variables[i].SolutionValue()); } List <double> zs = new List <double>(); for (int i = 0; i < zCount; i++) { zs.Add(variables[xCount + 1 + i].SolutionValue()); } return(new Tuple <double, List <double>, List <double> >(solver.Objective().Value(), ConvertToX(ys), zs)); }
private List <Constraint> ConvertToDualConstraintsWithZ(List <Constraint> _constraints, List <List <double> > numerators, List <double> ls, List <double> fOpts, OptDirectionEnum optDirection) { List <Constraint> constraintStructs = new List <Constraint>(); for (int i = 0; i < _constraints.Count; i++) { for (int j = 0; j < numerators.Count; j++) { _constraints[i].Coefficients.Add(0); } constraintStructs.Add(_constraints[i]); } for (int i = 0; i < numerators.Count; i++) { var coefs = new List <double>(); coefs.Add(0); coefs.AddRange(numerators[i]); for (int j = 0; j < numerators.Count; j++) { if (i == j) { if (optDirection == OptDirectionEnum.min) { coefs.Add(-1); } else { coefs.Add(1); } } else { coefs.Add(0); } } if (optDirection == OptDirectionEnum.min) { constraintStructs.Add(new Constraint(coefs, SymbolEnum.LessOrEqual, ls[i] + fOpts[i])); } else { constraintStructs.Add(new Constraint(coefs, SymbolEnum.MoreOrEqual, fOpts[i] - ls[i])); } } return(constraintStructs); }