Skip to content

BlackNellore/NLPMD_Reduced-cost

Repository files navigation

MaxProfitFeeding

Diet optimization model for beef cattle based on "Nutritional Requirements for Beef Cattle" 8th Ed. (NASEM, 2016) and the "Ruminant Nutrition System" (Tedeschi & Fox, 2020a, 2020b).

This model has three main functionalities: (i) finding profit-maximizing diets; (ii) running batches of scenarios; (iii) finding the reduced cost for a given ingredient. We built this model on top of a prior publication with significant modifications. In this version there is the optinal usage of the RData file generated by the ruminant nutrition system, where the animal characteristics will be computed from. Moreover, the usage of the HiGHS solver was deprecated, by using the Pyomo library to manage the optimization engine.

This work is based on a theoretical framework and in no way replaces a professional nutritional analysis. We do not hold any responsibility for applications of this work in livestock. Consult a veterinary about feed formulations for your animals.

This model is part of a PhD project at the University of Edinburgh and a thematic project funded by FAPESP.

References

FAPESP project Title: "Sugarcane - Livestock Integration: Modeling and Optimization", FAPESP Project Number: 2017/11523-5

NASEM - National Academies of Sciences, Engineering, and Medicine 2016. Nutrient Requirements of Beef Cattle, 8th Revised Edition. National Academies Press, Washington, D.C.

Tedeschi, L.O., Fox, D.G., 2020a. The Ruminant Nutrition System, Volume I – An Applied Model for Predicting Nutrient Requirement and Feed Utilization in Ruminants, 3rd ed. XanDu Publishing, Inc., Ann Harbor, MI, USA.

Tedeschi, L.O., Fox, D.G., 2020b. The Ruminant Nutrition System: Volume II - Tables of Equations and Coding. XanEdu, Ann Harbor, MI, USA.

Getting Started

TLDR:

>pip3 install -r requirements
>python run.py
  • Input in "./input.xlsx"
  • Ouput in "./output.xlsx"
  • Log in "./activity.log"
  • Settings in "./config.py"

Prerequisites and Setup

This python project requires some libraries. They should be automatically installed if you execute with administrative rights:

>pip3 install -r requirements

List of libraries installed:

  • xlrd
  • openpyxl
  • aenum
  • numpy
  • pandas
  • scipy
  • pyomo
  • tqdm
  • rpy2

NOTE: Linear programming solver not distributed along. Open-source suggestion: GLPK. Comercial/academic suggestion: CPLEX.

Basic Run

  1. In the file config.py attent for the following:

    1. If you are using CPLEX on MacOS, make sure the solver is set to SOLVER = 'cplex_direct'; if on Windows, use SOLVER = 'cplex'. For further info, check the Pyomo documentation.

    2. If you don't have the RNS/image.RData file, or if you don't want to use the RNS to compute animal requirements, set in the config.py the option:

      RNS_FEED_PARAMETERS = {'source': None,
                             'report_diff': False,
                             'on_error': 0}
  2. Adjust your input in the file "./input.xlsx":

    1. Feeds:

      • Feed Scenario - All ingredients with the same value belongs to a group of ingredients that will be used in the optimization scneario (matched with sheet Scenario). [int]
      • ID - Ingredient ID to be matched with sheet Feed Library.[int]
      • Min %DM - Minimum ingredient inclusion as % of dry matter. [0 to 100]
      • Max %DM - Maximum ingredient inclusion as % of dry matter. [0 to 100]
      • Cost [US$/kg AF] - Ingredient cost per kg as fed (dry matter conversion is computed inside the code). [float]
      • Name - Ingredient name, usually fetched with the VLOOKUP function. [str]
    2. Scenario:

      • ID: Scenario ID [int]
      • Feed Scenario: Define which feed scenario should be match in the sheet "Feeds" [int]
      • Batch: ID crossed with table Batch
      • Breed: Breed Name (does not affect result)
      • SBW: Shrunk Bodyweight [100; 800]
      • BCS: Body Condition Score [0; 9]
      • BE: Breed Factor (check NASEM 2016, pg355 Table 19-1)
      • L: Lactation Factor {1, 1.2}
      • SEX: {1, 1.15}
      • a2: 0 if not considering acclimatization factor, check NASEM (2016) otherwise
      • PH: Rumen desired pH
      • Selling Price: Cattle Selling Price per [U$/kg]
      • Linearization factor: an coefficient to adjust nonlinear SWG by a line.
      • Algorithm: BF - Brute Force; GSS - Golden Section Search
      • Identifier: String to name sheets when writing results
      • LB: Concentration of Net Energy for Maintenance (CNEm) [Mcal/kg] lower bound (suggestion: 0.8)
      • UB: Concentration of Net Energy for Maintenance (CNEm) [Mcal/kg] upper bound (suggestion: 3.0)
      • Tol: Result tolerance (suggested: 0.01)
      • Obj: MaxProfit (maximizes profit), MinCost (minimizes cost), or MaxProfitSWG (maximize profit/shrunk weight gain)
  3. Prior to run, (i) make sure all ingredient in the sheet Feeds exist in the sheet Feed Library. (ii) If you are using the RNS, make sure the ingredients' ID match those in the RData file. (iii) Check if your solver can be found by Pyomo by running the following script in a Python console:

     import pyomo.environ as pyo
    
     print(pyo.SolverFactory('cplex').available())
     print(pyo.SolverFactory('cplex_direct').available())
     print(pyo.SolverFactory('glpk').available())
  4. Run:

    >python run.py
  5. Results (and a copy of the input file) are stored in a new folder with the timestamp inside Output/{TIMESTAMP}/{FILENAME}.xlsx. If there is no output file, either the problem is infeasible or some other error happened. This can be checked on the log at ./activity.log.

Batch Run

  1. The table 'Batch' takes 5 inputs:

    • Batch ID: ID to be crossed with sheet Scenario
    • Filename: path + filename of CSV file with batch info
    • Period col: name of the col that contains the IDs of each running
    • Initial period: pi such as 'Period col' ≥ pi
    • Final period: pf such as 'Period col' ≤ pf
  2. Example CSV file 'test.csv':

    | row_ids | DDGS_01 | Animal_price | ... | variable_m | | ----------|:-------------:|:-------------:| :----:|:-------------:| | 1 | 0.86 | 5.43 | ... | 17.4 | | 2 | 1.23 | 3.45 | ... | 13.2 | | ... |... | ... | ... | ... | | n | 2.26 | 4.25 | ... | 11.9 |

  3. For the table above 'Filename' = 'test.csv' and 'Period col' = 'row_ids'. We could also set 'Initial period' = 2 and 'Final period' = 7 or leave them blank to use the whole file.

  4. The following tables and columns can be have the values replaced for a batch column:

    1. Feeds:
      • Min %DM
      • Max %DM
      • Cost [US$/kg AF]
    2. Scenario
      • SBW
      • BCS
      • BE
      • L
      • SEX
      • a2
      • PH
      • Selling Price [US$]
      • Linearization factor
  5. To run the batch simply make sure that you place the name of the batch column in the cell that you want to run as a batch. For example, instead of putting a value in the column 'Selling Price [US$]' on table 'Scenario', one could write 'Animal_price', assuming the file showed on item 2.

NOTE: If a scenario has batch ID = -1 or blank, i.e., it is not a batch scenario, having strings in place of values will raise error. So pay attention if you have multiple scenarios and not all are batch.

Using Reduced cost search:

By default the search is disabled with parameter -1 in sheet "Scenario", column "find reduced cost".

To run the search, simply define the ID of the variable (ingredient) of interest. In the column "Ingredient Level", define the minimum inclusion level of the variable in the solution. Use whatever cost (preferably big) in the sheet "Feeds" for that particular ingredient. The final solution will give you a column in the output with the reduced cost obtained. This algorithm uses the bisection-search method to find the "nonlinear reduced cost".

IMPORTANT: Reduced cost search does not run in conjuction with LCA and multiobjective models.

NOTE: we use the expression "reduced cost" in the nonlinear model, simply refering to the Karush-Kuhn-Tucker conditions that set the minimum cost at which one ingredient becomes part of the basic set (x > 0) of the solution. The term was adopted from typical linear programming terminology for convenience.

Bonus

Settings

You can change the file names and other settings in config.py. Be sure to have headers and sheet names matching in the config.py and input.xlsx.

INPUT_FILE = {'filename': {'name': 'input.xlsx'},
              'sheet_feed_lib': {'name': 'Feed Library',
                                 'headers': [...]},
              'sheet_feeds': {'name': 'Feeds',
                              'headers': [...]},
              'sheet_scenario': {'name': 'Scenario',
                                 'headers': [...]}}
OUTPUT_FILE = 'output.xlsx'
SOLVER = 'cplex'

Solver

DEPRECATED: The usage open-source solver HiGHS to optimize the LP models, present in previous versions of this software, was deprecated since we adopted the Pyomo optimization interface. Alternatively, you can use CPLEX, GUROBI, GPLK and other solvers available for Pyomo by changing the header of config.py to:

SOLVER = "solver_name_here_just_like_in_Pyomo"
SOLVER = "cplex"
SOLVER = "glpk"

Be sure to setup CPLEX (or whatever solver) properly before running.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages