Reputation: 29
I am trying to re-produce the following Excel Solver GRG Nonlinear optimization using the Microsoft Solver Foundation in VB.NET (numbers are simplified for the sake of this example):
This optimization is subject to the following relationships:
Is it possible to solve such a problem using Solver Foundation? When trying to implement this, the two things I struggled with are:
model.AddGoal("total_gas_rate", GoalKind.[not sure what goes here], Well1PGasRate + Well2PGasRate
), but how do I define the other one?Thanks!
Upvotes: 1
Views: 1568
Reputation: 1
Answer in C#:
static void SolverGasRate()
{
Console.WriteLine("\nBegin Solver Gas Rate using Solver Context MSF\n");
var solver = SolverContext.GetContext();
var model = solver.CreateModel();
var decisionWell1OilRate = new Decision(Domain.IntegerNonnegative, "Well1OilRate");
model.AddDecision(decisionWell1OilRate);
var decisionWell2GasRate = new Decision(Domain.IntegerNonnegative, "Well2GasRate");
model.AddDecision(decisionWell2GasRate);
Goal goal = model.AddGoal("Goal", GoalKind.Maximize, TotalGasRateTerm(decisionWell1OilRate, decisionWell2GasRate));
model.AddConstraint("Objective", TotalGasRateTerm(decisionWell1OilRate, decisionWell2GasRate) <= 100000);
model.AddConstraint("Constraint1", decisionWell1OilRate * 5 >= 0);
model.AddConstraint("Constraint2", decisionWell1OilRate * 5 <= 1000);
model.AddConstraint("Constraint3", decisionWell2GasRate <= 2000);
var solution = solver.Solve();
double Well1OilRate = decisionWell1OilRate.GetDouble();
double Well2GasRate = decisionWell2GasRate.GetDouble();
Console.WriteLine("Well1OilRate: " + (Well1OilRate).ToString());
Console.WriteLine("Well1GasRate: " + (Well1OilRate*5).ToString());
Console.WriteLine("Well2GasRate: " + (Well2GasRate).ToString());
Console.WriteLine("TotalGasRate: " + TotalGasRate(Well1OilRate, Well2GasRate).ToString());
Console.WriteLine("\nEnd Solver demo\n");
}
static Term TotalGasRateTerm(Decision decisionWell1OilRate, Decision decisionWell2GasRate)
{
return (decisionWell1OilRate * 5) + decisionWell2GasRate;
}
static double TotalGasRate(double Well1OilRate, double Well2GasRate)
{
return (Well1OilRate * 5) + Well2GasRate;
}
Output:
Begin Solver Gas Rate using Solver Context MSF
Well1OilRate: 200
Well1GasRate: 1000
Well2GasRate: 2000
TotalGasRate: 3000
End Solver demo
Upvotes: 0
Reputation: 599
This answer only addresses part 1 of your question and in a conceptual manner, but hopefully it is helpful. If you're trying to optimize for a specific value target
and the output of your function is output
then you could try something like this pseudocode:
minimize(absolute_value(output/target-1))
Effectively, this will give you a value that reaches zero as the output of your function nears the target value. So you can still use an optimization engine that minimizes the final output of your function.
Upvotes: 0