jijmodeling

The JijModeling library. See official documentation for details.

Module Contents

Classes

Name

Description

CategoryLabel

A category label corresponds to a set of labels representing some specific category (e.g. the name o…

CompileError

Compiler

A compiler that converts problems/expressions into OMMX instance/functions.

Constraint

A constraint in the mathematical optimization model.

ConstraintDetectionConfig

Configuration for automatic constraint hint detection during problem compilation.

ConstraintHintName

Name of constraint hits. To be used in ConstraintDetectionConfig.constraint_hints.

ConstraintSense

Classification of a constraint based on the comparison used.

DataType

The type of values in the instance data.

DecisionVar

A decision variable in a mathematical model.

DecisionVarKind

The type of values a decision variable may have.

DecoratedProblem

A variant of Problem that is only available in Decorator API provided by Problem.update.

DependentVar

A dependent variable in a mathematical model.

DesugaredProblemBuilder

Expression

An expression used to compose mathematical models.

ModelingError

Namespace

Placeholder

A placeholder for instance-specific parameters.

Problem

A class for creating an optimization problem.

ProblemSense

An optimization sense

ProtobufError

Type

TypeError

Functions

Name

Description

abs

Returns an expression representing the absolute value of the given expression.

acos

Returns an expression representing the arccosine of the given expression.

acosh

Returns an expression representing the hyperbolic arccosine of the given expression.

asin

Returns an expression representing the arcsine of the given expression.

asinh

Returns an expression representing the hyperbolic arcsine of the given expression.

atan

Returns an expression representing the arctangent of the given expression.

atanh

Returns an expression representing the hyperbolic arctangent of the given expression.

band

bnot

bor

ceil

Returns an expression which rounds down to the nearest whole number.

cos

Returns an expression representing the cosine of the given expression.

cosh

Returns an expression representing the hyperbolic cosine of the given expression.

count

Get the count/size of a category label.

diff

enumerate

Enumerate elements of a set-like collection with 0-based indices.

exp

Returns an expression representing the application of the exponential function on the given expressi…

filter

Creates an expression that filters the values of another sequence expression.

flat_map

Creates an expression which works like {py:func}jijmodeling.map, but flattens nested structure.

floor

from_protobuf

Deserializes a sequence of bytes as protobuf message encoding a {py:class}~jijmodeling.Problem.

indices

Get the set of indices of given array or jagged array.

is_same

Return true if src and dst are the same object defined by Jijmodeling.

items

Returns an expression representing the (key,value) pairs of a

keys

Returns an expression representing the keys of a dictionary-like

ln

Returns an expression representing the natural logarithm of the given expression.

log10

Returns an expression representing the decimal logarithm of the given expression.

log2

Returns an expression representing the binary logarithm of the given expression.

map

Creates an expression that maps func to a sequence of values.

max

Creates an expression that refers to the largest value among lhs and rhs.

min

Creates an expression that refers to the smallest value among lhs and rhs.

ndenumerate

Enumerate elements of a tensor or jagged array with multi-dimensional indices.

neg

prod

Comprehension syntax for {py:func}jijmodeling.prod, for use with decorated API.

product

Returns an expression representing the cartesian product of two {py:class}~jijmodeling.Expressions.

roll

rows

Creates a sequence over the rows of a multi-dimensional array expression.

set

sin

Returns an expression representing the sine of the given expression.

sinh

Returns an expression representing the hyperbolic sine of the given expression.

sqrt

Returns an expression representing the square root of the given expression.

sum

Comprehension syntax for {py:func}jijmodeling.sum for use with decorated API.

tan

Returns an expression representing the tangent of the given expression.

tanh

Returns an expression representing the hyperbolic tangent of the given expression.

to_protobuf

Serializes a {py:class}~jijmodeling.Problem into a protobuf byte message

unique

Remove duplicate elements from a set, preserving the order of first occurrences.

values

Returns an expression representing the values of a dictionary-like

xor

Type Aliases

Name

Description

ExpressionFunction

Any function that takes one or more Expressions as input and returns an Expression.

ExpressionLike

Any type that can be converted to an Expression, including:

Functions

abs(expr: ExpressionLike) Expression

Returns an expression representing the absolute value of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acos(expr: ExpressionLike) Expression

Returns an expression representing the arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acosh(expr: ExpressionLike) Expression

Returns an expression representing the hyperbolic arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asin(expr: ExpressionLike) Expression

Returns an expression representing the arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asinh(expr: ExpressionLike) Expression

Returns an expression representing the hyperbolic arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atan(expr: ExpressionLike) Expression

Returns an expression representing the arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atanh(expr: ExpressionLike) Expression

Returns an expression representing the hyperbolic arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

band(lhs: ExpressionLike, rhs: ExpressionLike) Expression
bnot(expr: ExpressionLike) Expression
bor(lhs: ExpressionLike, rhs: ExpressionLike) Expression
ceil(expr: ExpressionLike) Expression

Returns an expression which rounds down to the nearest whole number.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cos(expr: ExpressionLike) Expression

Returns an expression representing the cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cosh(expr: ExpressionLike) Expression

Returns an expression representing the hyperbolic cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

count(category_label: CategoryLabel) Expression

Get the count/size of a category label.

This function returns an expression that evaluates to the number of labels in the given category.

Arguments

  • category_label - The category label to count

Returns

An expression representing the count of the category label.

diff(lhs: ExpressionLike, rhs: ExpressionLike) Expression
enumerate(operand: ExpressionLike) Expression

Enumerate elements of a set-like collection with 0-based indices.

Returns a set of (index, element) tuples, similar to Python’s built-in enumerate() function.

Parameters: operand : Expression A set-like expression to enumerate.

Returns: Expression A set expression where each element is a tuple of (index, original_element).

exp(expr: ExpressionLike) Expression

Returns an expression representing the application of the exponential function on the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

filter(predicate: ExpressionFunction, operand: ExpressionLike) Expression

Creates an expression that filters the values of another sequence expression.

predicate will be called on each element in operand. The resulting expression represents only the values for which predicate is true.

This parallels python’s built-in filter() function, but made to work with JijModeling sequence expressions.

This is often useful when trying to create summations which only include a subset of potential indices. The resulting expression is usually used as the basis for jijmodeling.map(), jijmodeling.sum(), etc., or a method equivalent.

See also the method equivalents: Placeholder.filter, DecisionVar.filter and Expression.filter.

Examples

Using only variables with even indices as part of a constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> even_xs = jm.filter(lambda i: i % 2 == 0, N).map(lambda i: x[i])
>>> problem += problem.Constraint("constr", even_xs.sum() < 10)

Using only non-diagonal indices of an NxN matrix as part of a constraint, using the method version of filter.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> non_diagonals = jm.product(N, N).filter(lambda i, j: i != j)
>>> problem += problem.Constraint("constr", lambda i, j: W[i, j] * x[i, j] <= 100, domain=non_diagonals)
flat_map(func: ExpressionFunction, arg: ExpressionLike) Expression

Creates an expression which works like jijmodeling.map(), but flattens nested structure.

map is useful when func returns scalar values, but in some situations one wants to write a func that returns other mappings/sequences instead. That is where flat_map should be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced with jijmodeling.sum(), etc.)

You can also compare flat_map to a nested for-loop, or a generator expression that uses two for clauses. Indeed when using the decorated API (see tutorials or Problem.update()), you can use a generator expression-like syntax instead.

See also the method equivalents: Placeholder.flat_map(), DecisionVar.flat_map() and Expression.flat_map(). Using the methods often leads to code that is easier to read. Note that the method is not available for number literals.

Examples

Using only non-diagonal indices of an NxN matrix.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> objective = jm.flat_map(
...    lambda i: N.filter(lambda j: i != j).map(lambda j: W[i, j] * x[i, j]), N
... ).sum()
>>> problem += objective
floor(expr: ExpressionLike) Expression
from_protobuf(buf: bytes) Problem

Deserializes a sequence of bytes as protobuf message encoding a Problem.

indices(array: ExpressionLike) Expression

Get the set of indices of given array or jagged array.

Will throw type error when called on non-array type.

is_same(src: Any, dst: Any) bool

Return true if src and dst are the same object defined by Jijmodeling.

Args:

  • src: An object defined by Jijmodeling module, or an iterable of Jijmodeling objects.

  • dst: An object defined by Jijmodeling module, or an iterable of Jijmodeling objects.

Returns: bool: true if src and dst is the same object. Otherwise false.

Examples: Check if the two placeholders are the same.

>>> import jijmodeling as jm
>>> problem = jm.Problem("problem")
>>> a = problem.Placeholder("name")
>>> b = problem.Placeholder("name")
>>> assert jm.is_same(a, b)
>>> c = problem.Placeholder("name", ndim=2)
>>> assert not jm.is_same(a, c) # the value of `ndim` is different

Raises: TypeError: Raises if

  • src and dst are of different types which are not iterable

  • called on a type not defined by Jijmodeling (e.g. str)

Note: This function does not check the following attributes:

  • description

  • latex

For example,

>>> import jijmodeling as jm
>>> problem = jm.Problem("problem")
>>> src = problem.Placeholder("placeholder", latex="src")
>>> dst = problem.Placeholder("placeholder", latex="dst")
>>> assert jm.is_same(src, dst)

this code works without any exception.

items(dictionary: ExpressionLike) Expression

Returns an expression representing the (key,value) pairs of a dictionary-like Expression.

In other words, this is the JijModeling equivalent of the items() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Placeholder.items(), DecisionVar.items(), and Expression.items() to achieve this with methods, which are recommended for clarity.

If you want to refer to the keys used in the dictionary, use jijmodeling.keys() or its method equivalents. If you want the dictionary’s values, use jijmodeling.values() or its method equivalents instead.

keys(dictionary: ExpressionLike) Expression

Returns an expression representing the keys of a dictionary-like Expression.

In other words, this is the JijModeling equivalent of the keys() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Placeholder.keys(), DecisionVar.keys(), and Expression.keys() to achieve this with methods, which is recommended for clarity.

If you want to refer to the dictionary’s values, use jijmodeling.values() or its method equivalents. If you want key-value pairs, use jijmodeling.items() or its method equivalents instead.

ln(expr: ExpressionLike) Expression

Returns an expression representing the natural logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log10(expr: ExpressionLike) Expression

Returns an expression representing the decimal logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log2(expr: ExpressionLike) Expression

Returns an expression representing the binary logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

map(func: ExpressionFunction, arg: ExpressionLike) Expression

Creates an expression that maps func to a sequence of values.

This parallels python’s built-in map() function, but made to work with and create JijModeling expressions.

If arg is a number literal or scalar placeholder, each number from 0 to arg will be passed to func. If arg is a sequence expression (eg. a 1-dimensional placeholder, or the result of functions like jijmodeling.product() or jijmodeling.items()), each element in the sequence is passed to func.

This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like Placeholders and DecisionVars. The resulting expression is then usually passed to a reducer, like jijmodeling.sum() (or Expression.sum() is called on it), to form part of a constraint or the objective function.

See also the method equivalents: Placeholder.map(), DecisionVar.map() and Expression.map(). Using the methods often leads to code that is easier to read. Note that the method is not available for number literals.

Examples

Indexing by values from 0 to N. In this example we define N as the length of another placeholder, but a scalar Natural placeholder would work as well.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += jm.sum(jm.map(lambda i: W[i] * x[i], N))
>>> # or, same as above
>>> problem += jm.map(lambda i: W[i] * x[i], N).sum()
>>> # same as above but using method on N instead of this function:
>>> problem += N.map(lambda i: W[i] * x[i]).sum()

Indexing by specific values from instance data. In this example only the indices present in C in the instance data will be used in this constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> C = problem.Natural("C", ndim=1)
>>> problem += problem.Constraint("constr", jm.map(lambda i: x[i], C).sum() <= 100)

Accessing category label keys. Dictionary-like placeholders & decision-variables require keys from the appropriate CategoryLabel, which are accessed by mapping.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> W = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=I)
>>> problem += jm.sum(jm.map(lambda i: W[i] * x[i], I))

Or, using items() on a dictionary placeholder:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> W = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=I)
>>> problem += jm.map(lambda i, w: w * x[i], W.items())
max(operand: ExpressionLike) Expression
max(lhs: ExpressionLike, rhs: ExpressionLike) Expression

Creates an expression that refers to the largest value among lhs and rhs.

See also the method equivalents Placeholder.max(), DecisionVar.max(), and Expression.max().

min(operand: ExpressionLike) Expression
min(lhs: ExpressionLike, rhs: ExpressionLike) Expression

Creates an expression that refers to the smallest value among lhs and rhs.

See also the method equivalents Placeholder.min(), DecisionVar.min(), and Expression.min().

ndenumerate(operand: ExpressionLike) Expression

Enumerate elements of a tensor or jagged array with multi-dimensional indices.

This is similar to enumerate(), but for multi-dimensional arrays (tensors and jagged arrays). Each element is paired with its multi-dimensional index as a tuple of natural numbers.

Parameters: operand : Expression A tensor or jagged array expression to enumerate.

Returns: Expression An array expression where each element is a tuple of (index_tuple, original_element), where index_tuple is a tuple of natural numbers representing the multi-dimensional position.

neg(expr: ExpressionLike) Expression
prod(x: Generator[ExpressionLike, None, None]) Expression
prod(index: ExpressionLike, operand: ExpressionFunction) Expression
prod(operand: ExpressionLike, axis: Optional[ExpressionLike] = None) Expression

Comprehension syntax for jijmodeling.prod(), for use with decorated API.

When using the decorated API, you are allowed to use a comprehension/generator expression directly inside prod, using for clauses to mark the index.

NOTE: do not confuse with jijmodeling.product(). This is a sequence multiplication (like capital-PI notation). product is the cartesian product.

NOTE: this variant only works with decorated API!

See Problem.update() or the cheatsheet for more information on the decorated API.

Examples

>>> problem = jm.Problem("MyProblem", sense=jm.ProblemSense.MINIMIZE)
>>> @problem.update
>>> def _(problem: jm.DecoratedProblem):
...   N = problem.Placeholder(dtype=jm.DataType.NATURAL)
...   x = problem.BinaryVar(shape=N)
...   C = problem.Placeholder(ndim=1, dtype=np.uint64)
...   problem += jm.prod(x[i] for i in C)
>>>
product(sets: Any) Expression

Returns an expression representing the cartesian product of two Expressions.

For example product(10,10) represents all pairs (0,0),(0,1),...,(1,0),(1,1),...,(10, 10). This can then be map()ped to access these pairs of values, or filter()ed to remove unwanted values.

Do not confuse with prod(), which represents the multiplication of a sequence of values.

roll(operand: ExpressionLike, shift: Any, axis: Optional[int] = None) Expression
rows(array: ExpressionLike) Expression

Creates a sequence over the rows of a multi-dimensional array expression.

That is, each element will be a whole row (itself containing multiple values), which can then be operated on like other sequences (eg. using sum() or map()).

If the array is 3-dimensional or higher, rows will iterate over the first dimension/axis. For example, in a 3D matrix, the first element would be a 2D matrix representing all values x[0, _, _]

See also the method equivalents: Placeholder.rows(), DecisionVar.rows() and Expression.rows(). Using the methods often leads to code that is easier to read.

Examples

Create an objective function that multiplies each variable in a row, and then sums each row. In this case we have a 2x3 matrix, so the final expression is x[0, 0] * x[0, 1] * x[0, 2] + x[1, 0] * x[1, 1] * x[1, 2]. Using placeholders instead of literals in shape would allow this to be written for matrices of arbitrary size.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> d = problem.BinaryVar("d", shape=(2, 3))
>>> problem += jm.rows(d).map(lambda xs: xs.prod()).sum()

If the number of elements in the row can be guaranteed, the elements can be destructured as separate arguments in a lambda expression:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> V = problem.Natural("V")
>>> E = problem.Natural("E", shape=(N, 2))
>>> x = problem.BinaryVar("x", shape=V)
>>> problem += jm.map(lambda i, j: x[i] * x[j], jm.rows(E)).sum()
set(operand: ExpressionLike) Expression
sin(expr: ExpressionLike) Expression

Returns an expression representing the sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sinh(expr: ExpressionLike) Expression

Returns an expression representing the hyperbolic sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sqrt(expr: ExpressionLike) Expression

Returns an expression representing the square root of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sum(x: Generator[ExpressionLike, None, None]) Expression
sum(index: ExpressionLike, operand: ExpressionFunction) Expression
sum(operand: ExpressionLike, axis: Optional[ExpressionLike] = None) Expression

Comprehension syntax for jijmodeling.sum() for use with decorated API.

When using the decorated API, you are allowed to use a comprehension/generator expression directly inside sum, using for clauses to mark the index.

NOTE: only works with decorated API!

See Problem.update() or the cheatsheet for more information on the decorated API.

Examples

>>> problem = jm.Problem("MyProblem", sense=jm.ProblemSense.MINIMIZE)
>>> @problem.update
>>> def _(problem: jm.DecoratedProblem):
...   N = problem.Placeholder(dtype=jm.DataType.NATURAL)
...   x = problem.BinaryVar(shape=N)
...   C = problem.Placeholder(ndim=1, dtype=np.uint64)
...   problem += jm.sum(x[i] for i in C)
>>>
tan(expr: ExpressionLike) Expression

Returns an expression representing the tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

tanh(expr: ExpressionLike) Expression

Returns an expression representing the hyperbolic tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

to_protobuf(problem: Problem) bytes

Serializes a Problem into a protobuf byte message

unique(operand: ExpressionLike) Expression

Remove duplicate elements from a set, preserving the order of first occurrences.

This operation takes a set and returns a new set containing only unique elements. If the same element appears multiple times, only the first occurrence is kept.

Parameters: operand : Expression A set expression from which to remove duplicates.

Returns: Expression A set expression containing only unique elements from the input.

values(dictionary: ExpressionLike) Expression

Returns an expression representing the values of a dictionary-like Expression.

In other words, this is the JijModeling equivalent of the values() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Placeholder.values(), DecisionVar.values(), and Expression.values() to achieve this with methods, which is recommended for clarity.

If you want to refer to the keys used in the dictionary, use jijmodeling.keys() or its method equivalents. If you want key-value pairs, use jijmodeling.items() or its method equivalents instead.

xor(lhs: ExpressionLike, rhs: ExpressionLike) Expression

Classes

class CategoryLabel

A category label corresponds to a set of labels representing some specific category (e.g. the name of percels, or the ids of factors, etc). A value of category label is treated opaque in JijModeling, and can only be tested for equality / non-equality and used as keys in dictionary-like structures.

CategoryLabel objects can be created via Problem.CategoryLabel(). The concrete values should be given in instance_data dictionary together with placeholder values when creating a Compiler object or in eval(). In instance_data, category label should be given a list of either strings or integers.

__and__(rhs: ExpressionLike) Expression
__eq__(other: Any) Expression
__ge__(other: Any) Expression
__gt__(other: Any) Expression
__iter__() CategoryLabel

A dummy implementation to make CategoryLabel usable in comprehension syntax with Decorator API. Do not call this directly.

__le__(other: Any) Expression
__lt__(other: Any) Expression
__ne__(other: Any) Expression
__next__() Expression

A dummy implementation to make CategoryLabel usable in comprehension syntax with Decorator API. Do not call this directly.

__or__(rhs: ExpressionLike) Expression
__rand__(lhs: ExpressionLike) Expression
__ror__(lhs: ExpressionLike) Expression
__rxor__(lhs: ExpressionLike) Expression
__xor__(rhs: ExpressionLike) Expression
bnot() Expression
count() Expression

Get the count/size of this category label as an expression. Returns an expression that evaluates to the number of labels in this category.

custom_latex() Optional[str]
description() Optional[str]
diff(rhs: ExpressionLike) Expression
filter(func: ExpressionFunction) Expression
flat_map(func: ExpressionFunction) Expression
map(func: ExpressionFunction) Expression
name() str
class CompileError
class Compiler

A compiler that converts problems/expressions into OMMX instance/functions.

Compiler objects can be created via constructor of Compiler.from_problem() class method. In this section we explain the usage of Compiler constructor.

Args:

  • namespace (Namespace): The namespace containing decision variables and other symbols used in the problem. (Typically obtained via Problem.namespace.)

  • instance_data (dict[str, typing.Any]): A dictionary mapping names of placeholders and category labels to their concrete values for instance generation.

Instance Data: For placeholders, you can pass any of the following:

  1. a scalar (integer or floating number point) value,

  2. a tuple of scalars,

  3. a (nested) list of (1) or (2).

  4. a ndarray.array object from numpy package with dtype float or int.

For category labels, you can pass a list of strings or integers representing the concrete labels.

Returns: A Compiler object.

Raises: Raises ModelingError when there is missing or redundant placeholder(s) or category label(s) in instance_data.

__new__(namespace: Namespace, instance_data: str | int | float | NDArray[numpy.float64] | NDArray[numpy.int64] | list | dict | str) Compiler
eval_constraints(constraint: Constraint) list[Constraint]
eval_function(expr: ExpressionLike) Function
eval_problem(problem: Problem, prune_unused_dec_vars: bool = False, constraint_detection: ConstraintDetectionConfig | bool = None) Instance

Compiles a JijModeling Problem into an OMMX Instance.

Args:

  • problem (Problem): The JijModeling Problem to be compiled. The problem can be different from the on passed to Compiler.from_problem(), but the namespaces must be compatible.

  • prune_unused_dec_vars (bool, optional): If True, only include decision variables that appear in the objective or constraints. If False (default), include all declared decision variables regardless of usage.

  • constraint_detection (Optional[ConstraintDetectionConfig]): Configuration for automatic constraint hint detection. If None, the default configuration is used. Pass false or ConstraintDetectionConfig.disable() to disable constraint hint detection. See ConstraintDetectionConfig for details.

from_problem(problem: Problem, instance_data: str | int | float | NDArray[numpy.float64] | NDArray[numpy.int64] | list | dict | str) Compiler

Creates a Compiler object from a Problem object and instance data.

See Compiler constructor for details about instance_data.

get_constraint_id_by_name(name: str) dict

Obtains a dictionary from subscript to constraint Id.

get_decision_variable_by_name(name: str, subscript: int | str | CategoryLabel = None) DecisionVariable

Retrieves an OMMX decision variable by its name and optional subscript.

class Constraint

A constraint in the mathematical optimization model.

Constraints represent restrictions on the valid values for decision variables in the mathematical model. Constraints wrap around a valid comparison expression (using ==, <= or >=), often featuring decision variables on one side.

In JijModeling, Constraints exist within a Problem’s namespace, and cannot be defined outside of a problem. So to define a constraint, you must use Problem.Constraint() on a Problem instance.

Created Constraints must then be explicitly added to a problem using the += operator, for example:

>>> import jijmodeling as jm
>>> problem = jm.Problem("problem")
>>> x = problem.BinaryVar("x", shape=(10,))
>>> problem += problem.Constraint("constr", x.sum() == 1)
>>> problem
Problem(name="problem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=EQUAL, left=sum(x), right=1, shape=Scalar(Binary)),],})

__repr__() str
_repr_latex_() str
class ConstraintDetectionConfig

Configuration for automatic constraint hint detection during problem compilation. Use ConstraintDetectionConfig.disable() to disable automatic constraint hint detection.

Args:

  • constraint_hints (list[ConstraintHintName]): A list of constraint hints to be detected. See ConstraintHintName for available hints.

  • max_iter (Optional[int]): Maximum number of iterations for constraint hint detection. If None, it tries to iterate until fixpoint. Default: 10

  • max_hints (Optional[int]): Maximum number of hints to be detected. If None, there is no limit. Default: None

  • match_limit (int): Fine-tuning parameter to control simplification during constraint hint detection: the limit of the number of a single rule before the banning. If None, the default value is used. Default: 1000.

  • ban_length (int): Fine-tuning parameter to control simplification during constraint hint detection: how many simplification iterations to prevent banned rules to be fired. If None, the default value is used. Default: 5.

__new__(max_iter: Optional[int] = 10, max_hints: Optional[int] = None, constraint_hints: Optional[Sequence[ConstraintHintName]] = None, match_limit: Optional[int] = None, ban_length: Optional[int] = None) ConstraintDetectionConfig
ban_length() int

Fine-tuning parameter to control simplification during constraint hint detection: how many simplification iterations to prevent banned rules to be fired. If None, the default value is used. Default: 5.

constraint_hints() list[ConstraintHintName]

A list of constraint hints to be detected. See ConstraintHintName for available hints. Default is ConstraintDetectionConfig.default_hints().

default_hints() list[ConstraintHintName]

A default list of constraint hints to be detected.

disable() ConstraintDetectionConfig

Disables automatic constraint hint detection.

disabled() bool

If True, automatic constraint hint detection is disabled, regardless of other paramters.

match_limit() int

Fine-tuning parameter to control simplification during constraint hint detection: the limit of the number of a single rule before the banning. If None, the default value is used. Default: 1000.

max_hints() Optional[int]

Maximum number of hints to be detected. If None, there is no limit. Default: None

max_iter() Optional[int]

Maximum number of iterations for constraint hint detection. If None, it tries to iterate until fixpoint. Default: 5

class ConstraintHintName

Name of constraint hits. To be used in ConstraintDetectionConfig.constraint_hints.

OneHot

One-hot constraint, or simplicial constraint. A one-hot constraint on binary variables x_1, x_2, …, x_n requires that exactly one of the variables is set to 1, and the others are set to 0. This can be expressed as x1++xn=1x_1 + \dots + x_n = 1 .

Sos1
class ConstraintSense

Classification of a constraint based on the comparison used.

Constraints can be

  • lhs == rhs Equalities: ConstraintSense.EQUAL

  • lhs <= rhs Inequalities: ConstraintSense.LESS_THAN_EQUAL

  • lhs >= rhs Inequalities: ConstraintSense.GREATER_THAN_EQUAL

EQUAL
GREATER_THAN_EQUAL
LESS_THAN_EQUAL
class DataType

The type of values in the instance data.

Used to specify the types of values Placeholder will be able to hold. This type is used for type checking and error detection, particularly when compiling models into ommx instances – not allowing data of the wrong kind to be used in a given placeholder. This is also used when trying to generate random instances from a model.

Placeholders may also have tuples of DataTypes as their types, eg. (DataType.NATURAL, DataType.NATURAL) for representing edges in a graph.

BINARY
FLOAT
INTEGER
NATURAL
class DecisionVar

A decision variable in a mathematical model.

Decision variables are fundamental parts of mathematical optimization, representing the values the solver can change to attempt to optimize the objective function. As such, they will likely show up in Expressions throughout your model. DecisionVar should generally work where Expression is expected and operations will automatically convert as needed.

Decision variables must belong to some namespace, ie. a Problem, so you CANNOT construct one directly. Use Problem.DecisionVar() or shorthand methods (eg. Problem.BinaryVar(), Problem.IntegerVar(), etc.) to define decision variables.

Decision variables can be defined and used as scalars (unit variables), n-dimensional arrays, or as dictionaries. In the latter two cases, a single DecisionVariable object represents multiple variables in the model, and requires subscripting to access individual variables. This is similar to how in a mathematical formula you may call a whole set of variables xx made up of x0,x1,...x_0, x_1, .... More details on these is provided in later sections.

Upper and lower bounds.

Decision variables must have well-defined upper and lower bounds. These can be specified through any valid expression but CANNOT contain decision variables. What counts as a valid expression depends the decision variable but should be intuitive.

For all types of decision variable, a number literal, scalar Placeholders, or expressions that evaluate to scalars can be used as bounds. When this is used with array or dictionary variables, this sets the same bounds for all variables the object represents.

For array variables, you can set the bounds separately for each individual variable by passing in a matching array expression (eg. an array of numbers or an array placeholder). The shape of the decision variable and the bound expression must match (eg. a 2x2 decision variable likewise requires a 2x2 matrix of bounds) and otherwise will cause errors. Due to how placeholders may have vaguely-defined shapes, some errors may only happen when evaluating the model with actual data.

For dictionary variables, you can set the bounds separately by passing in a matching dictionary placeholder. The keys of the placeholder must matcha the decision variable, and so partial dictionaries cannot be used.

For both array and dictionary variables, you can also set each bound separately by passing a function (usually a lambda). When evaluating your problem, each valid index for that variable (be it a natural number or a key from the appropriate category label) will be passed to the function, and the returned value must be a scalar that will be used as that variable’s bound.

Using functions to set bounds is considered a more niche operation you will often not need, but it can be useful when there is some operation on the instance data you want to use to define the bounds (eg. the upper bound is lower bound + 10); or when you want to do some index manipulation (eg. setting the bound to an inverse matrix by doing lambda i,j: V[j,i]).

Binary decision variables should have upper and lower bounds defined as 1 and 0 and using other bounds will lead to an error when evaluating your model into an OMMX instance. The Problem.BinaryVar() method sets the correct bounds automatically.

Array decision variables and shape

You can define DecisionVars as n-dimensional arrays (aka. matrix, tensors, etc.) of decision variables. While some operations can work on arrays directly, in general this means you’ll have to use subscripts (ie. indexing with []) to get individual decision variables when writing expressions.

Array variables are defined by specifying a shape in the constructor method. Shapes are tuples or lists of expressions, where each entry specifies the number of decision variables in a given dimension. For example:

  • a 10 shape represents a 1-dimensional array with 10 variables. (Defining the shape as (10,) would be equivalent)

  • a (2, 2) shape represents a 2-dimensional array with 2 variables in each dimension (a 2x2 matrix)

Scalar variables have a shape of () (an empty tuple), which is also the default value of shape when none is specified.

Unlike Placeholder, decision variables must have a defined shape. You cannot simply specify “2-dimensional”, for example. As an alternative you can define the shape using scalar placeholders or the length of placeholders, allowing you to still define decision variable arrays with size parametrized on the instance data.

Dictionary decision variables

As an alternative to the array-like interface, decision variables can also be used in a style closer to python dictionaries: an unordered collection indexed by a set of labels. This is recommended mostly when you’re focused on string-based labels or want non-contiguous indices.

To use variables this way, you must first define a set of labels through Problem.CategoryLabel()s. This is a special kind of placeholder which will represent the keys to dictionaries, and can be reused throughout your model (eg. to define matching dictionary-like Placeholders).

This CategoryLabel instance is then passed to the dict_keys parameter in the appropriate constructor (Problem.DecisionVar(), etc.). Tuples of category labels can be passed to define dictionaries which use multiple keys.

The array and dictionary representations are mutually exclusive, and you cannot set both shape and dict_keys together. Doing so will lead to an exception.

Unlike Placeholders, decision variables can only be used as total dictionaries over the entire category domain. You cannot define them as partial dictionaries, and there is no partial_dict parameter.

Attributes:

  • name (str): A name of the continuous variable.

  • kind (DecisionVarKind): The kind of the decision variable, which can be one of the following:

    • BINARY: A binary variable.

    • INTEGER: An integer variable.

    • CONTINUOUS: A continuous variable.

    • SEMI_INTEGER: A semi-integer variable.

    • SEMI_CONTINUOUS: A semi-continuous variable.

  • shape (tuple): A tuple with the size of each dimension of the integer variable. Empty if the variable is not multi-dimensional.

  • lower_bound: The lower bound of the variable.

  • upper_bound: The upper bound of the variable.

  • description (str): A description of the continuous variable.

Examples: Create a scalar continuous variable whose name is “z” and is bounded to [-1, 1].

>>> import jijmodeling as jm
>>> problem = jm.Problem("example")
>>> z = problem.DecisionVar(
...     "z",
...     kind=jm.DecisionVarKind.CONTINUOUS,
...     lower_bound=-1, upper_bound=1
... )

or equivalently:

```python
>>> import jijmodeling as jm
>>> problem = jm.Problem("example")
>>> z = problem.ContinuousVar("z", lower_bound=-1, upper_bound=1)
>>> z
DecisionVariable(name="z", kind=CONTINUOUS, shape=, lower_bound=-1, upper_bound=1, )

Create a 2-dimensional integer variable...
- whose name is "x".
- whose domain is [0, 2].
- where each dimension has length 2 (making this a 2x2 matrix).

```python
>>> import jijmodeling as jm
>>> problem = jm.Problem("example")
>>> x = problem.IntegerVar("x", shape=[2, 2], lower_bound=0, upper_bound=2)
>>> x
DecisionVariable(name="x", kind=INTEGER, shape=2, 2, lower_bound=0, upper_bound=2, )

Create a 1-dimensional continuous variable, and construct an expression
accessing the 123rd component of it..

```python
>>> import jijmodeling as jm
>>> problem = jm.Problem("example")
>>> x = problem.ContinuousVar("x", shape=[124], lower_bound=0, upper_bound=2)
>>> x[123]
Expression(x[123])
__add__(rhs: ExpressionLike) Expression
__eq__(other: Any) Expression
__ge__(other: Any) Expression
__getitem__(subscripts: Any) Expression
__gt__(other: Any) Expression
__iter__() Any
__le__(other: Any) Expression
__lt__(other: Any) Expression
__mod__(rhs: ExpressionLike) Expression
__mul__(rhs: ExpressionLike) Expression
__ne__(other: Any) Expression
__neg__() Expression
__pow__(exponent: Any, modulo: Optional[Any] = None) Expression
__radd__(lhs: ExpressionLike) Expression
__repr__() str
__rmod__(lhs: ExpressionLike) Expression
__rmul__(lhs: ExpressionLike) Expression
__rpow__(base: Any, modulo: Optional[Any] = None) Expression
__rsub__(lhs: ExpressionLike) Expression
__rtruediv__(lhs: ExpressionLike) Expression
__sub__(rhs: ExpressionLike) Expression
__truediv__(rhs: ExpressionLike) Expression
_repr_latex_() str
abs() Expression

Returns an expression representing the absolute value of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acos() Expression

Returns an expression representing the arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acosh() Expression

Returns an expression representing the hyperbolic arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asin() Expression

Returns an expression representing the arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asinh() Expression

Returns an expression representing the hyperbolic arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atan() Expression

Returns an expression representing the arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atanh() Expression

Returns an expression representing the hyperbolic arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

ceil() Expression

Returns an expression which rounds down to the nearest whole number.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cos() Expression

Returns an expression representing the cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cosh() Expression

Returns an expression representing the hyperbolic cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

enumerate() Expression

Enumerate elements of a set-like collection with 0-based indices.

Returns a set of (index, element) tuples, similar to Python’s built-in enumerate() function.

Parameters: operand : Expression A set-like expression to enumerate.

Returns: Expression A set expression where each element is a tuple of (index, original_element).

exp() Expression

Returns an expression representing the application of the exponential function on the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

filter(predicate: ExpressionFunction) Expression

Creates an expression that filters the values of this sequence.

predicate will be called on each element in self. The resulting expression represents only the values for which predicate is true.

This is an alternative to jijmodeling.filter() which allows you to place the indexing expression first.

This is often useful when trying to create summations which only include a subset of potential indices.The resulting expression is usually used as the basis for jijmodeling.map(), jijmodeling.sum(), etc., or a method equivalent.

Examples:

Using only variables with even indices as part of a constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> even_xs = N.filter(lambda i: i % 2 == 0).map(lambda i: x[i])
>>> problem += problem.Constraint("constr", even_xs.sum() <= 10)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=LESS_THAN_EQUAL, left=sum(N.filter(lambda i: i % 2 == 0).map(lambda (i: natural): x[i])), right=10, shape=Scalar(Natural)),],})

Using only non-diagonal indices of an NxN matrix as part of a constraint, using the method version of filter.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> non_diagonals = jm.product(N, N).filter(lambda i, j: i != j)
>>> problem += problem.Constraint("constr", lambda i, j: W[i, j] * x[i, j] >= 0, domain=non_diagonals)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", , lambda (i, j): W[i, j] * x[i, j] >= 0, domain=set((N, N)).filter(lambda (i, j): i != j)),],})

flat_map(func: ExpressionFunction) Expression

Creates an expression which works like map(), but flattens nested structure.

This is an alternative to flat_map() which allows you to place the indexing expression first.

map is useful when func returns scalar values, but in some situations one wants to write a func that returns other mappings/sequences instead. That is where flat_map should be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced with sum(), etc.)

You can also compare flat_map to a nested for-loop, or a generator expression that uses two for clauses. Indeed when using the decorated API (see tutorials or @Problem.update), you can use a generator expression-like syntax instead.

Examples:

Using only non-diagonal indices of an NxN matrix.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> objective = N.flat_map(
...    lambda i: N.filter(lambda j: i != j).map(lambda j: W[i, j] * x[i, j])
... ).sum()
>>> problem += objective
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(N.flat_map(lambda (i: natural): N.filter(lambda j: i != j).map(lambda (j: natural): W[i, j] * x[i, j]))), constraints=[])

floor() Expression
indices() Expression

Get the set of indices of given array or jagged array.

Will throw type error when called on non-array type.

items() Expression

Returns an expression representing this object’s (key,value) pairs.

In other words, this is the JijModeling equivalent of the items() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.keys() and Expression.values().

Examples: Simple matching of weights to their respective variables, as an alternative to just using keys() or the CategoryLabel:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> weights = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=I)
>>> problem += jm.sum(weights.items(), lambda i, w: w * x[i])
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.items().map(lambda ((i, w): Tuple[CategoryLabel("I"), float]): w * x[i])), constraints=[])

Same as above, but using the decorated API:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> @problem.update
... def _(problem):
...     I = problem.CategoryLabel()
...     W = problem.Float(dict_keys=I)
...     x = problem.BinaryVar(dict_keys=I)
...     problem += jm.sum(w * x[i] for i, w in W.items())
>>> problem
Problem(name="MyProblem", ...)

keys() Expression

Returns an expression representing this dictionary-like object’s keys.

In other words, this is the JijModeling equivalent of the keys() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.values() and Expression.items().

Examples: Refer to a dictionary-like placeholder’s keys when creating other objects or writing summations:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> W = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=W.keys())
>>> problem += jm.sum(W.keys(), lambda i: W[i] * x[i])
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.keys().map(lambda (i: CategoryLabel("I")): W[i] * x[i])), constraints=[])
ln() Expression

Returns an expression representing the natural logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log10() Expression

Returns an expression representing the decimal logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log2() Expression

Returns an expression representing the binary logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

map(func: ExpressionFunction) Expression

Creates an expression that maps the values in self to func.

This is an alternative to jijmodeling.map() which allows you to place the indexing expression first.

When called on valid scalar scalars, each number from 0 to this self will be passed to func. When called on a sequence expression (eg. a 1-dimensional placeholder, or the result of functions like jijmodeling.product() or jijmodeling.items()), each element in the sequence is passed to func.

This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like Placeholders and DecisionVars. The resulting expression is then usually passed to a reducer, like jijmodeling.sum() (or Expression.sum() is called on it), to form part of a constraint or the objective function.

Examples:

Indexing by values from 0 to N. In this example we define N as the length of another placeholder, but a scalar Natural placeholder would work as well.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += N.map(lambda i: W[i] * x[i]).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.len_at(0).map(lambda (i: natural): W[i] * x[i])), constraints=[])

Indexing by specific values from instance data. In this example only the indices present in C in the instance data will be used in this constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> C = problem.Natural("C", ndim=1)
>>> problem += problem.Constraint("constr", C.map(lambda i: x[i]).sum() <= 100)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=LESS_THAN_EQUAL, left=sum(C.map(lambda (i: natural): x[i])), right=100, shape=Scalar(Integer)),],})

max() Expression
max(rhs: ExpressionLike) Expression

Creates an expression which refers to the largest value in self.

This method works only on valid sequence expressions, where the resulting expression is a scalar representing the largest among all values in the sequence.

min() Expression
min(rhs: ExpressionLike) Expression

Creates an expression which refers to the smallest value in self.

This method works only on valid sequence expressions, where the resulting expression is a scalar representing the smallest among all values in the sequence.

ndenumerate() Expression

Enumerate elements of a tensor or jagged array with multi-dimensional indices.

Returns an array where each element is paired with its multi-dimensional index as a tuple of natural numbers.

Parameters: operand : Expression A tensor or jagged array expression to enumerate.

Returns: Expression An array expression where each element is a tuple of (index_tuple, original_element), where index_tuple is a tuple of natural numbers representing the multi-dimensional position.

prod(axis: ExpressionLike | int | Sequence[ExpressionLike] | Sequence[int] = None) Expression

Creates an expression representing the multiplication of self.

This is an alternative to using jijmodeling.prod(), where a method call on an expression may be more convenient/readable.

If self isn’t a valid sequence which can be multiplied, you will get an error when the resulting expression is added to a Problem and is type-checked.

The optional axis parameter allows you to specify axes of a multi-dimensional expression across which to perform the operation.

Examples:

Simple product of decision variables

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> problem += x.prod()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=prod(x), constraints=[])

roll(shift: Any, axis: Optional[int] = None) Expression
rows() Expression

Creates a sequence over the rows of this multi-dimensional array expression.

That is, each element will be a whole row (itself containing multiple values), which can then be operated on like other sequences (eg. using jijmodeling.sum() or jijmodeling.map()).

If the array is 3-dimensional or higher, rows will iterate over the first dimension/axis. For example, in a 3D matrix, the first element would be a 2D matrix representing all values x[0, _, _]

Examples

Create an objective function that multiplies each variable in a row, and then sums each row. In this case we have a 2x3 matrix, so the final expression is x[0, 0] * x[0, 1] * x[0, 2] + x[1, 0] * x[1, 1] * x[1, 2]. Using placeholders instead of literals in shape would allow this to be written for matrices of arbitrary size.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> d = problem.BinaryVar("d", shape=(2, 3))
>>> problem += d.rows().map(lambda xs: xs.prod()).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(d.rows().map(lambda (xs: Array[3; binary!]): prod(xs))), constraints=[])

If the number of elements in the row can be guaranteed, the elements can be destructured as separate arguments in a lambda expression:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> V = problem.Natural("V")
>>> E = problem.Natural("E", shape=(N, 2))
>>> x = problem.BinaryVar("x", shape=V)
>>> problem += jm.map(lambda i, j: x[i] * x[j], E.rows()).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(E.rows().map(lambda ((i, j): Array[2; natural]): x[i] * x[j])), constraints=[])

sin() Expression

Returns an expression representing the sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sinh() Expression

Returns an expression representing the hyperbolic sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sqrt() Expression

Returns an expression representing the square root of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sum(axis: ExpressionLike | int | Sequence[ExpressionLike] | Sequence[int] = None) Expression

Creates an expression representing the summation of self.

This is an alternative to using jijmodeling.sum(), where a method call on an expression may be more convenient/readable.

If self isn’t a valid sequence which can be summed, you will get an error when the resulting expression is added to a Problem and is type-checked.

The optional axis parameter allows you to specify axes of a multi-dimensional expression across which to perform the operation.

Examples:

Simple sum of decision variables.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> problem += x.sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(x), constraints=[])

Performing a weighted sum. Note that this sort of usage may lead to errors when the shapes don’t match. In this case we guarantee that x has the same shape as W through its definition.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += (W * x).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W * x), constraints=[])

tan() Expression

Returns an expression representing the tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

tanh() Expression

Returns an expression representing the hyperbolic tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

unique() Expression

Remove duplicate elements from this array-like expression, preserving order.

Returns: Expression A set expression with duplicates removed.

values() Expression

Returns an expression representing this dictionary-like object’s values.

In other words, this is the JijModeling equivalent of the values() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.keys() and Expression.items().

Examples: Defining a simple objective function which just sums a dictionary-based decision variable.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> x = problem.IntegerVar("x", dict_keys=I, lower_bound=0, upper_bound=100)
>>> problem += x.values().sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(x.values()), constraints=[])
class DecisionVarKind

The type of values a decision variable may have.

The larger domain, before being restricted by the upper and lower bounds

  • Binary variables may only be either 1 or 0. (other bounds will lead to errors).

  • Integer variables can only be discrete integers withing the upper/lower bound range.

  • Continuous variables can be any real number within the bounded range.

  • Semi-Integer and Semi-Continuous are like the above, but always accept “0” as a value. Support for these in tooling is limited.

BINARY
CONTINUOUS
INTEGER
SEMI_CONTINUOUS
SEMI_INTEGER
class DecoratedProblem

A variant of Problem that is only available in Decorator API provided by Problem.update. See Problem for more details.

Binary(name: Optional[str] = None, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a binary number in this problem’s namespace.

A shorthand for DecoratedProblem.Placeholder(dtype=DataType.BINARY), provided for clarity and convenience. See DecoratedProblem.Placeholder for more details on placeholders.

BinaryVar(name: Optional[str] = None, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines a binary decision variable and registers it to the problem namespace. See DecoratedProblem.DecisionVariable for more details.

A shorthand for DecoratedProblem.DecisionVariable(dtype=DecisionVarKind.BINARY, lower_bound=0, upper_bound=1), provided for clarity and convenience.

Args

  • name (str | None): A name for the binary variable. If omitted, local variable name is used.

  • shape (list | tuple): A sequence with the size of each dimension of the binary variable. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this variable represents a dictionary-like structure with keys dict_keys.

  • latex (str, optional): A LaTeX-name of the binary variable to be represented in Jupyter notebook.

    • It is set to name by default.

  • description (str, optional): A description of the binary variable.

CategoryLabel(name: Optional[str] = None, latex: Optional[str] = None, description: Optional[str] = None) CategoryLabel

Add a new opaque category label to the namespace.

A category label corresponds to a set of labels representing some specific category (e.g. the name of percels, or the ids of factors, etc). A value of category label is treated opaque in JijModeling, and can only be tested for equality / non-equality and used as keys in dictionary-like structures.

CategoryLabel objects can be created via Problem.CategoryLabel(). The concrete values should be given in instance_data dictionary together with placeholder values when creating a Compiler object or in Problem.eval(). In instance_data, category label should be given a list of either strings or integers.

Args

  • name (str | None): A name for the category label. If omitted, local variable name is used.

  • latex (str, optional): An optional LaTeX representation to be used in Jupyter notebook.

    • When not provided, name is used by default.

  • description (str, optional): An optional description for user reference.

Constraint(name: str, expression: ExpressionLike, description: Optional[str] = None) Constraint
Constraint(name: str, expressions: Generator[ExpressionLike, None, None], description: Optional[str] = None) Constraint
Constraint(name: str, expression: ExpressionFunction, domain: ExpressionLike, description: Optional[str] = None) Constraint

Constructs Constraint object from comparison expression, WITHOUT registering it to the problem. Use += operator to register the constraint to the problem.

ContinuousVar(name: Optional[str] = None, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines a continuous decision variable and registers it to the problem namespace. See Problem.DecisionVar for more details.

This is shorthand for problem.DecisionVariable(dtype=DecisionVarKind.CONTINUOUS).

Args

  • name (str | None): A name for the binary variable. If omitted, local variable name is used.

  • shape (list | tuple): A sequence with the size of each dimension of the continuous variable. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this variable represents a dictionary-like structure with keys dict_keys.

  • lower_bound: The lower bound of the variable.

  • upper_bound: The upper bound of the variable.

  • latex (str, optional): A LaTeX-name of the continuous variable to be represented in Jupyter notebook.

    • It is set to name by default.

  • description (str, optional): A description of the continuous variable.

Raises

ModelingError: Raises if a bound is a Placeholder or Subscript object whose ndim is neither 0 nor the same value as ndim of the continuous variable.

DecisionVar(name: Optional[str] = None, kind: DecisionVarKind, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines a DecisionVar and registers it to the problem namespace.

Decision variables can be scalars, multi-dimensional arrays (eg. representing arrays and matrices of variables), or total dictionaries.

Variables must have a DecisionVarKind (such as BINARY, INTEGER, CONTINUOUS), as well as defined lower and upper bounds.

We recommend using alternative convenience methods which predefine the decision variable’s kind, such as DecoratedProblem.IntegerVar() for integers, or DecoratedProblem.BinaryVar() for binary variables.

Representation

Depending on the arguments described below, the representation of the decision variable will be determined as follows:

  1. If none of shape or dict_keys is provided, or shape is (), DecisionVar will be considered as a scalar value (= array of dimension 0).

  2. If shape is provided and dict_keys is not provided, DecisionVar will be considered as a multi-dimensional array with fixed shape.

  3. If dict_keys is provided without shape, DecisionVar will be considered as a dictionary-like structure with keys specified by dict_keys.

  4. Otherwise, an error is raised.

Args

  • name (str | None): A name for the binary variable. If omitted, local variable name is used.

  • kind (DecisionVarKind): A kind of the decision variable.

  • shape (list | tuple): A sequence with the size of each dimension of the variable. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this variable represents a dictionary-like structure with keys dict_keys.

  • lower_bound and upper_bound (jijmodeling.Expression): A lower and upper bounds of the variable.

  • kind (DecisionVarKind): The kind of the decision variable.

  • latex (str, optional): An optional LaTeX representation to be used in Jupyter notebook.

    • It is set to be the same as name by default.

  • description (str, optional): An optional description, for user reference.

Examples

Create a scalar binary variable whose name is “z”.

import jijmodeling as jm
problem = jm.Problem("my_problem")
@problem.update
def update(problem: jm.DecoratedProblem):
    z = problem.DecisionVar(kind=jm.DecisionVarKind.BINARY, lower_bound=0, upper_bound=1)

Create a 2-dimensional binary variable whose name is “x” and has a 2x2 shape.

import jijmodeling as jm
problem = jm.Problem("my_problem")
@problem.update
def update(problem: jm.DecoratedProblem):
    z = problem.BinaryVar(shape=[2, 2])

Create a total dictionary of integer variables with the keys (I, J, 5)

import jijmodeling as jm
problem = jm.Problem("my_problem")
@problem.update
def update(problem: jm.DecoratedProblem):
    w = problem.IntegerVar(
        lower_bound=0,
        upper_bound=10,
        dict_keys=(5, 5, 5)
    )
DependentVar(definition: ExpressionLike, description: Optional[str] = None, latex: Optional[str] = None) DependentVar
DependentVar(name: str, definition: ExpressionLike, description: Optional[str] = None, latex: Optional[str] = None) DependentVar

Defines a dependent variable in this problem’s namespace.

Dependent variables are expressions defined in terms of other variables (placeholders, decision variables, or other dependent variables). They provide a way to give names to commonly-used subexpressions, improving model readability and reducing duplication.

Args

  • name (str | None): The name of the dependent variable. If omitted, the local variable name is used.

  • definition (Expression): The expression that defines this dependent variable.

  • description (str, optional): An optional description for user reference.

  • latex (str, optional): An optional custom LaTeX representation.

Examples

Define a dependent variable that squares a placeholder:

import jijmodeling as jm
problem = jm.Problem("example")
@problem.update
def _(problem: jm.DecoratedProblem):
    x = problem.Float("x")
    x_squared = problem.DependentVar(definition=x * x)
Dim(name: Optional[str] = None, ndim: Optional[int] = 0, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a natural number in this problem’s namespace.

This is just a shorthand for DecoratedProblem.Natural(ndim=0) and effectively the same as any other natural placeholder for practical purposes. The use of Dim is recommended just for clarity when defining a placeholder which will be used to define the length of multi-dimensional objects.

See DecoratedProblem.Placeholder() for more details on placeholders.

Float(name: Optional[str] = None, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a floating-point (real) number in this problem’s namespace.

A shorthand for DecoratedProblem.Placeholder(dtype=DataType.FLOAT), provided for clarity and convenience. See DecoratedProblem.Placeholder() for more details on placeholders.

Graph(name: Optional[str] = None, dtype: DataType | type | tuple = DataType.NATURAL, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

A placeholder expressing a directed graph with vertices of type dtype (without edge weights), represented by a 1-dimensional array of tuples.

A shorthand for DecoratedProblem.Placeholder(dtype=(dtype, dtype), ndim=1). By default dtype is DataType.Natural but can be specified.

Integer(name: Optional[str] = None, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing an integer in this problem’s namespace.

A shorthand for DecoratedProblem.Placeholder(dtype=DataType.INTEGER), provided for clarity and convenience. See DecoratedProblem.Placeholder() for more details on placeholders.

IntegerVar(name: Optional[str] = None, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines an integer decision variable and registers it to the problem namespace. See DecoratedProblem.DecisionVar for more details.

This is shorthand for Problem.DecisionVariable(kind=DecisionVarKind.INTEGER).

Args

  • name (str | None): A name for the binary variable. If omitted, local variable name is used.

  • shape (list | tuple): A sequence with the size of each dimension of the integer variable. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this variable represents a dictionary-like structure with keys dict_keys.

  • lower_bound: The lower bound of the variable.

  • upper_bound: The upper bound of the variable.

  • latex (str, optional): A LaTeX-name of the integer variable to be represented in Jupyter notebook.

    • It is set to name by default.

  • description (str, optional): A description of the integer variable.

Raises

ModelingError: Raises if a bound is a Placeholder or Subscript object whose ndim is neither 0 nor the same value as ndim of the integer variable.

Length(name: Optional[str] = None, ndim: Optional[int] = 0, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a natural number in this problem’s namespace.

This is just a shorthand for DecoratedProblem.Natural(ndim=0) and effectively the same as any other natural placeholder for practical purposes. The use of Length is recommended just for clarity when defining a placeholder which will be used to define the length of multi-dimensional objects.

See DecoratedProblem.Placeholder() for more details on placeholders.

Natural(name: Optional[str] = None, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a natural number in this problem’s namespace.

A shorthand for DecoratedProblem.Placeholder(dtype=DataType.NATURAL), provided for clarity and convenience. See DecoratedProblem.Placeholder() for more details on placeholders.

PartialDict(name: Optional[str] = None, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple, dtype: DataType | type | tuple, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

A shorthand for creating a partial dictionary placeholder with key type

Placeholder(name: Optional[str] = None, dtype: DataType | type | tuple, ndim: Optional[int] = None, shape: Optional[Sequence[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder in this problem’s namespace.

Placeholders can be a scalar, multi-dimensional array (representing arrays and matrices), or dictionary keyed by integers or strings.

When calling DecoratedProblem.Placehoder, you must specify dtype explicitly to indicate the type of data the placeholder holds. Alternative shorthand methods like DecoratedProblem.Integer, DecoratedProblem.Binary, or DecoratedProblem.Natural are recommended for convenience in their specific use cases.

Representation

Depending on the arguments described below, the representation of the placeholder will be determined as follows:

  1. If none none of ndim, shape, jagged, dict_keys, or partial_dict is provided, or, ndim is set to zero, Placeholder will be considered as a scalar value (= array of dimension 0).

  2. If either (or both consistently) of ndim or shape is provided and jagged is False (or omitted), and none of dict_keys or partial_dict is given, Placeholder will be considered as a multi-dimensional array with fixed shape.

  3. If either (or both consistently), of ndim or shape is provided and jagged is True, and none of dict_keys or partial_dict is given,Placeholder will be considered as a jagged array (i.e. a non-rectangular ndim array).

  4. If dict_keys is specified but none of ndim, shape, jagged is provided, then Placeholder will be considered as a total dictionary-like structure with keys specified by dict_keys.

  5. If both dict_keys and partial_dict (set to True) are specified, and none of ndim, shape, or jagged is provided, then Placeholder will be considered as a partial dictionary-like structure with keys specified by dict_keys.

  6. Otherwise, an error is raised.

Args

  • name (str | None): The placeholder’s name. If omitted, the local variable name is used.

  • dtype (DataType): The type of data this placeholder holds (integer, floating point, etc.).

  • ndim (int): The number of dimensions in this placeholder. Defaults to 0 (a scalar value).

  • shape (list | tuple): A sequence with the size of each dimension of the placeholder. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

    • There is no need to provide ndim if shape is specified, but they must not conflict if both specified.

  • jagged (bool): Whether this placeholder represents a jagged array (ie. a non-square matrix). Ignored if scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this placeholder represents a dictionary-like structure with keys dict_keys.

  • partial_dict (bool, optional): If dict_keys is provided, specifies whether this placeholder represents a partial dictionary (i.e., not all keys are guaranteed to be present). Defaults to False.

  • latex (str, optional): An optional LaTeX representation to be used in Jupyter notebook.

    • When not provided, name is used by default.

  • description (str, optional): An optional description for user reference.

Examples

Create a scalar integer placeholder whose name is “a”.

import jijmodeling as jm
problem = jm.Problem("my_problem")
@problem.update
def _(problem: jm.DecoratedProblem):
    a = problem.Integer("a")
SemiContinuousVar(name: Optional[str] = None, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar
SemiIntegerVar(name: Optional[str] = None, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines a semi-integer decision variable and registers it to the problem namespace. See DecoratedProblem.DecisionVar for more details.

This is shorthand for problem.DecisionVariable(kind=DecisionVarKind.SEMI_INTEGER).

TotalDict(name: Optional[str] = None, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple, dtype: DataType | type | tuple, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

A shorthand for creating a total dictionary placeholder with key type

__iadd__(other: Constraint) DecoratedProblem
__iadd__(other: ExpressionLike) DecoratedProblem

Add constraint to the problem.

eval(instance_data: str | int | float | NDArray[numpy.float64] | NDArray[numpy.int64] | list | dict | str, constraint_detection: ConstraintDetectionConfig | bool = None) Instance

Compiles and evaluates the problem given the specified instance data, returning an OMMX instance.

A short-hand of Compiler.from_problem(self, data).eval_problem(self).

Args

  • instance_data (dict[str, InstanceValue]): A dictionary mapping placeholder and category label names to their corresponding values for this instance. See Compiler for more details on the expected format of instance_data.

  • constraint_detection (Optional[ConstraintDetectionConfig]): Configuration for automatic constraint hint detection. If None, the default configuration is used. Pass false or jijmodeling.ConstraintDetectionConfig.disable() to disable constraint hint detection. See Compiler and ConstraintDetectionConfig for details.

generate_random_dataset(_default: Any, _options: Any, _seed: Optional[int]) Any

Generates a dictionary of random InstanceDataValue for a given problem. To generate ommx.v1.Instance object directly, use InstanceDataValue.generate_random_instance instead.

Args

  • options (optional): a dictionary of range parameters for each separate placeholders. The key must be the name of the placeholder and the value must be range parameter (as described in “Range Parameters and Range Syntax” below).

  • default (optional): default range parameters for placeholders which is not specified in options.

  • seed (optional): seed for random number generation.

Returns

dict: The dictionary from the name of placeholders to the generated InstanceDataValue objects. To be fed to Interpreter.eval_problem.

Range Parameters and Range Syntax

A range parameter is a dictionary consisting of the following fields:

  • size (optional): interval of natural numbers for the size of each array dimension (default: range(1, 6))

  • value (optional): interval of real numbers for the value of each array element (default: range(-1.0, 1.0) - a uniform distribution on a closed interval [1.0,1.0][-1.0, 1.0]).

Example range parameter config:

{"size": range(2, 10), "value": jm.range.value.closed(100.0, 200.0)}

Intervals are expressed as a range object. Currently, the following syntax is supported for range objects:

  1. Direct value of type int or float - it corresponds to a singleton interval [a,a]={a}[a, a] = \{a\}. In random generation context, this just means a constant fixed value.

  2. Use the functions from jijmodeling.range, jijmodeling.range.size, or jijmodeling.range.value modules.

    • Use functions from jij.modeling.range.size to specify (non-negative) integer intervals, and jij.modeling.range.value for real intervals. jij.modeling.range dynamically determines the type of the range based on the input.

    • These three modules provides the following combinators (see the module documents for more details.): - closed(a, b): a closed interval [a,b][a, b] - open(a, b): an open interval (a,b)(a, b) - closed_open(a, b): an upper half-open interval [a,b)[a, b) - open_closed(a, b): a lower half-open interval (a,b](a, b] - greater_than(a): an open interval (a,)(a, \infty) - at_least(a): a closed interval [a,)[a, \infty) - less_than(a): an open interval (,a)(-\infty, a) - at_most(a): a closed interval (,a](-\infty, a]

  3. Use range builtin function: this is equivalent to jijmodeling.range.value.closed_open(a, b).

    • Any python range object with step = 1 can be used as a size range; otherwise it results in runtime error.

  4. Use a tuple: raw tuple (a, b) is equivalent to jijmodeling.range.closed_open(a, b) if a and b are either int or float.

    • You can also use bound object as a tuple component; in such case, both tuple components must be one of the following:

      1. A string "Unbounded" means -\infty (in the first component) or \infty (the second).

      2. A dictionary {"Included": a} means the endpoint is inclusive.

      3. A dictionary {"Excluded": a} means the endpoint is exclusive.

    • Examples: - (1.2, 4) is equivalent to closed_open(1.2, 4), - (-1, {"Included": 1}) is equivalent to closed(-1, 1), - (-5, {"Excluded": 4}) is equivalent to closed_open(-5, 4) and built in function range(-5, 4), - ({"Excluded": 1}, {"Excluded": 2.5}) is equivalent to open(1, 2.5), - ({"Included": -1}, "Unbounded") is equivalent to at_least(-1). - (5, "Unbounded") is INVALID; 5 must be bound object.

  5. The range object: A dictionary of form {"start": lb, "end": ub}, where both lb and ub are the bound object described as above.

Examples

import jijmodeling as jm
import builtins
problem = jm.Problem("problem")
N = problem.Integer("N")
c = problem.Float("c", shape=(N,))
x = problem.BinaryVar("x", shape=(N,))
i = jm.Element("i", belong_to=N)
problem += jm.sum(i, c[i] * x[i])
inputs = problem.generate_random_dataset(
    options={
        'N': {"value": builtins.range(10, 20)},
        'c': {"value": jm.range.value.closed(-1.0, 1.0)}
         # You can also specify "size" for the range of jagged array dimension size.
    },
    seed=123 # omittable
)
assert set(inputs.keys()) == {"N", "c"}
inputs
# {'N': 11.0, 'c': array([ 0.93914459, -0.06511935, -0.7460324 , -0.32443706,  0.99981451,
#        -0.24407535,  0.31329469,  0.52206453, -0.1291936 ,  0.30443087,
#         0.53125838])}
generate_random_instance(_default: Any, _options: Any, _seed: Optional[int], _hints: Optional[Any]) Any

Generates random ommx.v1.Instance for a given problem. See also InstanceDataValue.generate_random_dataset.

Args

  • options (optional): a dictionary of range parameters for each separate placeholders. The key must be the name of the placeholder and the value must be range parameter (as described in “Range Parameters and Range Syntax” section in Problem.generate_random_dataset()).

  • default (optional): default range parameters for placeholders which is not specified in options.

  • seed (optional): seed for random number generation.

  • hints (optional): the hints to be detected during compilation see Interpreter.eval_problem for more details.

Returns

instance: The OMMX v1 instance object.

Examples

import jijmodeling as jm
import builtins
import ommx.v1
problem = jm.Problem("problem")
N = problem.Integer("N")
c = problem.Float("c", shape=(N,))
x = problem.BinaryVar("x", shape=(N,))
i = jm.Element("i", belong_to=N)
problem += jm.sum(i, c[i] * x[i])
instance = problem.generate_random_instance(
    options={
        'N': {"value": builtins.range(10, 20)},
        'c': {"value": jm.range.value.closed(-1.0, 1.0)}
    },
    seed=123
)
assert type(instance) is ommx.v1.Instance
get_problem_schema() dict

Returns the schema of the problem.

Returns

  • schema: The dictionary containing the schema of the problem.

infer(expr: ExpressionLike) Type

Infers the resulting type of an expression using this problem as a namespace.

This is mostly intended for testing purposes, and not as part of standard model writing.

Examples

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Length(name="N")
>>> x = problem.BinaryVar("x", shape=(N,))
>>> y = problem.IntegerVar("y", shape=(N,), lower_bound=0,upper_bound=10)
>>> problem.infer(jm.sum(x))
binary!
>>> problem.infer(jm.sum(y))
int!

type_of(name: str) Type

Returns the type associated with a given name (eg. of a placeholder or decision variable).

This is mostly inteded for testing purposes, and not as part of standard model writing.

:raises ModelingError: If the name is undefined in this problem’s namespace.

class DependentVar

A dependent variable in a mathematical model.

Dependent variables are expressions defined in terms of other variables (placeholders, decision variables, or other dependent variables). They provide a way to give names to commonly-used subexpressions, improving model readability and reducing duplication.

Unlike decision variables, dependent variables are not optimized by the solver - they’re computed from other variables. Unlike placeholders, their values are determined by the model structure rather than instance data.

Dependent variables must belong to some namespace (ie. a Problem), so you CANNOT construct one directly. Use Problem.DependentVar() to define dependent variables.

Attributes:

  • name (str): The name of the dependent variable.

  • definition (Expression): The expression that defines this dependent variable.

  • description (str, optional): An optional description for user reference.

  • custom_latex (str, optional): An optional custom LaTeX representation.

Examples: Define a dependent variable that squares a placeholder:

import jijmodeling as jm
problem = jm.Problem("example")
x = problem.Float("x")
x_squared = problem.DependentVar("x_squared", x * x)
__add__(rhs: ExpressionLike) Expression
__and__(rhs: ExpressionLike) Expression
__eq__(other: Any) Expression
__ge__(other: Any) Expression
__getitem__(subscripts: Any) Expression
__gt__(other: Any) Expression
__iter__() Any
__le__(other: Any) Expression
__lt__(other: Any) Expression
__mod__(rhs: ExpressionLike) Expression
__mul__(rhs: ExpressionLike) Expression
__ne__(other: Any) Expression
__neg__() Expression
__or__(rhs: ExpressionLike) Expression
__pow__(exponent: Any, modulo: Optional[Any] = None) Expression
__radd__(lhs: ExpressionLike) Expression
__rand__(lhs: ExpressionLike) Expression
__repr__() str
__rmod__(lhs: ExpressionLike) Expression
__rmul__(lhs: ExpressionLike) Expression
__ror__(lhs: ExpressionLike) Expression
__rpow__(base: Any, modulo: Optional[Any] = None) Expression
__rsub__(lhs: ExpressionLike) Expression
__rtruediv__(lhs: ExpressionLike) Expression
__rxor__(lhs: ExpressionLike) Expression
__sub__(rhs: ExpressionLike) Expression
__truediv__(rhs: ExpressionLike) Expression
__xor__(rhs: ExpressionLike) Expression
_repr_latex_() str
abs() Expression

Returns an expression representing the absolute value of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acos() Expression

Returns an expression representing the arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acosh() Expression

Returns an expression representing the hyperbolic arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asin() Expression

Returns an expression representing the arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asinh() Expression

Returns an expression representing the hyperbolic arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atan() Expression

Returns an expression representing the arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atanh() Expression

Returns an expression representing the hyperbolic arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

bnot() Expression
ceil() Expression

Returns an expression which rounds down to the nearest whole number.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cos() Expression

Returns an expression representing the cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cosh() Expression

Returns an expression representing the hyperbolic cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

diff(rhs: ExpressionLike) Expression
enumerate() Expression

Enumerate elements of a set-like collection with 0-based indices.

Returns a set of (index, element) tuples, similar to Python’s built-in enumerate() function.

Parameters: operand : Expression A set-like expression to enumerate.

Returns: Expression A set expression where each element is a tuple of (index, original_element).

exp() Expression

Returns an expression representing the application of the exponential function on the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

filter(predicate: ExpressionFunction) Expression

Creates an expression that filters the values of this sequence.

predicate will be called on each element in self. The resulting expression represents only the values for which predicate is true.

This is an alternative to jijmodeling.filter() which allows you to place the indexing expression first.

This is often useful when trying to create summations which only include a subset of potential indices.The resulting expression is usually used as the basis for jijmodeling.map(), jijmodeling.sum(), etc., or a method equivalent.

Examples:

Using only variables with even indices as part of a constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> even_xs = N.filter(lambda i: i % 2 == 0).map(lambda i: x[i])
>>> problem += problem.Constraint("constr", even_xs.sum() <= 10)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=LESS_THAN_EQUAL, left=sum(N.filter(lambda i: i % 2 == 0).map(lambda (i: natural): x[i])), right=10, shape=Scalar(Natural)),],})

Using only non-diagonal indices of an NxN matrix as part of a constraint, using the method version of filter.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> non_diagonals = jm.product(N, N).filter(lambda i, j: i != j)
>>> problem += problem.Constraint("constr", lambda i, j: W[i, j] * x[i, j] >= 0, domain=non_diagonals)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", , lambda (i, j): W[i, j] * x[i, j] >= 0, domain=set((N, N)).filter(lambda (i, j): i != j)),],})

flat_map(func: ExpressionFunction) Expression

Creates an expression which works like map(), but flattens nested structure.

This is an alternative to flat_map() which allows you to place the indexing expression first.

map is useful when func returns scalar values, but in some situations one wants to write a func that returns other mappings/sequences instead. That is where flat_map should be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced with sum(), etc.)

You can also compare flat_map to a nested for-loop, or a generator expression that uses two for clauses. Indeed when using the decorated API (see tutorials or @Problem.update), you can use a generator expression-like syntax instead.

Examples:

Using only non-diagonal indices of an NxN matrix.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> objective = N.flat_map(
...    lambda i: N.filter(lambda j: i != j).map(lambda j: W[i, j] * x[i, j])
... ).sum()
>>> problem += objective
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(N.flat_map(lambda (i: natural): N.filter(lambda j: i != j).map(lambda (j: natural): W[i, j] * x[i, j]))), constraints=[])

floor() Expression
indices() Expression

Get the set of indices of given array or jagged array.

Will throw type error when called on non-array type.

items() Expression

Returns an expression representing this object’s (key,value) pairs.

In other words, this is the JijModeling equivalent of the items() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.keys() and Expression.values().

Examples: Simple matching of weights to their respective variables, as an alternative to just using keys() or the CategoryLabel:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> weights = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=I)
>>> problem += jm.sum(weights.items(), lambda i, w: w * x[i])
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.items().map(lambda ((i, w): Tuple[CategoryLabel("I"), float]): w * x[i])), constraints=[])

Same as above, but using the decorated API:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> @problem.update
... def _(problem):
...     I = problem.CategoryLabel()
...     W = problem.Float(dict_keys=I)
...     x = problem.BinaryVar(dict_keys=I)
...     problem += jm.sum(w * x[i] for i, w in W.items())
>>> problem
Problem(name="MyProblem", ...)

keys() Expression

Returns an expression representing this dictionary-like object’s keys.

In other words, this is the JijModeling equivalent of the keys() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.values() and Expression.items().

Examples: Refer to a dictionary-like placeholder’s keys when creating other objects or writing summations:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> W = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=W.keys())
>>> problem += jm.sum(W.keys(), lambda i: W[i] * x[i])
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.keys().map(lambda (i: CategoryLabel("I")): W[i] * x[i])), constraints=[])
ln() Expression

Returns an expression representing the natural logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log10() Expression

Returns an expression representing the decimal logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log2() Expression

Returns an expression representing the binary logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

map(func: ExpressionFunction) Expression

Creates an expression that maps the values in self to func.

This is an alternative to jijmodeling.map() which allows you to place the indexing expression first.

When called on valid scalar scalars, each number from 0 to this self will be passed to func. When called on a sequence expression (eg. a 1-dimensional placeholder, or the result of functions like jijmodeling.product() or jijmodeling.items()), each element in the sequence is passed to func.

This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like Placeholders and DecisionVars. The resulting expression is then usually passed to a reducer, like jijmodeling.sum() (or Expression.sum() is called on it), to form part of a constraint or the objective function.

Examples:

Indexing by values from 0 to N. In this example we define N as the length of another placeholder, but a scalar Natural placeholder would work as well.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += N.map(lambda i: W[i] * x[i]).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.len_at(0).map(lambda (i: natural): W[i] * x[i])), constraints=[])

Indexing by specific values from instance data. In this example only the indices present in C in the instance data will be used in this constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> C = problem.Natural("C", ndim=1)
>>> problem += problem.Constraint("constr", C.map(lambda i: x[i]).sum() <= 100)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=LESS_THAN_EQUAL, left=sum(C.map(lambda (i: natural): x[i])), right=100, shape=Scalar(Integer)),],})

max() Expression
max(rhs: ExpressionLike) Expression

Creates an expression which refers to the largest value in self.

This method works only on valid sequence expressions, where the resulting expression is a scalar representing the largest among all values in the sequence.

min() Expression
min(rhs: ExpressionLike) Expression

Creates an expression which refers to the smallest value in self.

This method works only on valid sequence expressions, where the resulting expression is a scalar representing the smallest among all values in the sequence.

ndenumerate() Expression

Enumerate elements of a tensor or jagged array with multi-dimensional indices.

Returns an array where each element is paired with its multi-dimensional index as a tuple of natural numbers.

Parameters: operand : Expression A tensor or jagged array expression to enumerate.

Returns: Expression An array expression where each element is a tuple of (index_tuple, original_element), where index_tuple is a tuple of natural numbers representing the multi-dimensional position.

prod(axis: ExpressionLike | int | Sequence[ExpressionLike] | Sequence[int] = None) Expression

Creates an expression representing the multiplication of self.

This is an alternative to using jijmodeling.prod(), where a method call on an expression may be more convenient/readable.

If self isn’t a valid sequence which can be multiplied, you will get an error when the resulting expression is added to a Problem and is type-checked.

The optional axis parameter allows you to specify axes of a multi-dimensional expression across which to perform the operation.

Examples:

Simple product of decision variables

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> problem += x.prod()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=prod(x), constraints=[])

roll(shift: Any, axis: Optional[int] = None) Expression
rows() Expression

Creates a sequence over the rows of this multi-dimensional array expression.

That is, each element will be a whole row (itself containing multiple values), which can then be operated on like other sequences (eg. using jijmodeling.sum() or jijmodeling.map()).

If the array is 3-dimensional or higher, rows will iterate over the first dimension/axis. For example, in a 3D matrix, the first element would be a 2D matrix representing all values x[0, _, _]

Examples

Create an objective function that multiplies each variable in a row, and then sums each row. In this case we have a 2x3 matrix, so the final expression is x[0, 0] * x[0, 1] * x[0, 2] + x[1, 0] * x[1, 1] * x[1, 2]. Using placeholders instead of literals in shape would allow this to be written for matrices of arbitrary size.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> d = problem.BinaryVar("d", shape=(2, 3))
>>> problem += d.rows().map(lambda xs: xs.prod()).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(d.rows().map(lambda (xs: Array[3; binary!]): prod(xs))), constraints=[])

If the number of elements in the row can be guaranteed, the elements can be destructured as separate arguments in a lambda expression:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> V = problem.Natural("V")
>>> E = problem.Natural("E", shape=(N, 2))
>>> x = problem.BinaryVar("x", shape=V)
>>> problem += jm.map(lambda i, j: x[i] * x[j], E.rows()).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(E.rows().map(lambda ((i, j): Array[2; natural]): x[i] * x[j])), constraints=[])

sin() Expression

Returns an expression representing the sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sinh() Expression

Returns an expression representing the hyperbolic sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sqrt() Expression

Returns an expression representing the square root of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sum(axis: ExpressionLike | int | Sequence[ExpressionLike] | Sequence[int] = None) Expression

Creates an expression representing the summation of self.

This is an alternative to using jijmodeling.sum(), where a method call on an expression may be more convenient/readable.

If self isn’t a valid sequence which can be summed, you will get an error when the resulting expression is added to a Problem and is type-checked.

The optional axis parameter allows you to specify axes of a multi-dimensional expression across which to perform the operation.

Examples:

Simple sum of decision variables.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> problem += x.sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(x), constraints=[])

Performing a weighted sum. Note that this sort of usage may lead to errors when the shapes don’t match. In this case we guarantee that x has the same shape as W through its definition.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += (W * x).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W * x), constraints=[])

tan() Expression

Returns an expression representing the tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

tanh() Expression

Returns an expression representing the hyperbolic tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

unique() Expression

Remove duplicate elements from this array-like expression, preserving order.

Returns: Expression A set expression with duplicates removed.

values() Expression

Returns an expression representing this dictionary-like object’s values.

In other words, this is the JijModeling equivalent of the values() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.keys() and Expression.items().

Examples: Defining a simple objective function which just sums a dictionary-based decision variable.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> x = problem.IntegerVar("x", dict_keys=I, lower_bound=0, upper_bound=100)
>>> problem += x.values().sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(x.values()), constraints=[])
class DesugaredProblemBuilder
__call__() None
class Expression

An expression used to compose mathematical models.

Expressions form the core of how optimization problems are represented in JijModeling, being how you define the objective function and constraints of in your jijmodeling.Problem.

You build Expressions by applying regular mathematical operators on relevant JijModeling objects (eg. jijmodeling.DecisionVar, jijmodeling.Placeholder) alongside number literals. Many methods on Expression and other JijModeling classes also return Expressions. There’s no need to directly instantiate or convert an Expression as it’s done automatically whenever one is required.

Generally speaking, JijModeling is very permissive with what expression you may write. However, type-checking happens when an Expression is added to a Problem, meaning invalid operations will be detected and result in errors.

Additional checks happen when evaluating a model alongside instance data to create an OMMX instance. Additional OMMX restrictions may apply (such as limits on operations allowed on decision variables), and your data will have to be appropriate for the expressions you have written.

Notes on ExpressionLike and ExpressionFunction

There are dummy type aliases called ExpressionLike and ExpressionFunction, which are present only in stub files. They serves as a shorthand to make type hints more readable, as many functions and methods accept a wide variety of types that can be converted to expressions, but not necessarily Expression objects themselves. The meaning of these type aliases are as follows:

  1. ExpressionLike: Any type that can be converted to an Expression. This includes:

    • Expression itself,

    • Numeric values like int and float,

    • DecisionVar, DependentVar, and Placeholder, CategoryLabel, and

    • tuples, lists, and dictionaries of them.

  2. ExpressionFunction: Any function (callable) that takes one or more Expression arguments and returns an Expression. Due to the limitations of Python’s type hinting system, the hint lists functions with only up to five arguments, but you can actually use functions with more expressions as well.

__add__(rhs: ExpressionLike) Expression
__and__(rhs: ExpressionLike) Expression
__call__(args: Any) Expression
__eq__(other: Any) Expression
__ge__(other: Any) Expression
__getitem__(subscripts: Any) Expression
__gt__(other: Any) Expression
__iter__() Any
__le__(other: Any) Expression
__lt__(other: Any) Expression
__mod__(rhs: ExpressionLike) Expression
__mul__(rhs: ExpressionLike) Expression
__ne__(other: Any) Expression
__neg__() Expression
__or__(rhs: ExpressionLike) Expression
__pow__(exponent: Any, modulo: Optional[Any] = None) Expression
__radd__(lhs: ExpressionLike) Expression
__rand__(lhs: ExpressionLike) Expression
__repr__() str
__rmod__(lhs: ExpressionLike) Expression
__rmul__(lhs: ExpressionLike) Expression
__ror__(lhs: ExpressionLike) Expression
__rpow__(base: Any, modulo: Optional[Any] = None) Expression
__rsub__(lhs: ExpressionLike) Expression
__rtruediv__(lhs: ExpressionLike) Expression
__rxor__(lhs: ExpressionLike) Expression
__sub__(rhs: ExpressionLike) Expression
__truediv__(rhs: ExpressionLike) Expression
__xor__(rhs: ExpressionLike) Expression
_repr_latex_() str
abs() Expression

Returns an expression representing the absolute value of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acos() Expression

Returns an expression representing the arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acosh() Expression

Returns an expression representing the hyperbolic arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asin() Expression

Returns an expression representing the arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asinh() Expression

Returns an expression representing the hyperbolic arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atan() Expression

Returns an expression representing the arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atanh() Expression

Returns an expression representing the hyperbolic arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

bnot() Expression
ceil() Expression

Returns an expression which rounds down to the nearest whole number.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cos() Expression

Returns an expression representing the cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cosh() Expression

Returns an expression representing the hyperbolic cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

diff(rhs: ExpressionLike) Expression
enumerate() Expression

Enumerate elements of a set-like collection with 0-based indices.

Returns a set of (index, element) tuples, similar to Python’s built-in enumerate() function.

Parameters: operand : Expression A set-like expression to enumerate.

Returns: Expression A set expression where each element is a tuple of (index, original_element).

exp() Expression

Returns an expression representing the application of the exponential function on the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

filter(predicate: ExpressionFunction) Expression

Creates an expression that filters the values of this sequence.

predicate will be called on each element in self. The resulting expression represents only the values for which predicate is true.

This is an alternative to jijmodeling.filter() which allows you to place the indexing expression first.

This is often useful when trying to create summations which only include a subset of potential indices.The resulting expression is usually used as the basis for jijmodeling.map(), jijmodeling.sum(), etc., or a method equivalent.

Examples:

Using only variables with even indices as part of a constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> even_xs = N.filter(lambda i: i % 2 == 0).map(lambda i: x[i])
>>> problem += problem.Constraint("constr", even_xs.sum() <= 10)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=LESS_THAN_EQUAL, left=sum(N.filter(lambda i: i % 2 == 0).map(lambda (i: natural): x[i])), right=10, shape=Scalar(Natural)),],})

Using only non-diagonal indices of an NxN matrix as part of a constraint, using the method version of filter.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> non_diagonals = jm.product(N, N).filter(lambda i, j: i != j)
>>> problem += problem.Constraint("constr", lambda i, j: W[i, j] * x[i, j] >= 0, domain=non_diagonals)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", , lambda (i, j): W[i, j] * x[i, j] >= 0, domain=set((N, N)).filter(lambda (i, j): i != j)),],})

flat_map(func: ExpressionFunction) Expression

Creates an expression which works like map(), but flattens nested structure.

This is an alternative to flat_map() which allows you to place the indexing expression first.

map is useful when func returns scalar values, but in some situations one wants to write a func that returns other mappings/sequences instead. That is where flat_map should be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced with sum(), etc.)

You can also compare flat_map to a nested for-loop, or a generator expression that uses two for clauses. Indeed when using the decorated API (see tutorials or @Problem.update), you can use a generator expression-like syntax instead.

Examples:

Using only non-diagonal indices of an NxN matrix.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> objective = N.flat_map(
...    lambda i: N.filter(lambda j: i != j).map(lambda j: W[i, j] * x[i, j])
... ).sum()
>>> problem += objective
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(N.flat_map(lambda (i: natural): N.filter(lambda j: i != j).map(lambda (j: natural): W[i, j] * x[i, j]))), constraints=[])

floor() Expression
indices() Expression

Get the set of indices of given array or jagged array.

Will throw type error when called on non-array type.

items() Expression

Returns an expression representing this object’s (key,value) pairs.

In other words, this is the JijModeling equivalent of the items() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.keys() and Expression.values().

Examples: Simple matching of weights to their respective variables, as an alternative to just using keys() or the CategoryLabel:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> weights = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=I)
>>> problem += jm.sum(weights.items(), lambda i, w: w * x[i])
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.items().map(lambda ((i, w): Tuple[CategoryLabel("I"), float]): w * x[i])), constraints=[])

Same as above, but using the decorated API:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> @problem.update
... def _(problem):
...     I = problem.CategoryLabel()
...     W = problem.Float(dict_keys=I)
...     x = problem.BinaryVar(dict_keys=I)
...     problem += jm.sum(w * x[i] for i, w in W.items())
>>> problem
Problem(name="MyProblem", ...)

keys() Expression

Returns an expression representing this dictionary-like object’s keys.

In other words, this is the JijModeling equivalent of the keys() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.values() and Expression.items().

Examples: Refer to a dictionary-like placeholder’s keys when creating other objects or writing summations:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> W = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=W.keys())
>>> problem += jm.sum(W.keys(), lambda i: W[i] * x[i])
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.keys().map(lambda (i: CategoryLabel("I")): W[i] * x[i])), constraints=[])
len_at(axis: int, latex: Optional[str] = None) Expression

Returns an expression which represents the length (number of values) of this expression at a given dimension (0-indexed).

This can be used, for example, when trying to match the shape of an object to the number of values in an array.

ln() Expression

Returns an expression representing the natural logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log10() Expression

Returns an expression representing the decimal logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log2() Expression

Returns an expression representing the binary logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

map(func: ExpressionFunction) Expression

Creates an expression that maps the values in self to func.

This is an alternative to jijmodeling.map() which allows you to place the indexing expression first.

When called on valid scalar scalars, each number from 0 to this self will be passed to func. When called on a sequence expression (eg. a 1-dimensional placeholder, or the result of functions like jijmodeling.product() or jijmodeling.items()), each element in the sequence is passed to func.

This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like Placeholders and DecisionVars. The resulting expression is then usually passed to a reducer, like jijmodeling.sum() (or Expression.sum() is called on it), to form part of a constraint or the objective function.

Examples:

Indexing by values from 0 to N. In this example we define N as the length of another placeholder, but a scalar Natural placeholder would work as well.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += N.map(lambda i: W[i] * x[i]).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.len_at(0).map(lambda (i: natural): W[i] * x[i])), constraints=[])

Indexing by specific values from instance data. In this example only the indices present in C in the instance data will be used in this constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> C = problem.Natural("C", ndim=1)
>>> problem += problem.Constraint("constr", C.map(lambda i: x[i]).sum() <= 100)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=LESS_THAN_EQUAL, left=sum(C.map(lambda (i: natural): x[i])), right=100, shape=Scalar(Integer)),],})

max() Expression
max(rhs: ExpressionLike) Expression

Creates an expression which refers to the largest value in self.

This method works only on valid sequence expressions, where the resulting expression is a scalar representing the largest among all values in the sequence.

min() Expression
min(rhs: ExpressionLike) Expression

Creates an expression which refers to the smallest value in self.

This method works only on valid sequence expressions, where the resulting expression is a scalar representing the smallest among all values in the sequence.

ndenumerate() Expression

Enumerate elements of a tensor or jagged array with multi-dimensional indices.

Returns an array where each element is paired with its multi-dimensional index as a tuple of natural numbers.

Parameters: operand : Expression A tensor or jagged array expression to enumerate.

Returns: Expression An array expression where each element is a tuple of (index_tuple, original_element), where index_tuple is a tuple of natural numbers representing the multi-dimensional position.

prod(axis: ExpressionLike | int | Sequence[ExpressionLike] | Sequence[int] = None) Expression

Creates an expression representing the multiplication of self.

This is an alternative to using jijmodeling.prod(), where a method call on an expression may be more convenient/readable.

If self isn’t a valid sequence which can be multiplied, you will get an error when the resulting expression is added to a Problem and is type-checked.

The optional axis parameter allows you to specify axes of a multi-dimensional expression across which to perform the operation.

Examples:

Simple product of decision variables

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> problem += x.prod()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=prod(x), constraints=[])

roll(shift: Any, axis: Optional[int] = None) Expression
rows() Expression

Creates a sequence over the rows of this multi-dimensional array expression.

That is, each element will be a whole row (itself containing multiple values), which can then be operated on like other sequences (eg. using jijmodeling.sum() or jijmodeling.map()).

If the array is 3-dimensional or higher, rows will iterate over the first dimension/axis. For example, in a 3D matrix, the first element would be a 2D matrix representing all values x[0, _, _]

Examples

Create an objective function that multiplies each variable in a row, and then sums each row. In this case we have a 2x3 matrix, so the final expression is x[0, 0] * x[0, 1] * x[0, 2] + x[1, 0] * x[1, 1] * x[1, 2]. Using placeholders instead of literals in shape would allow this to be written for matrices of arbitrary size.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> d = problem.BinaryVar("d", shape=(2, 3))
>>> problem += d.rows().map(lambda xs: xs.prod()).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(d.rows().map(lambda (xs: Array[3; binary!]): prod(xs))), constraints=[])

If the number of elements in the row can be guaranteed, the elements can be destructured as separate arguments in a lambda expression:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> V = problem.Natural("V")
>>> E = problem.Natural("E", shape=(N, 2))
>>> x = problem.BinaryVar("x", shape=V)
>>> problem += jm.map(lambda i, j: x[i] * x[j], E.rows()).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(E.rows().map(lambda ((i, j): Array[2; natural]): x[i] * x[j])), constraints=[])

shape(latex: Optional[str] = None) Expression

Returns an expression which represents the shape of this expression.

Unlike the attributes in DecisionVar and Placeholder, this expression is opaque and abstract – but can still be used to define the shape of new objects according to the shape of arbitrary expressions.

sin() Expression

Returns an expression representing the sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sinh() Expression

Returns an expression representing the hyperbolic sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sqrt() Expression

Returns an expression representing the square root of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sum(axis: ExpressionLike | int | Sequence[ExpressionLike] | Sequence[int] = None) Expression

Creates an expression representing the summation of self.

This is an alternative to using jijmodeling.sum(), where a method call on an expression may be more convenient/readable.

If self isn’t a valid sequence which can be summed, you will get an error when the resulting expression is added to a Problem and is type-checked.

The optional axis parameter allows you to specify axes of a multi-dimensional expression across which to perform the operation.

Examples:

Simple sum of decision variables.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> problem += x.sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(x), constraints=[])

Performing a weighted sum. Note that this sort of usage may lead to errors when the shapes don’t match. In this case we guarantee that x has the same shape as W through its definition.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += (W * x).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W * x), constraints=[])

tan() Expression

Returns an expression representing the tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

tanh() Expression

Returns an expression representing the hyperbolic tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

unique() Expression

Remove duplicate elements from this array-like expression, preserving order.

Returns: Expression A set expression with duplicates removed.

values() Expression

Returns an expression representing this dictionary-like object’s values.

In other words, this is the JijModeling equivalent of the values() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.keys() and Expression.items().

Examples: Defining a simple objective function which just sums a dictionary-based decision variable.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> x = problem.IntegerVar("x", dict_keys=I, lower_bound=0, upper_bound=100)
>>> problem += x.values().sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(x.values()), constraints=[])
with_latex(latex: Optional[str]) Expression

Returns an equivalent expression with the given custom LaTeX representation.

This allows setting custom LaTeX representations for arbitrary expressions or for derived objects.

Note that as Expressions are immutable, this returns a new one with the given custom LaTeX. Use as such:

N = x.len_at(0)
N = N.with_latex("N")
# or
N = x.len_at(0).with_latex("N")

Note that some methods like jijmodeling.Expression.len_at() already allow you to specify a custom LaTeX string as an optional argument.

class ModelingError
class Namespace
Placeholder(name: str, dtype: DataType | type | tuple, ndim: Optional[int] = None, shape: Optional[Sequence[Optional[ExpressionLike]]] = None, jagged: bool = False, latex: Optional[str] = None, description: Optional[str] = None) Placeholder
__new__() Namespace
add_category_label(label: CategoryLabel) None

Add a new opaque category label to the namespace.

add_decision_var(var: DecisionVar) None
add_placeholder(placeholder: Placeholder) None
from_problem(problem: Problem) Namespace
infer(expr: ExpressionLike) Type
type_of(name: str) Optional[Type]
class Placeholder

A placeholder for instance-specific parameters.

This class represents a symbol of unspecified value, which is to be replaced by numerical values when you evaluate an optimization problem, before solving it. Think of it like a instance-specific constant/parameters you want to abstract in your model (for examples, the weights of different objects/nodes).

Like decision variables, Placeholders are often used throughout your model within Expressions, and should generally work wherever an Expression is expected. Operations will automatically convert as needed.

Placeholders must belong to some namespace, i.e. a Problem, so you cannot construct one directly. Use Problem.Placeholder or shorthand methods shorthands (e.g., Problem.Integer, Problem.Float, etc.) to define placeholders.

Placeholders can be defined and used as scalars (unit values), n-dimensional arrays, or as dictionaries. In the latter two cases, a single Placeholder object represents multiple values in the model, and requires subscripting to access individual values. This is similar to how in a mathematical formula you may call a whole set by a symbol WW, made up of W0,W1,...W_0, W_1, .... More details on these usages is provided in the following sections.

Array placeholders, shape and ndim

You can define Placeholders as n-dimensional arrays (aka. matrix, tensors, etc.). While some operations can work on arrays directly, in general this means you’ll have to use subscripts (ie. indexing with []) to refer to individual values writing expressions.

Array placeholders are defined by specifying either ndim or shape in the constructor method. ndim simply states the number of dimensions a placeholder will have. Shapes are tuples or lists of expressions, where each entry specifies the number of values in a given dimension. For example:

  • a 10 shape represents a 1-dimensional array with 10 values. (Defining the shape as (10,) would be equivalent)

  • a (2, 2) shape represents a 2-dimensional array with 2 values in each dimension (a 2x2 matrix)

Only one of ndim or shape is required to define an array placeholder, but if both are provided they must be consistent with eachother.

When only ndim is provided, the shape of the placeholder is not yet defined but it still has one in an abstract sense (which will be defined by the instance data), and Placeholder.shape will return a tuple of “length at” expressions.

Scalar placeholders have a shape of () (an empty tuple) and 0 dimensions.

Dictionary placeholders

As an alternative to the array-like interface, placeholders can also be used in a style closer to python dictionaries: an unordered collection indexed by a set of labels. This is recommended mostly when you’re focused on string-based labels or want non-contiguous indices.

To use variables this way, you must first define a set of labels through Problem.CategoryLabel()s. This is a special kind of placeholder which will represent the keys to dictionaries, and can be reused throughout your model (eg. to define matching dictionary-like DecisionVars).

This CategoryLabel instance is then passed to the dict_keys parameter in the appropriate constructor (Problem.Placeholder(), etc.). Tuples of category labels can be passed to define dictionaries which use multiple keys.

By default, dictionary placeholders are “total”, that is, each label given by the CategoryLabel must have a corresponding value in the data. If you wish to create a partial dictionary, when only certain keys will have data, you must define partial_dict as True when creating the placeholder.

The array and dictionary representations are mutually exclusive, and you cannot set dict_keys alongside shape/ndim. Doing so will lead to an exception.

Attributes:

  • name (str): A name of the placeholder.

  • dtype (DataType, optional): The data type (eg. DataType.INT or DataType.FLOAT) of the placeholder.

  • ndim (int): The number of dimensions of the placeholder.

  • shape (tuple of Optional[Expression], optional): The (partial) shape of the placeholder if given.

  • jagged (boolean, defaut: False): True if the placeholder will be treated as a jagged array in random data generation. Ignored for scalars.

  • dict_keys (DictKeySpec): The specification of dictionary keys if the placeholder is a dictionary type.

  • partial_dict (bool, default: False): True if the placeholder is a partial dictionary. Ignored if dict_keys is not given.

  • description (str, optional): A description for user reference.

Raises:

  • TypeError: Raises if set a float value to ndim.

  • OverflowError: Raises if set a negative value to ndim.

Examples: Create a scalar (or ndim is 0) placeholder whose name is “a”.

import jijmodeling as jm
problem = jm.Problem("example")
a = problem.Placeholder("a", dtype=float)

Create a 2-dimensional integer placeholder whose name is “m”.

import jijmodeling as jm
problem = jm.Problem("example")
m = problem.Integer("m", ndim=2)

Create a 1-dimensional natural number placeholder with the index of 123.

>>> import jijmodeling as jm
>>> problem = jm.Problem("example")
>>> a = problem.Natural("a", ndim=2)
>>> a[123]
Expression(a[123])

__add__(rhs: ExpressionLike) Expression
__and__(rhs: ExpressionLike) Expression
__eq__(other: Any) Expression
__ge__(other: Any) Expression
__getitem__(subscripts: Any) Expression
__gt__(other: Any) Expression
__iter__() Any
__le__(other: Any) Expression
__lt__(other: Any) Expression
__mod__(rhs: ExpressionLike) Expression
__mul__(rhs: ExpressionLike) Expression
__ne__(other: Any) Expression
__neg__() Expression
__or__(rhs: ExpressionLike) Expression
__pow__(exponent: Any, modulo: Optional[Any] = None) Expression
__radd__(lhs: ExpressionLike) Expression
__rand__(lhs: ExpressionLike) Expression
__repr__() str
__rmod__(lhs: ExpressionLike) Expression
__rmul__(lhs: ExpressionLike) Expression
__ror__(lhs: ExpressionLike) Expression
__rpow__(base: Any, modulo: Optional[Any] = None) Expression
__rsub__(lhs: ExpressionLike) Expression
__rtruediv__(lhs: ExpressionLike) Expression
__rxor__(lhs: ExpressionLike) Expression
__sub__(rhs: ExpressionLike) Expression
__truediv__(rhs: ExpressionLike) Expression
__xor__(rhs: ExpressionLike) Expression
_repr_latex_() str
abs() Expression

Returns an expression representing the absolute value of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acos() Expression

Returns an expression representing the arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

acosh() Expression

Returns an expression representing the hyperbolic arccosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asin() Expression

Returns an expression representing the arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

asinh() Expression

Returns an expression representing the hyperbolic arcsine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atan() Expression

Returns an expression representing the arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

atanh() Expression

Returns an expression representing the hyperbolic arctangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

bnot() Expression
ceil() Expression

Returns an expression which rounds down to the nearest whole number.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cos() Expression

Returns an expression representing the cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

cosh() Expression

Returns an expression representing the hyperbolic cosine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

diff(rhs: ExpressionLike) Expression
enumerate() Expression

Enumerate elements of a set-like collection with 0-based indices.

Returns a set of (index, element) tuples, similar to Python’s built-in enumerate() function.

Parameters: operand : Expression A set-like expression to enumerate.

Returns: Expression A set expression where each element is a tuple of (index, original_element).

exp() Expression

Returns an expression representing the application of the exponential function on the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

filter(predicate: ExpressionFunction) Expression

Creates an expression that filters the values of this sequence.

predicate will be called on each element in self. The resulting expression represents only the values for which predicate is true.

This is an alternative to jijmodeling.filter() which allows you to place the indexing expression first.

This is often useful when trying to create summations which only include a subset of potential indices.The resulting expression is usually used as the basis for jijmodeling.map(), jijmodeling.sum(), etc., or a method equivalent.

Examples:

Using only variables with even indices as part of a constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> even_xs = N.filter(lambda i: i % 2 == 0).map(lambda i: x[i])
>>> problem += problem.Constraint("constr", even_xs.sum() <= 10)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=LESS_THAN_EQUAL, left=sum(N.filter(lambda i: i % 2 == 0).map(lambda (i: natural): x[i])), right=10, shape=Scalar(Natural)),],})

Using only non-diagonal indices of an NxN matrix as part of a constraint, using the method version of filter.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> non_diagonals = jm.product(N, N).filter(lambda i, j: i != j)
>>> problem += problem.Constraint("constr", lambda i, j: W[i, j] * x[i, j] >= 0, domain=non_diagonals)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", , lambda (i, j): W[i, j] * x[i, j] >= 0, domain=set((N, N)).filter(lambda (i, j): i != j)),],})

flat_map(func: ExpressionFunction) Expression

Creates an expression which works like map(), but flattens nested structure.

This is an alternative to flat_map() which allows you to place the indexing expression first.

map is useful when func returns scalar values, but in some situations one wants to write a func that returns other mappings/sequences instead. That is where flat_map should be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced with sum(), etc.)

You can also compare flat_map to a nested for-loop, or a generator expression that uses two for clauses. Indeed when using the decorated API (see tutorials or @Problem.update), you can use a generator expression-like syntax instead.

Examples:

Using only non-diagonal indices of an NxN matrix.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.BinaryVar("x", shape=(N, N))
>>> W = problem.Float("W", shape=(N, N))
>>> objective = N.flat_map(
...    lambda i: N.filter(lambda j: i != j).map(lambda j: W[i, j] * x[i, j])
... ).sum()
>>> problem += objective
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(N.flat_map(lambda (i: natural): N.filter(lambda j: i != j).map(lambda (j: natural): W[i, j] * x[i, j]))), constraints=[])

floor() Expression
indices() Expression

Get the set of indices of given array or jagged array.

Will throw type error when called on non-array type.

items() Expression

Returns an expression representing this object’s (key,value) pairs.

In other words, this is the JijModeling equivalent of the items() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.keys() and Expression.values().

Examples: Simple matching of weights to their respective variables, as an alternative to just using keys() or the CategoryLabel:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> weights = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=I)
>>> problem += jm.sum(weights.items(), lambda i, w: w * x[i])
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.items().map(lambda ((i, w): Tuple[CategoryLabel("I"), float]): w * x[i])), constraints=[])

Same as above, but using the decorated API:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> @problem.update
... def _(problem):
...     I = problem.CategoryLabel()
...     W = problem.Float(dict_keys=I)
...     x = problem.BinaryVar(dict_keys=I)
...     problem += jm.sum(w * x[i] for i, w in W.items())
>>> problem
Problem(name="MyProblem", ...)

keys() Expression

Returns an expression representing this dictionary-like object’s keys.

In other words, this is the JijModeling equivalent of the keys() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.values() and Expression.items().

Examples: Refer to a dictionary-like placeholder’s keys when creating other objects or writing summations:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> W = problem.Float("W", dict_keys=I)
>>> x = problem.BinaryVar("x", dict_keys=W.keys())
>>> problem += jm.sum(W.keys(), lambda i: W[i] * x[i])
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.keys().map(lambda (i: CategoryLabel("I")): W[i] * x[i])), constraints=[])
len_at(axis: int, latex: Optional[str] = None) Expression

Returns an expression representing the length (number of values) a placeholder has at a given dimension (0-indexed).

This can be used, for example, when trying to match the shape of an object to the number of values in an array.

Examples

import jijmodeling as jm
problem = jm.Problem("MyProblem")
V = problem.Integer(name="V", ndim=1)
N = V.len_at(0)
x = problem.BinaryVar("x", shape=(N,))
ln() Expression

Returns an expression representing the natural logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log10() Expression

Returns an expression representing the decimal logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

log2() Expression

Returns an expression representing the binary logarithm of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

map(func: ExpressionFunction) Expression

Creates an expression that maps the values in self to func.

This is an alternative to jijmodeling.map() which allows you to place the indexing expression first.

When called on valid scalar scalars, each number from 0 to this self will be passed to func. When called on a sequence expression (eg. a 1-dimensional placeholder, or the result of functions like jijmodeling.product() or jijmodeling.items()), each element in the sequence is passed to func.

This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like Placeholders and DecisionVars. The resulting expression is then usually passed to a reducer, like jijmodeling.sum() (or Expression.sum() is called on it), to form part of a constraint or the objective function.

Examples:

Indexing by values from 0 to N. In this example we define N as the length of another placeholder, but a scalar Natural placeholder would work as well.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += N.map(lambda i: W[i] * x[i]).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W.len_at(0).map(lambda (i: natural): W[i] * x[i])), constraints=[])

Indexing by specific values from instance data. In this example only the indices present in C in the instance data will be used in this constraint.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> C = problem.Natural("C", ndim=1)
>>> problem += problem.Constraint("constr", C.map(lambda i: x[i]).sum() <= 100)
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=0, constraints={constr: [Constraint(name="constr", sense=LESS_THAN_EQUAL, left=sum(C.map(lambda (i: natural): x[i])), right=100, shape=Scalar(Integer)),],})

max() Expression
max(rhs: ExpressionLike) Expression

Creates an expression which refers to the largest value in self.

This method works only on valid sequence expressions, where the resulting expression is a scalar representing the largest among all values in the sequence.

min() Expression
min(rhs: ExpressionLike) Expression

Creates an expression which refers to the smallest value in self.

This method works only on valid sequence expressions, where the resulting expression is a scalar representing the smallest among all values in the sequence.

ndenumerate() Expression

Enumerate elements of a tensor or jagged array with multi-dimensional indices.

Returns an array where each element is paired with its multi-dimensional index as a tuple of natural numbers.

Parameters: operand : Expression A tensor or jagged array expression to enumerate.

Returns: Expression An array expression where each element is a tuple of (index_tuple, original_element), where index_tuple is a tuple of natural numbers representing the multi-dimensional position.

prod(axis: ExpressionLike | int | Sequence[ExpressionLike] | Sequence[int] = None) Expression

Creates an expression representing the multiplication of self.

This is an alternative to using jijmodeling.prod(), where a method call on an expression may be more convenient/readable.

If self isn’t a valid sequence which can be multiplied, you will get an error when the resulting expression is added to a Problem and is type-checked.

The optional axis parameter allows you to specify axes of a multi-dimensional expression across which to perform the operation.

Examples:

Simple product of decision variables

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> problem += x.prod()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=prod(x), constraints=[])

roll(shift: Any, axis: Optional[int] = None) Expression
rows() Expression

Creates a sequence over the rows of this multi-dimensional array expression.

That is, each element will be a whole row (itself containing multiple values), which can then be operated on like other sequences (eg. using jijmodeling.sum() or jijmodeling.map()).

If the array is 3-dimensional or higher, rows will iterate over the first dimension/axis. For example, in a 3D matrix, the first element would be a 2D matrix representing all values x[0, _, _]

Examples

Create an objective function that multiplies each variable in a row, and then sums each row. In this case we have a 2x3 matrix, so the final expression is x[0, 0] * x[0, 1] * x[0, 2] + x[1, 0] * x[1, 1] * x[1, 2]. Using placeholders instead of literals in shape would allow this to be written for matrices of arbitrary size.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> d = problem.BinaryVar("d", shape=(2, 3))
>>> problem += d.rows().map(lambda xs: xs.prod()).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(d.rows().map(lambda (xs: Array[3; binary!]): prod(xs))), constraints=[])

If the number of elements in the row can be guaranteed, the elements can be destructured as separate arguments in a lambda expression:

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> V = problem.Natural("V")
>>> E = problem.Natural("E", shape=(N, 2))
>>> x = problem.BinaryVar("x", shape=V)
>>> problem += jm.map(lambda i, j: x[i] * x[j], E.rows()).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(E.rows().map(lambda ((i, j): Array[2; natural]): x[i] * x[j])), constraints=[])

sin() Expression

Returns an expression representing the sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sinh() Expression

Returns an expression representing the hyperbolic sine of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sqrt() Expression

Returns an expression representing the square root of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

sum(axis: ExpressionLike | int | Sequence[ExpressionLike] | Sequence[int] = None) Expression

Creates an expression representing the summation of self.

This is an alternative to using jijmodeling.sum(), where a method call on an expression may be more convenient/readable.

If self isn’t a valid sequence which can be summed, you will get an error when the resulting expression is added to a Problem and is type-checked.

The optional axis parameter allows you to specify axes of a multi-dimensional expression across which to perform the operation.

Examples:

Simple sum of decision variables.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Natural("N")
>>> x = problem.IntegerVar("x", shape=N, lower_bound=0, upper_bound=10)
>>> problem += x.sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(x), constraints=[])

Performing a weighted sum. Note that this sort of usage may lead to errors when the shapes don’t match. In this case we guarantee that x has the same shape as W through its definition.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> W = problem.Float("W", ndim=1)
>>> N = W.len_at(0)
>>> x = problem.BinaryVar("x", shape=N)
>>> problem += (W * x).sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(W * x), constraints=[])

tan() Expression

Returns an expression representing the tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

tanh() Expression

Returns an expression representing the hyperbolic tangent of the given expression.

Note that expr must be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.

unique() Expression

Remove duplicate elements from this array-like expression, preserving order.

Returns: Expression A set expression with duplicates removed.

values() Expression

Returns an expression representing this dictionary-like object’s values.

In other words, this is the JijModeling equivalent of the values() method on Python dictionaries, used when creating JijModeling expressions.

While it’s possible to call this on any Expression, this is intended for dictionary-like Placeholders and DecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to a Problem and is type-checked.

See also Expression.keys() and Expression.items().

Examples: Defining a simple objective function which just sums a dictionary-based decision variable.

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> I = problem.CategoryLabel("I")
>>> x = problem.IntegerVar("x", dict_keys=I, lower_bound=0, upper_bound=100)
>>> problem += x.values().sum()
>>> problem
Problem(name="MyProblem", sense=MINIMIZE, objective=sum(x.values()), constraints=[])
class Problem

A class for creating an optimization problem.

Attributes:

  • name (str): A name of the optimization problem.

  • sense (ProblemSense): Sense of the optimization problem.

  • objective: The objective function of the optimization problem.

  • constraints (dict): A dictionary that stores constraints.

    • A key is the name of a constraint and the value is the constraint object.

Args:

  • name (str): A name of the optimization problem.

  • sense (optional): Sense of the optimization problem. Defaults to ProblemSense.MINIMIZE.

  • description (str, optional): An optional description of the problem, for user reference.

Binary(name: str, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a binary number in this problem’s namespace.

A shorthand for Problem.Placeholder(dtype=DataType.BINARY), provided for clarity and convenience. See Problem.Placeholder for more details on placeholders.

BinaryVar(name: str, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines a binary decision variable and registers it to the problem namespace. See Problem.DecisionVar for more details.

A shorthand for Problem.DecisionVariable(dtype=DecisionVarKind.BINARY, lower_bound=0, upper_bound=1), provided for clarity and convenience.

Args

  • name (str): A name of the binary variable.

  • shape (list | tuple): A sequence with the size of each dimension of the binary variable. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this variable represents a dictionary-like structure with keys dict_keys.

  • latex (str, optional): A LaTeX-name of the binary variable to be represented in Jupyter notebook.

    • It is set to name by default.

  • description (str, optional): A description of the binary variable.

CategoryLabel(name: str, latex: Optional[str] = None, description: Optional[str] = None) CategoryLabel

Add a new opaque category label to the namespace.

A category label corresponds to a set of labels representing some specific category (e.g. the name of percels, or the ids of factors, etc). A value of category label is treated opaque in JijModeling, and can only be tested for equality / non-equality and used as keys in dictionary-like structures.

CategoryLabel objects can be created via Problem.CategoryLabel(). The concrete values should be given in instance_data dictionary together with placeholder values when creating a Compiler object or in Problem.eval(). In instance_data, category label should be given a list of either strings or integers.

Args

  • name (str): The name of the category label.

  • latex (str, optional): An optional LaTeX representation to be used in Jupyter notebook.

    • When not provided, name is used by default.

  • description (str, optional): An optional description for user reference.

Constraint(name: str, expression: ExpressionLike, description: Optional[str] = None) Constraint
Constraint(name: str, expression: ExpressionFunction, domain: ExpressionLike, description: Optional[str] = None) Constraint

Constructs Constraint object from comparison expression, WITHOUT registering it to the problem. Use += operator to register the constraint to the problem.

ContinuousVar(name: str, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines a continuous decision variable and registers it to the problem namespace. See Problem.DecisionVar for more details.

This is shorthand for problem.DecisionVariable(dtype=DecisionVarKind.CONTINUOUS).

Args

  • name (str): A name of the continuous variable.

  • shape (list | tuple): A sequence with the size of each dimension of the continuous variable. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this variable represents a dictionary-like structure with keys dict_keys.

  • lower_bound: The lower bound of the variable.

  • upper_bound: The upper bound of the variable.

  • latex (str, optional): A LaTeX-name of the continuous variable to be represented in Jupyter notebook.

    • It is set to name by default.

  • description (str, optional): A description of the continuous variable.

Raises

ModelingError: Raises if a bound is a Placeholder or Subscript object whose ndim is neither 0 nor the same value as ndim of the continuous variable.

DecisionVar(name: str, kind: DecisionVarKind, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines a DecisionVar and registers it to the problem namespace.

Decision variables can be scalars, multi-dimensional arrays (eg. representing arrays and matrices of variables), or total dictionaries. Variables must have a DecisionVarKind (such as BINARY, INTEGER, CONTINUOUS), as well as defined lower and upper bounds.

See DecisionVar documentation for more general info on decision variables, their representation, and bounds.

We recommend using alternative convenience methods which predefine the decision variable’s kind, such as Problem.IntegerVar() for integers, or Problem.BinaryVar() for binary variables.

Representation

Depending on the arguments described below, the representation of the decision variable will be determined as follows:

  1. If none of shape or dict_keys is provided, or shape is (), DecisionVar will be considered as a scalar value (= array of dimension 0).

  2. If shape is provided and dict_keys is not provided, DecisionVar will be considered as a multi-dimensional array with fixed shape.

  3. If dict_keys is provided without shape, DecisionVar will be considered as a dictionary-like structure with keys specified by dict_keys.

  4. Otherwise, an error is raised.

Args

  • name (str): A name for the binary variable.

  • kind (DecisionVarKind): A kind of the decision variable.

  • shape (list | tuple): A sequence with the size of each dimension of the variable. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this variable represents a dictionary-like structure with keys dict_keys.

  • lower_bound and upper_bound (jijmodeling.Expression): A lower and upper bounds of the variable.

  • kind (DecisionVarKind): The kind of the decision variable.

  • latex (str, optional): An optional LaTeX representation to be used in Jupyter notebook.

    • It is set to be the same as name by default.

  • description (str, optional): An optional description, for user reference.

Examples

Create a scalar binary variable whose name is “z”.

import jijmodeling as jm
problem = jm.Problem("my_problem")
z = problem.DecisionVar("z", kind=jm.DecisionVarKind.BINARY, lower_bound=0, upper_bound=1)

Create a 2-dimensional binary variable whose name is “x” and has a 2x2 shape.

import jijmodeling as jm
problem = jm.Problem("my_problem")
x = problem.BinaryVar("x", shape=[2, 2])

Create a 1-dimensional binary variable with the index of 123.

>>> import jijmodeling as jm
>>> problem = jm.Problem("my_problem")
>>> x = problem.BinaryVar("x", shape=[124])
>>> x[123]
Expression(x[123])

DependentVar(name: str, definition: ExpressionLike, description: Optional[str] = None, latex: Optional[str] = None) DependentVar

Defines a dependent variable and registers it to the problem namespace.

Dependent variables are expressions defined in terms of other variables (placeholders, decision variables, or other dependent variables). They provide a way to give names to commonly-used subexpressions, improving model readability and reducing duplication.

Unlike decision variables, dependent variables are not optimized by the solver - they’re computed from other variables. Unlike placeholders, their values are determined by the model structure rather than instance data.

Args

  • name (str): The name of the dependent variable.

  • definition (Expression): The expression that defines this dependent variable.

  • description (str, optional): An optional description for user reference.

  • latex (str, optional): An optional custom LaTeX representation.

    • When not provided, name is used by default.

Returns

DependentVar: The created dependent variable object.

Examples

Define a dependent variable that squares a placeholder:

import jijmodeling as jm
problem = jm.Problem("example")
x = problem.Float("x")
x_squared = problem.DependentVar("x_squared", x * x)
Dim(name: str, ndim: Optional[int] = 0, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a natural number in this problem’s namespace.

This is just a shorthand for Problem.Natural(ndim=0) and effectively the same as any other natural placeholder for practical purposes. The use of Dim is recommended just for clarity when defining a placeholder which will be used to define the length of multi-dimensional objects.

See Placeholder for more details on placeholders.

Float(name: str, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a floating-point (real) number in this problem’s namespace.

A shorthand for Problem.Placeholder(dtype=DataType.FLOAT), provided for clarity and convenience. See Placeholder for more details on placeholders.

Graph(name: str, dtype: DataType | type | tuple = DataType.NATURAL, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

A placeholder expressing a directed graph (without edge weights), represented by a 1-dimensional array of tuples.

A shorthand for Problem.Placeholder(dtype=(vertex, vertex), ndim=1). By default vertex is DataType.Natural but can be specified.

Integer(name: str, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing an integer in this problem’s namespace.

A shorthand for Problem.Placeholder(dtype=DataType.INTEGER), provided for clarity and convenience. See Placeholder for more details on placeholders.

IntegerVar(name: str, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines an integer decision variable and registers it to the problem namespace. See Problem.DecisionVar for more details.

This is shorthand for Problem.DecisionVariable(kind=DecisionVarKind.INTEGER).

Args

  • name (`str): A name of the integer variable.

  • shape (list | tuple): A sequence with the size of each dimension of the integer variable. Defaults to an empty tuple (a scalar value).

    • Each item in shape must be a valid expression evaluating to a non-negative scalar.

  • dict_keys (tuple[Expression, ...], optional): If provided, specifies that this variable represents a dictionary-like structure with keys dict_keys.

  • lower_bound: The lower bound of the variable.

  • upper_bound: The upper bound of the variable.

  • latex (str, optional): A LaTeX-name of the integer variable to be represented in Jupyter notebook.

    • It is set to name by default.

  • description (str, optional): A description of the integer variable.

Raises

ModelingError: Raises if a bound is a Placeholder or Subscript object whose ndim is neither 0 nor the same value as ndim of the integer variable.

Length(name: str, ndim: Optional[int] = 0, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a natural number in this problem’s namespace.

This is just a shorthand for Problem.Natural(ndim=0) and effectively the same as any other natural placeholder for practical purposes. The use of Length is recommended just for clarity when defining a placeholder which will be used to define the length of multi-dimensional objects.

See Placeholder for more details on placeholders.

Natural(name: str, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

Defines a Placeholder representing a natural number in this problem’s namespace.

A shorthand for Problem.Placeholder(dtype=DataType.NATURAL), provided for clarity and convenience. See Placeholder for more details on placeholders.

PartialDict(name: str, dtype: DataType | type | tuple, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

A shorthand for creating a partial dictionary placeholder with key type

Placeholder(name: str, dtype: DataType | type | tuple, dict_keys: DataType | type | ExpressionLike, description: Optional[str] = None, latex: Optional[str] = None) Placeholder
Placeholder(name: str, dtype: DataType | type | tuple, dict_keys: DataType | type | ExpressionLike, partial_dict: Literal[False], description: Optional[str] = None, latex: Optional[str] = None) Placeholder
Placeholder(name: str, dtype: DataType | type | tuple, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple, partial_dict: Literal[True], description: Optional[str] = None, latex: Optional[str] = None) Placeholder
Placeholder(name: str, dtype: DataType | type | tuple, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple, partial_dict: bool, description: Optional[str] = None, latex: Optional[str] = None) Placeholder
Placeholder(name: str, dtype: DataType | type | tuple, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, description: Optional[str] = None, latex: Optional[str] = None) Placeholder
Placeholder(name: str, dtype: DataType | type | tuple, ndim: Optional[int] = None, shape: Optional[ExpressionLike] | Sequence[Optional[ExpressionLike]] = None, jagged: bool = False, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple = None, partial_dict: Optional[bool] = None, description: Optional[str] = None, latex: Optional[str] = None) Placeholder
SemiContinuousVar(name: str, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar
SemiIntegerVar(name: str, shape: ExpressionLike | Sequence[ExpressionLike] = None, dict_keys: DataType | type | ExpressionLike = None, lower_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, upper_bound: ExpressionLike | Sequence[ExpressionLike] | ExpressionFunction, latex: Optional[str] = None, description: Optional[str] = None) DecisionVar

Defines a semi-integer decision variable and registers it to the problem namespace. See DecisionVar for more details.

This is shorthand for Problem.DecisionVar(kind=DecisionVarKind.SEMI_INTEGER).

TotalDict(name: str, dtype: DataType | type | tuple, dict_keys: DataType | type | CategoryLabel | ExpressionLike | tuple, latex: Optional[str] = None, description: Optional[str] = None) Placeholder

A shorthand for creating a total dictionary placeholder with key type

__iadd__(other: Constraint) Problem
__iadd__(other: ExpressionLike) Problem

Add constraint to the problem.

__new__(name: str, sense: ProblemSense = ProblemSense.MINIMIZE, description: Optional[str] = None) Problem
__repr__() str
_repr_latex_() str
define(name: str, sense: ProblemSense = ProblemSense.MINIMIZE, description: Optional[str] = None) Callable[[Callable[[DecoratedProblem], Any]], Problem]

A function decorator to fully define a Problem using the decorated API.

This decorator takes as arguments the same parameters as a Problem constructor: a name, optional ProblemSense (defaults to minimize), and an optional description.

This must decorate a function that takes DecoratedProblem as the only argument and returns None. The resulting Problem will be the value of the variable with the decorated function’s name.

Example

>>> import jijmodeling as jm
>>> @jm.Problem.define("Knapsack Problem", sense=jm.ProblemSense.MAXIMIZE)
>>> def problem(problem: jm.DecoratedProblem):
>>>     w = problem.Float(ndim=1, description="Weights of the items")
>>>     N = w.len_at(0)
>>>     v = problem.Float(ndim=1, description="Values of the items")
>>>     W = problem.Float(description="Total weight")
>>>     x = problem.BinaryVar(shape=(N,), description="Selected items")
>>>
>>>     problem += problem.Constraint("weight", jm.sum(w * x) <= W)
>>>     problem += jm.sum(v * x)
>>>
>>> assert isinstance(problem, jm.Problem)
>>> w_data = [10, 20, 30]
>>> v_data = [60, 100, 120]
>>> instance_data = {"w": w_data, "v": v_data, "W": 50}
>>> instance = problem.eval(instance_data)
eval(instance_data: str | int | float | NDArray[numpy.float64] | NDArray[numpy.int64] | list | dict | str, prune_unused_dec_vars: bool = False, constraint_detection: ConstraintDetectionConfig | bool = None) Instance

Compiles and evaluates the problem given the specified instance data, returning an OMMX instance.

A short-hand of Compiler.from_problem(self, data).eval_problem(self).

Args

  • instance_data (dict[str, InstanceValue]): A dictionary mapping placeholder and category label names to their corresponding values for this instance. See Compiler for more details on the expected format of instance_data.

  • prune_unused_dec_vars (bool, optional): If True, only include decision variables that appear in the objective or constraints. If False (default), include all declared decision variables regardless of usage.

  • constraint_detection (Optional[ConstraintDetectionConfig]): Configuration for automatic constraint hint detection. If None, the default configuration is used. Pass false or ConstraintDetectionConfig.disable to disable constraint hint detection. See Compiler and ConstraintDetectionConfig for details.

from_protobuf(buf: bytes) Problem

Constructs a problem by deserializing a sequence of bytes as a protobuf message.

generate_random_dataset(_default: Any, _options: Any, _seed: Optional[int]) Any

Generates a dictionary of random InstanceDataValue for a given problem. To generate ommx.v1.Instance object directly, use InstanceDataValue.generate_random_instance instead.

Args

  • options (optional): a dictionary of range parameters for each separate placeholders. The key must be the name of the placeholder and the value must be range parameter (as described in “Range Parameters and Range Syntax” below).

  • default (optional): default range parameters for placeholders which is not specified in options.

  • seed (optional): seed for random number generation.

Returns

dict: The dictionary from the name of placeholders to the generated InstanceDataValue objects. To be fed to Interpreter.eval_problem.

Range Parameters and Range Syntax

A range parameter is a dictionary consisting of the following fields:

  • size (optional): interval of natural numbers for the size of each array dimension (default: range(1, 6))

  • value (optional): interval of real numbers for the value of each array element (default: range(-1.0, 1.0) - a uniform distribution on a closed interval [1.0,1.0][-1.0, 1.0]).

Example range parameter config:

{"size": range(2, 10), "value": jm.range.value.closed(100.0, 200.0)}

Intervals are expressed as a range object. Currently, the following syntax is supported for range objects:

  1. Direct value of type int or float - it corresponds to a singleton interval [a,a]={a}[a, a] = \{a\}. In random generation context, this just means a constant fixed value.

  2. Use the functions from jijmodeling.range, jijmodeling.range.size, or jijmodeling.range.value modules.

    • Use functions from jij.modeling.range.size to specify (non-negative) integer intervals, and jij.modeling.range.value for real intervals. jij.modeling.range dynamically determines the type of the range based on the input.

    • These three modules provides the following combinators (see the module documents for more details.): - closed(a, b): a closed interval [a,b][a, b] - open(a, b): an open interval (a,b)(a, b) - closed_open(a, b): an upper half-open interval [a,b)[a, b) - open_closed(a, b): a lower half-open interval (a,b](a, b] - greater_than(a): an open interval (a,)(a, \infty) - at_least(a): a closed interval [a,)[a, \infty) - less_than(a): an open interval (,a)(-\infty, a) - at_most(a): a closed interval (,a](-\infty, a]

  3. Use range builtin function: this is equivalent to jijmodeling.range.value.closed_open(a, b).

    • Any python range object with step = 1 can be used as a size range; otherwise it results in runtime error.

  4. Use a tuple: raw tuple (a, b) is equivalent to jijmodeling.range.closed_open(a, b) if a and b are either int or float.

    • You can also use bound object as a tuple component; in such case, both tuple components must be one of the following:

      1. A string "Unbounded" means -\infty (in the first component) or \infty (the second).

      2. A dictionary {"Included": a} means the endpoint is inclusive.

      3. A dictionary {"Excluded": a} means the endpoint is exclusive.

    • Examples: - (1.2, 4) is equivalent to closed_open(1.2, 4), - (-1, {"Included": 1}) is equivalent to closed(-1, 1), - (-5, {"Excluded": 4}) is equivalent to closed_open(-5, 4) and built in function range(-5, 4), - ({"Excluded": 1}, {"Excluded": 2.5}) is equivalent to open(1, 2.5), - ({"Included": -1}, "Unbounded") is equivalent to at_least(-1). - (5, "Unbounded") is INVALID; 5 must be bound object.

  5. The range object: A dictionary of form {"start": lb, "end": ub}, where both lb and ub are the bound object described as above.

Examples

import jijmodeling as jm
import builtins
problem = jm.Problem("problem")
N = problem.Integer("N")
c = problem.Float("c", shape=(N,))
x = problem.BinaryVar("x", shape=(N,))
i = jm.Element("i", belong_to=N)
problem += jm.sum(i, c[i] * x[i])
inputs = problem.generate_random_dataset(
    options={
        'N': {"value": builtins.range(10, 20)},
        'c': {"value": jm.range.value.closed(-1.0, 1.0)}
         # You can also specify "size" for the range of jagged array dimension size.
    },
    seed=123 # omittable
)
assert set(inputs.keys()) == {"N", "c"}
inputs
# {'N': 11.0, 'c': array([ 0.93914459, -0.06511935, -0.7460324 , -0.32443706,  0.99981451,
#        -0.24407535,  0.31329469,  0.52206453, -0.1291936 ,  0.30443087,
#         0.53125838])}
generate_random_instance(_default: Any, _options: Any, _seed: Optional[int], _hints: Optional[Any]) Any

Generates random ommx.v1.Instance for a given problem. See also InstanceDataValue.generate_random_dataset.

Args

  • options (optional): a dictionary of range parameters for each separate placeholders. The key must be the name of the placeholder and the value must be range parameter (as described in “Range Parameters and Range Syntax” section in Problem.generate_random_dataset()).

  • default (optional): default range parameters for placeholders which is not specified in options.

  • seed (optional): seed for random number generation.

  • hints (optional): the hints to be detected during compilation see Interpreter.eval_problem for more details.

Returns

instance: The OMMX v1 instance object.

Examples

import jijmodeling as jm
import builtins
import ommx.v1
problem = jm.Problem("problem")
N = problem.Integer("N")
c = problem.Float("c", shape=(N,))
x = problem.BinaryVar("x", shape=(N,))
i = jm.Element("i", belong_to=N)
problem += jm.sum(i, c[i] * x[i])
instance = problem.generate_random_instance(
    options={
        'N': {"value": builtins.range(10, 20)},
        'c': {"value": jm.range.value.closed(-1.0, 1.0)}
    },
    seed=123
)
assert type(instance) is ommx.v1.Instance
get_problem_schema() dict

Returns the schema of the problem.

Returns

  • schema: The dictionary containing the schema of the problem.

infer(expr: ExpressionLike) Type

Infers the resulting type of an expression using this problem as a namespace.

This is mostly intended for testing purposes, and not as part of standard model writing.

Examples

>>> import jijmodeling as jm
>>> problem = jm.Problem("MyProblem")
>>> N = problem.Length(name="N")
>>> x = problem.BinaryVar("x", shape=(N,))
>>> y = problem.IntegerVar("y", shape=(N,), lower_bound=0,upper_bound=10)
>>> problem.infer(jm.sum(x))
binary!
>>> problem.infer(jm.sum(y))
int!

namespace() Namespace

Access to the internal Namespace associated with this problem.

Accessing this directly is not normally necessary for regular users.

to_protobuf() bytes

Serializes this problem into a protobuf byte message

type_of(name: str) Optional[Type]

Returns the type associated with a given name (eg. of a placeholder or decision variable).

This is mostly inteded for testing purposes, and not as part of standard model writing.

:raises ModelingError: If the name is undefined in this problem’s namespace.

update(func: Callable[[DecoratedProblem], Any]) DesugaredProblemBuilder

A function decorator to modify an existing Problem using the decorated API.

This must decorate a function that takes DecoratedProblem as the only argument and returns None. You can call update multiple times.

The given function will automatically be evaluated exactly once by the decocrator, so you DO NOT need to call it yourself.

Example

import jijmodeling as jm
problem = jm.Problem("Knapsack Problem", sense=jm.ProblemSense.MAXIMIZE)

@problem.update
def my_updater(problem: jm.DecoratedProblem):
    w = problem.Float(ndim=1, description="Weights of the items")
    N = w.len_at(0)
    v = problem.Float(ndim=1, description="Values of the items")
    W = problem.Float(description="Total weight")
    x = problem.BinaryVar(shape=(N,), description="Selected items")

    problem += problem.Constraint("weight", jm.sum(w * x) <= W)
    problem += jm.sum(v * x)

w_data = [10, 20, 30]
v_data = [60, 100, 120]
instance_data = {"w": w_data, "v": v_data, "W": 50}
instance = problem.eval(instance_data)
class ProblemSense

An optimization sense

Specifies whether the problem is a minization or maximization problem. Mostly used in the constructor for Problem, or obtained from an existing problem through Problem.sense()

MAXIMIZE
MINIMIZE
class ProtobufError
class Type
__eq__(other: object) bool
class TypeError

Type Aliases

type ExpressionFunction = Callable[[Expression], Expression] | Callable[[Expression, Expression], Expression] | Callable[[Expression, Expression, Expression], Expression] | Callable[[Expression, Expression, Expression, Expression], Expression] | Callable[[Expression, Expression, Expression, Expression, Expression], Expression]

Any function that takes one or more Expressions as input and returns an Expression. Due to the limitation of Python’s typing system, we define overloads for up to 5 arguments here, but you can accept more if needed.

type ExpressionLike = Expression | int | float | DecisionVar | DependentVar | CategoryLabel | Placeholder | list | tuple | ExpressionFunction | dict

Any type that can be converted to an Expression, including:

  • Expression itself,

  • Numeric values like int and float,

  • DecisionVar, DependentVar, and Placeholder, CategoryLabel, and

  • tuples, lists, and dictionaries of them.