The matrix route (model_to_lp(),
solve_highs()) needs nothing beyond the ‘highs’ R package.
The code-generation routes run external toolchains, and multimod has to
find three executables:
| Route | Executable | Looked up by |
|---|---|---|
MathProg, solve_gmpl()
|
glpsol |
get_multimod_glpsol() |
JuMP, solve_jump()
|
julia |
get_multimod_julia() |
Pyomo, solve_pyomo()
|
python |
get_multimod_python() |
Each lookup checks, in this order, and stops at the first hit:
- an R option, set with
set_multimod_python(),set_multimod_julia(),set_multimod_glpsol()(or the corresponding options, such asoptions(multimod.python_path = ...)); - an environment variable:
MULTIMOD_PYTHON,MULTIMOD_JULIA,MULTIMOD_GLPSOL; - a YAML configuration file, project-level
.multimod.ymlfirst, then the user-level file undertools::R_user_dir("multimod", "config"); - automatic detection: for Python the conda environment named
multimodthrough reticulate; for glpsol the ‘glpsol’ R package, then the conda environment, then thePATH; for Julia thePATH.
multimod_config_show() prints what each lookup currently
resolves to and where the value comes from.
Setting a path
For the current session:
set_multimod_python("C:/Users/me/.conda/envs/multimod/python.exe")
set_multimod_julia("C:/Julia-1.11/bin/julia.exe")
set_multimod_glpsol("C:/glpk/bin/glpsol.exe")
get_multimod_julia()To make it permanent for one user, put the options in
~/.Rprofile (usethis::edit_r_profile() opens
it):
options(
multimod.python_path = "C:/Users/me/.conda/envs/multimod/python.exe",
multimod.julia_path = "C:/Julia-1.11/bin/julia.exe",
multimod.glpsol_path = "C:/glpk/bin/glpsol.exe"
)Environment variables suit CI and containers. In a shell:
export MULTIMOD_PYTHON=/usr/bin/python3
export MULTIMOD_JULIA=/usr/local/bin/julia
export MULTIMOD_GLPSOL=/usr/bin/glpsolA YAML file suits a project shared by several people:
multimod_config_write(
config = list(
python = list(path = "C:/Users/me/.conda/envs/multimod/python.exe",
env_name = "multimod"),
julia = list(path = "C:/Julia-1.11/bin/julia.exe"),
glpsol = list(path = "C:/glpk/bin/glpsol.exe")
),
global = FALSE # .multimod.yml in the working directory; TRUE = user level
)
multimod_config_path() # where the project file is
multimod_config_read()The file is plain YAML and can be edited by hand:
python:
path: "C:/Users/me/.conda/envs/multimod/python.exe"
env_name: "multimod"
julia:
path: "C:/Julia-1.11/bin/julia.exe"
glpsol:
path: "C:/glpk/bin/glpsol.exe"Add .multimod.yml to .gitignore when the
paths are user-specific.
To go back to automatic detection, clear the option:
set_multimod_python(NULL)GLPK
The ‘glpsol’ R package ships the glpsol executable,
which multimod finds automatically:
install.packages("glpsol")
get_multimod_glpsol()A system GLPK works as well: brew install glpk on macOS,
apt-get install glpk-utils on Debian and Ubuntu, winglpk or
MSYS2 on Windows. The conda environment that
mm_setup_python() creates also holds a copy. Check what
will be used:
system2(get_multimod_glpsol(), "--version")Julia
Install Julia from julialang.org and make sure the executable resolves:
get_multimod_julia()
system2(get_multimod_julia(), c("-e", "println(VERSION)"))The generated model.jl needs the packages JuMP, HiGHS,
Arrow, DataFrames and CSV. It installs any that are missing on its first
run, which takes a few minutes; to do it beforehand:
Python
mm_setup_python() creates a conda environment named
multimod with Python 3.14, installs pyomo, highspy, pyarrow
and pandas with pip and GLPK with conda, and activates it through
reticulate. Miniconda is installed first if there is none.
mm_check_python() reports the interpreter that will be
used, its version and the packages that fail to import.
solve_pyomo() uses the configured interpreter as it is;
solve_pyomo(ensure_env = TRUE) checks it first and runs
mm_setup_python() when it is not usable.
To use an existing interpreter instead, point to it and check it carries the packages a route needs:
set_multimod_python("/path/to/python")
mm_check_python(packages = c("pyomo", "highspy", "pyarrow"))When a tool is not found
-
multimod_config_show()says which source each path comes from. A stale option or environment variable wins over everything below it. -
Sys.which("julia")andSys.which("glpsol")show what thePATHresolves. On Windows the conda environment’sbindirectory is not on thePATH; multimod looks inside it for glpsol, but a shell will not. -
mm_check_python()reports whether the interpretersolve_pyomo()will use carries the needed packages.
