JijModeling 2.9.1 Release Notes#

Performance Improvements#

Faster construction of expressions and constraints#

Creating expressions and constraints now takes less time. The improvement is particularly noticeable in Jupyter notebooks and when running Python with -m or -c flags. Previously, the time to create each expression or constraint in these environments grew with the number of loaded Python modules, and could be many times longer than when running a script directly with python script.py. In these environments, model construction is now about as fast as in a script.

The following times are for building a model with 2,000 individually created constraints (CPython 3.14 on Linux):

How the benchmark was run

Before

After

Jupyter notebook

about 35 s

about 0.14 s

python -m

about 6.6 s

about 0.26 s

python script.py

about 0.53 s

about 0.25 s

Note, however, that creating many constraints of the same form one by one, as this benchmark does, is not the recommended way to write a model. Define such constraints as a constraint family instead (see Setting the Objective and Constraints). JijModeling can then handle them as a single unit, which makes building the model, constraint detection, and compilation into an OMMX instance all faster than with individually created constraints.

Feature Enhancements#

Additional improvements to LaTeX output#

We’ve improved how indices are displayed when indexing folds and genarray expressions. For example, when setting an axis in this TSP example:

import jijmodeling as jm 

@jm.Problem.define("tsp")
def tsp(problem):
    N = problem.Natural()
    x = problem.BinaryVar(shape=(N, N))
    d = problem.Float(shape=(N,N))
    problem += jm.sum(d[i, j] * x[(t + 1) % N, j] for t in N for i in N for j in N)
    problem += problem.Constraint("one time", x.sum(axis=0) == 1)
    problem += problem.Constraint("one city", x.sum(axis=1) == 1)
tsp
\[\begin{array}{rl} \text{Problem}\colon &\text{tsp}\\\displaystyle \min &\displaystyle \sum _{t=0}^{N-1}{\sum _{i=0}^{N-1}{\sum _{j=0}^{N-1}{{d}_{i,j}\cdot {x}_{\left(t+1\right)\bmod N,j}}}}\\&\\\text{s.t.}&\\&\begin{aligned} \text{one city}&\quad \displaystyle \sum _{j=0}^{N-1}{{x}_{i,j}}=1\quad \forall i\;\text{s.t.}\;i\in \left\{0,\ldots ,N-1\right\}\\\text{one time}&\quad \displaystyle \sum _{j=0}^{N-1}{{x}_{j,i}}=1\quad \forall i\;\text{s.t.}\;i\in \left\{0,\ldots ,N-1\right\}\end{aligned} \\&\\\text{where}&\\&\text{Decision Variables:}\\&\qquad \begin{alignedat}{2}{x}_{i,j}&\in \left\{0,1\right\}&\qquad &\text{a }2\text{-dim array of }\text{binary}\text{ decision variables}\\&\forall i\in \left\{0,\ldots ,N-1\right\},\;\forall j\in \left\{0,\ldots ,N-1\right\}&&\\\end{alignedat}\\&\\&\text{Placeholders:}\\&\qquad \begin{alignedat}{2}{d}_{i,j}&\in \mathbb{R}&\qquad &\text{a }2\text{-dim array of placeholders with elements in }\mathbb{R}\\&\forall i\in \left\{0,\ldots ,N-1\right\},\;\forall j\in \left\{0,\ldots ,N-1\right\}&&\\&&&\\N&\in \mathbb{N}&\qquad &\text{a scalar placeholder in }\mathbb{N}\\\end{alignedat}\end{array} \]

Some other expressions involving subscript on genarray are now also reduced in LaTeX output:

@jm.Problem.define("problem")
def prob(problem):
  N = problem.Natural()
  M = problem.Natural()
  x = problem.IntegerVar(shape=(M,N), lower_bound=1, upper_bound=10)
  a = problem.Integer(shape=(M,N))

  A = problem.NamedExpr(jm.genarray(x[m,n] * a[m] for (n, m) in (N, M)).sum())
  B = problem.NamedExpr(jm.sum(jm.genarray(x[m,n] * a[m] for (n, m) in (N, M))[i, j] for i in N for j in M))
 
prob
\[\begin{array}{rl} \text{Problem}\colon &\text{problem}\\\displaystyle \min &\displaystyle 0\\&\\\text{where}&\\&\text{Decision Variables:}\\&\qquad \begin{alignedat}{2}{x}_{i,j}&\in \mathbb{Z}\;\left(1\leq {x}_{i,j}\leq 10\right)&\qquad &\text{a }2\text{-dim array of }\text{integer}\text{ decision variables}\\&\forall i\in \left\{0,\ldots ,M-1\right\},\;\forall j\in \left\{0,\ldots ,N-1\right\}&&\\\end{alignedat}\\&\\&\text{Placeholders:}\\&\qquad \begin{alignedat}{2}{a}_{i,j}&\in \mathbb{Z}&\qquad &\text{a }2\text{-dim array of placeholders with elements in }\mathbb{Z}\\&\forall i\in \left\{0,\ldots ,M-1\right\},\;\forall j\in \left\{0,\ldots ,N-1\right\}&&\\&&&\\M&\in \mathbb{N}&\qquad &\text{a scalar placeholder in }\mathbb{N}\\&&&\\N&\in \mathbb{N}&\qquad &\text{a scalar placeholder in }\mathbb{N}\\\end{alignedat}\\&\\&\text{Named Expressions:}\\&\qquad \begin{alignedat}{2}A&=\sum _{n=0}^{N-1}{\sum _{m=0}^{M-1}{{x}_{m,n}\cdot {a}_{m}}}&\quad &\in \mathbb{Z}\\&&&\\B&=\sum _{i=0}^{N-1}{\sum _{j=0}^{M-1}{{x}_{j,i}\cdot {a}_{j}}}&\quad &\in \mathbb{Z}\\\end{alignedat}\end{array} \]

Easier skill discovery for agents#

Instructions for obtaining the skill are now included in the README, API Reference, package metadata, module documentation, and other places. Although manual installation remains more reliable, this change makes it easier for coding agents to discover the skill automatically and write idiomatic JijModeling code.