[TOC]
using System;
using CenterSpace.NMath.Core;
using CenterSpace.NMath.Analysis;
namespace CenterSpace.NMath.Analysis.Examples.CSharp
{
class LinearProgrammingExample
{
/// <summary>
/// A .NET example in C# showing how to solve a linear system using linear programming and
/// the simplex method.
/// </summary>
static void Main(string[] args)
{
Console.WriteLine();
// A farmer has 640 acres of farmland. It can be planted with wheat, barley, corn or a
// combination of the three. The farmer wishes to maximize his profit subject to the
// limits on land, fertilizer, and water.
// Currently, wheat is $3.38/bushel. The farmer can expect a yield of 55 bushels/acre.
double wheatPrice = 3.38;
double wheatYield = 55.0;
double wheatRevenuePerAcre = wheatPrice * wheatYield;
// Currently, barley is $1.98/bushel. The farmer can expect a yield of 75 bushels/acre.
double barleyPrice = 1.98;
double barleyYield = 75.0;
double barleyRevenuePerAcre = barleyPrice * barleyYield;
// Currently, corn is $1.70/bushel. The farmer can expect a yield of 110 bushels/acre.
double cornPrice = 1.70;
double cornYield = 110.0;
double cornRevenuePerAcre = cornPrice * cornYield;
// Therefore, the objective function is:
Console.Write("Maximize " + wheatRevenuePerAcre + "w + ");
Console.WriteLine(barleyRevenuePerAcre + "b + " + cornRevenuePerAcre + "c");
Console.WriteLine("where");
Console.WriteLine();
DoubleVector revenue = new DoubleVector(wheatRevenuePerAcre, barleyRevenuePerAcre, cornRevenuePerAcre);
// Make a matrix big enough for 5 constraints and 3 variables.
DoubleMatrix constraints = new DoubleMatrix(5, 3);
// Make a vector of right-hand sides.
DoubleVector rightHandSides = new DoubleVector(constraints.Rows);
// The farmer has 8,000 lbs of nitrogen fertilizer. It's known that wheat requires
// 12 lb/acre, barley 5 lb/acre and corn 22 lb/acre.
Console.WriteLine("12w + 5b + 22c <= 8000");
constraints[0, Slice.All] = new DoubleVector(12.0, 5.0, 22.0);
rightHandSides[0] = 8000.0;
// The farmer has 22,000 lbs of phosphate fertilizer. It's known that wheat requires
// 30 lb/acre, barley 8 lb/acre and corn 50 lb/acre.
Console.WriteLine("30w + 8b + 50c <= 22000");
constraints[1, Slice.All] = new DoubleVector(30.0, 8.0, 50.0);
rightHandSides[1] = 22000.0;
// The farmer has a permit for 1,000 acre-feet of water. Wheat requires 1.5 ft of water,
// barley requires 0.7 and corn 2.2.
Console.WriteLine("1.5w + 0.7b + 2.2c <= 1200");
constraints[2, Slice.All] = new DoubleVector(1.5, 0.7, 2.2);
rightHandSides[2] = 1200.0;
// The farmer has a maximum of 640 acres for planting.
Console.WriteLine("w + b + c <= 640");
constraints[3, Slice.All] = new DoubleVector(1.0, 1.0, 1.0);
rightHandSides[3] = 640.0;
// Create an LP solver with an error tolerance of 0.001.
SimplexLPSolver solver = new SimplexLPSolver(0.001);
// Solve
solver.Solve(revenue, constraints, rightHandSides, 5, 0, 0);
// Was a finite solution found?
Console.WriteLine();
if (solver.IsGood)
{
Console.WriteLine("solution: " + solver.Solution.ToString("f0"));
Console.WriteLine();
Console.WriteLine("optimal value: " + solver.OptimalValue.ToString("f0"));
}
Console.WriteLine();
// Let's say the farmer is also contractually obligated to farm at least 50 acres
// of barley.
Console.WriteLine("Add variable bound: b >= 10");
DoubleVector lowerBounds = new DoubleVector(0.0, 10.0, 0.0);
DoubleVector upperBounds = new DoubleVector(640.0, 640.0, 640.0);
// Solve again
solver.Solve(revenue, constraints, rightHandSides, 5, 0, 0, lowerBounds, upperBounds);
// Good?
Console.WriteLine();
if (solver.IsGood)
{
Console.WriteLine("solution: " + solver.Solution.ToString("f0"));
Console.WriteLine();
Console.WriteLine("optimal value: " + solver.OptimalValue.ToString("f0"));
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Press Enter Key");
Console.Read();
} // Main
} // class
} // namespace
[TOC]