JijModeling 2.9.1 リリースノート#

パフォーマンス改善#

式・制約の構築の高速化#

式や制約の作成にかかる時間が短縮されました。 特に Jupyter Notebook 上、python -m や python -c で実行した場合に、大きな効果があります。 従来、これらの環境では、式や制約を一つ作成するのにかかる時間が、読み込み済みの Python モジュール数に応じて増えていました。そのため、python script.py で直接実行する場合の何倍も時間がかかることがありました。 これらの環境でも、スクリプト実行と同程度の速さでモデルを構築できるようになりました。

以下は、制約を一つずつ 2,000 個作成してモデルを構築した際の所要時間です(CPython 3.14、Linux)。

実行方法

変更前

変更後

Jupyter Notebook

約 35 秒

約 0.14 秒

python -m

約 6.6 秒

約 0.26 秒

python script.py

約 0.53 秒

約 0.25 秒

ただし、このベンチマークのように同じ形の制約を一つずつ大量に作成する方法は推奨しません。 そのような制約は制約条件の族として定義してください(目的関数と制約条件の設定 を参照)。族として定義すると JijModeling はそれらの制約を一つの定義として扱えるため、モデルの構築・制約検出・ OMMX インスタンスへのコンパイルのいずれも、制約を個別に作成する場合より高速になります。

機能強化#

LaTeX 出力の改善#

畳み込みや genarray を使った場合の表示を改善しました。たとえば、以下のような axis 指定総和の TSP 問題の表記が改善されました:

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} \]

また、以下のような genarray 等に対する添え字も簡約して表示されるようになりました:

@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} \]

エージェントがスキルを発見しやすく#

README や API Reference、パッケージのメタデータ、モジュール内ドキュメントなどにスキルの取得方法を明記することで、コーディングエージェントがスキルを発見しやすくなりました。 これにより、コーディングエージェントがより自然な JijModeling コードを書きやすくなりました。