fsvolsay3.fs 2.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
// Copyright 2012 Hakan Kjellerstrand
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

open System
open Google.OrTools.FSharp
open Google.OrTools.LinearSolver


let solver (solverType:LinearProgramming) =
  let svr = new Solver(
      "Volsay3", enum<Solver.OptimizationProblemType>(solverType.Id));

  let products = ["Gas"; "Chloride"]
  let components = ["nitrogen"; "hydrogen"; "chlorine"]

  let demand = [[1.0;3.0;0.0]; [1.0;4.0;1.0]] // column vectors
  let stock = [50.0;180.0;40.0] // upper bound constraints for each component
  let profit = [30.0;40.0]

  // Variables
  let production = [ for i in 0 .. (products.Length-1) -> svr.MakeNumVar(0.0, 10000.0, products.[i]) ]

  // Constraints

  // generate column index selectors
  let cols = [ for i in 0 .. (demand.Length-1) -> i ]

  for row = 0 to (components.Length-1) do
      // generate constraint operands based on indices
      let constraintOperands = List.map (fun c ->  production.[c] * demand.[c].[row]) cols
      let linearExp = List.reduce (+) constraintOperands

      // create the constraint
      let rc = RangeConstraint(linearExp, Double.NegativeInfinity, stock.[row])
      svr.Add(rc) |> ignore


  // Objective
  let objectiveOperands = List.map (fun c ->  profit.[c] * production.[c]) cols
  let objectiveExp = List.reduce (+) objectiveOperands
  svr.Maximize(objectiveExp)

  let resultStatus = svr.Solve();

  match resultStatus with
  | status when status <> Solver.ResultStatus.OPTIMAL ->
      printfn "The problem does not have an optimal solution!"
      exit 0
  | _ ->
      printfn "\nProblem solved in %d milliseconds" (svr.WallTime())
      printfn "Iterations: %i\n" (svr.Iterations())

  printfn "Objective: %f" (svr.Objective().Value())
  products |> List.iteri (fun i x -> printfn "%-10s: %f ReducedCost: %f" x ((production.[i]).SolutionValue()) ((production.[i]).ReducedCost()) )

solver LinearProgramming.CLP