jijmodeling
The JijModeling library. See official documentation for details.
Module Contents
Classes
Name |
Description |
|---|---|
A category label corresponds to a set of labels representing some specific category (e.g. the name o… |
|
A compiler that converts problems/expressions into OMMX instance/functions. |
|
A constraint in the mathematical optimization model. |
|
Configuration for automatic constraint hint detection during problem compilation. |
|
Name of constraint hits. To be used in ConstraintDetectionConfig.constraint_hints. |
|
Classification of a constraint based on the comparison used. |
|
The type of values in the instance data. |
|
A decision variable in a mathematical model. |
|
The type of values a decision variable may have. |
|
A variant of Problem that is only available in Decorator API provided by Problem.update. |
|
A dependent variable in a mathematical model. |
|
An expression used to compose mathematical models. |
|
A placeholder for instance-specific parameters. |
|
A class for creating an optimization problem. |
|
An optimization sense |
|
Functions
Name |
Description |
|---|---|
Returns an expression representing the absolute value of the given expression. |
|
Returns an expression representing the arccosine of the given expression. |
|
Returns an expression representing the hyperbolic arccosine of the given expression. |
|
Returns an expression representing the arcsine of the given expression. |
|
Returns an expression representing the hyperbolic arcsine of the given expression. |
|
Returns an expression representing the arctangent of the given expression. |
|
Returns an expression representing the hyperbolic arctangent of the given expression. |
|
Returns an expression which rounds down to the nearest whole number. |
|
Returns an expression representing the cosine of the given expression. |
|
Returns an expression representing the hyperbolic cosine of the given expression. |
|
Get the count/size of a category label. |
|
Enumerate elements of a set-like collection with 0-based indices. |
|
Returns an expression representing the application of the exponential function on the given expressi… |
|
Creates an expression that filters the values of another sequence expression. |
|
Creates an expression which works like {py:func}jijmodeling.map, but flattens nested structure. |
|
Deserializes a sequence of bytes as protobuf message encoding a {py:class}~jijmodeling.Problem. |
|
Get the set of indices of given array or jagged array. |
|
Return true if src and dst are the same object defined by Jijmodeling. |
|
Returns an expression representing the (key,value) pairs of a |
|
Returns an expression representing the keys of a dictionary-like |
|
Returns an expression representing the natural logarithm of the given expression. |
|
Returns an expression representing the decimal logarithm of the given expression. |
|
Returns an expression representing the binary logarithm of the given expression. |
|
Creates an expression that maps func to a sequence of values. |
|
Creates an expression that refers to the largest value among lhs and rhs. |
|
Creates an expression that refers to the smallest value among lhs and rhs. |
|
Enumerate elements of a tensor or jagged array with multi-dimensional indices. |
|
Comprehension syntax for {py:func}jijmodeling.prod, for use with decorated API. |
|
Returns an expression representing the cartesian product of two {py:class}~jijmodeling.Expressions. |
|
Creates a sequence over the rows of a multi-dimensional array expression. |
|
Returns an expression representing the sine of the given expression. |
|
Returns an expression representing the hyperbolic sine of the given expression. |
|
Returns an expression representing the square root of the given expression. |
|
Comprehension syntax for {py:func}jijmodeling.sum for use with decorated API. |
|
Returns an expression representing the tangent of the given expression. |
|
Returns an expression representing the hyperbolic tangent of the given expression. |
|
Serializes a {py:class}~jijmodeling.Problem into a protobuf byte message |
|
Remove duplicate elements from a set, preserving the order of first occurrences. |
|
Returns an expression representing the values of a dictionary-like |
|
Type Aliases
Name |
Description |
|---|---|
Any function that takes one or more Expressions as input and returns an Expression. |
|
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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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 :
ExpressionA set-like expression to enumerate.Returns:
ExpressionA 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
exprmust 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.
predicatewill be called on each element inoperand. The resulting expression represents only the values for whichpredicateis 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.filterandExpression.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.mapis useful whenfuncreturns scalar values, but in some situations one wants to write afuncthat returns other mappings/sequences instead. That is whereflat_mapshould be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced withjijmodeling.sum(), etc.)You can also compare
flat_mapto a nested for-loop, or a generator expression that uses twoforclauses. Indeed when using the decorated API (see tutorials orProblem.update()), you can use a generator expression-like syntax instead.See also the method equivalents:
Placeholder.flat_map(),DecisionVar.flat_map()andExpression.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
trueifsrcanddstare 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:trueifsrcanddstis the same object. Otherwisefalse.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 ifsrcanddstare of different types which are not iterablecalled on a type not defined by Jijmodeling (e.g.
str)
Note: This function does not check the following attributes:
descriptionlatex
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-likeExpression.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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Placeholder.items(),DecisionVar.items(), andExpression.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, usejijmodeling.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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Placeholder.keys(),DecisionVar.keys(), andExpression.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, usejijmodeling.items()or its method equivalents instead.
- ln(expr: ExpressionLike) Expression
Returns an expression representing the natural logarithm of the given expression.
Note that
exprmust 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
exprmust 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
exprmust 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
functo a sequence of values.This parallels python’s built-in
map()function, but made to work with and create JijModeling expressions.If
argis a number literal or scalar placeholder, each number from 0 toargwill be passed tofunc. Ifargis a sequence expression (eg. a 1-dimensional placeholder, or the result of functions likejijmodeling.product()orjijmodeling.items()), each element in the sequence is passed tofunc.This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like
Placeholders andDecisionVars. The resulting expression is then usually passed to a reducer, likejijmodeling.sum()(orExpression.sum()is called on it), to form part of a constraint or the objective function.See also the method equivalents:
Placeholder.map(),DecisionVar.map()andExpression.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
Cin 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
lhsandrhs.See also the method equivalents
Placeholder.max(),DecisionVar.max(), andExpression.max().
- min(operand: ExpressionLike) Expression
- min(lhs: ExpressionLike, rhs: ExpressionLike) Expression
Creates an expression that refers to the smallest value among
lhsandrhs.See also the method equivalents
Placeholder.min(),DecisionVar.min(), andExpression.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 :
ExpressionA tensor or jagged array expression to enumerate.Returns:
ExpressionAn 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, usingforclauses to mark the index.NOTE: do not confuse with
jijmodeling.product(). This is a sequence multiplication (like capital-PI notation).productis 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 bemap()ped to access these pairs of values, orfilter()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()ormap()).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()andExpression.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 inshapewould 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
exprmust 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
exprmust 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
exprmust 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, usingforclauses 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
exprmust 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
exprmust be a scalar. Also, evaluating models where this operation is performed on decision variables is currently unsupported.
- 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 :
ExpressionA set expression from which to remove duplicates.Returns:
ExpressionA 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Placeholder.values(),DecisionVar.values(), andExpression.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, usejijmodeling.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.
CategoryLabelobjects can be created viaProblem.CategoryLabel(). The concrete values should be given ininstance_datadictionary together with placeholder values when creating aCompilerobject or ineval(). Ininstance_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.
- 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.
Compilerobjects can be created via constructor ofCompiler.from_problem()class method. In this section we explain the usage ofCompilerconstructor.Args:
namespace(Namespace): The namespace containing decision variables and other symbols used in the problem. (Typically obtained viaProblem.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:
a scalar (integer or floating number point) value,
a tuple of scalars,
a (nested) list of (1) or (2).
a
ndarray.arrayobject fromnumpypackage withdtypefloat or int.
For category labels, you can pass a list of strings or integers representing the concrete labels.
Returns: A
Compilerobject.Raises: Raises
ModelingErrorwhen there is missing or redundant placeholder(s) or category label(s) ininstance_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): IfTrue, only include decision variables that appear in the objective or constraints. IfFalse(default), include all declared decision variables regardless of usage.constraint_detection (
Optional[ConstraintDetectionConfig]): Configuration for automatic constraint hint detection. IfNone, the default configuration is used. PassfalseorConstraintDetectionConfig.disable()to disable constraint hint detection. SeeConstraintDetectionConfigfor details.
-
from_problem(problem: Problem, instance_data: str | int | float | NDArray[
numpy.float64] | NDArray[numpy.int64] | list | dict | str) Compiler Creates a
Compilerobject from aProblemobject and instance data.See
Compilerconstructor for details aboutinstance_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,
Constraintsexist within aProblem’s namespace, and cannot be defined outside of a problem. So to define a constraint, you must useProblem.Constraint()on aProbleminstance.Created
Constraintsmust 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. SeeConstraintHintNamefor available hints.max_iter(Optional[int]): Maximum number of iterations for constraint hint detection. IfNone, it tries to iterate until fixpoint. Default:10max_hints(Optional[int]): Maximum number of hints to be detected. IfNone, there is no limit. Default:Nonematch_limit(int): Fine-tuning parameter to control simplification during constraint hint detection: the limit of the number of a single rule before the banning. IfNone, 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. IfNone, 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
ConstraintHintNamefor available hints. Default isConstraintDetectionConfig.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.
- 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 .
- Sos1
- class ConstraintSense
Classification of a constraint based on the comparison used.
Constraints can be
lhs == rhsEqualities:ConstraintSense.EQUALlhs <= rhsInequalities:ConstraintSense.LESS_THAN_EQUALlhs >= rhsInequalities: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
Placeholderwill 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.DecisionVarshould generally work whereExpressionis expected and operations will automatically convert as needed.Decision variables must belong to some namespace, ie. a
Problem, so you CANNOT construct one directly. UseProblem.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
DecisionVariableobject 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 made up of . 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
1and0and using other bounds will lead to an error when evaluating your model into an OMMX instance. TheProblem.BinaryVar()method sets the correct bounds automatically.Array decision variables and
shapeYou 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
shapein 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
10shape 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 ofshapewhen 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-likePlaceholders).This
CategoryLabelinstance is then passed to thedict_keysparameter 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
shapeanddict_keystogether. 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 nopartial_dictparameter.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
- __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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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 :
ExpressionA set-like expression to enumerate.Returns:
ExpressionA 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
exprmust 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.
predicatewill be called on each element inself. The resulting expression represents only the values for whichpredicateis 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.mapis useful whenfuncreturns scalar values, but in some situations one wants to write afuncthat returns other mappings/sequences instead. That is whereflat_mapshould be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced withsum(), etc.)You can also compare
flat_mapto a nested for-loop, or a generator expression that uses twoforclauses. 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.keys()andExpression.values().Examples: Simple matching of weights to their respective variables, as an alternative to just using
keys()or theCategoryLabel:>>> 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.values()andExpression.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
exprmust 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
exprmust 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
exprmust 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
selftofunc.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
selfwill be passed tofunc. When called on a sequence expression (eg. a 1-dimensional placeholder, or the result of functions likejijmodeling.product()orjijmodeling.items()), each element in the sequence is passed tofunc.This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like
Placeholders andDecisionVars. The resulting expression is then usually passed to a reducer, likejijmodeling.sum()(orExpression.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
Cin 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 :
ExpressionA tensor or jagged array expression to enumerate.Returns:
ExpressionAn 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
selfisn’t a valid sequence which can be multiplied, you will get an error when the resulting expression is added to aProblemand is type-checked.The optional
axisparameter 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()orjijmodeling.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 inshapewould 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
exprmust 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
exprmust 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
exprmust 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
selfisn’t a valid sequence which can be summed, you will get an error when the resulting expression is added to aProblemand is type-checked.The optional
axisparameter 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
xhas the same shape asWthrough 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
exprmust 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
exprmust 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:
ExpressionA 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.keys()andExpression.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
Problemthat is only available in Decorator API provided byProblem.update. SeeProblemfor 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
Placeholderrepresenting a binary number in this problem’s namespace.A shorthand for
DecoratedProblem.Placeholder(dtype=DataType.BINARY), provided for clarity and convenience. SeeDecoratedProblem.Placeholderfor 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.DecisionVariablefor 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
shapemust 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 keysdict_keys.latex(str, optional): A LaTeX-name of the binary variable to be represented in Jupyter notebook.It is set to
nameby 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.
CategoryLabelobjects can be created viaProblem.CategoryLabel(). The concrete values should be given ininstance_datadictionary together with placeholder values when creating aCompilerobject or inProblem.eval(). Ininstance_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,
nameis 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
Constraintobject 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.DecisionVarfor 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
shapemust 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 keysdict_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
nameby default.
description(str, optional): A description of the continuous variable.
Raises
ModelingError: Raises if a bound is aPlaceholderorSubscriptobject whosendimis neither0nor the same value asndimof 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
DecisionVarand 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 asBINARY,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, orDecoratedProblem.BinaryVar()for binary variables.Representation
Depending on the arguments described below, the representation of the decision variable will be determined as follows:
If none of
shapeordict_keysis provided, orshapeis(), DecisionVar will be considered as a scalar value (= array of dimension 0).If
shapeis provided anddict_keysis not provided, DecisionVar will be considered as a multi-dimensional array with fixed shape.If
dict_keysis provided withoutshape, DecisionVar will be considered as a dictionary-like structure with keys specified bydict_keys.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
shapemust 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 keysdict_keys.lower_boundandupper_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
nameby 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
Placeholderrepresenting 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 ofDimis 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
Placeholderrepresenting a floating-point (real) number in this problem’s namespace.A shorthand for
DecoratedProblem.Placeholder(dtype=DataType.FLOAT), provided for clarity and convenience. SeeDecoratedProblem.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 defaultdtypeisDataType.Naturalbut 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
Placeholderrepresenting an integer in this problem’s namespace.A shorthand for
DecoratedProblem.Placeholder(dtype=DataType.INTEGER), provided for clarity and convenience. SeeDecoratedProblem.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.DecisionVarfor 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
shapemust 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 keysdict_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
nameby default.
description(str, optional): A description of the integer variable.
Raises
ModelingError: Raises if a bound is aPlaceholderorSubscriptobject whosendimis neither0nor the same value asndimof 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
Placeholderrepresenting 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 ofLengthis 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
Placeholderrepresenting a natural number in this problem’s namespace.A shorthand for
DecoratedProblem.Placeholder(dtype=DataType.NATURAL), provided for clarity and convenience. SeeDecoratedProblem.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
Placeholderin 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 specifydtypeexplicitly to indicate the type of data the placeholder holds. Alternative shorthand methods likeDecoratedProblem.Integer,DecoratedProblem.Binary, orDecoratedProblem.Naturalare 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:
If none none of
ndim,shape,jagged,dict_keys, orpartial_dictis provided, or,ndimis set to zero, Placeholder will be considered as a scalar value (= array of dimension 0).If either (or both consistently) of
ndimorshapeis provided andjaggedisFalse(or omitted), and none ofdict_keysorpartial_dictis given, Placeholder will be considered as a multi-dimensional array with fixed shape.If either (or both consistently), of
ndimorshapeis provided andjaggedisTrue, and none ofdict_keysorpartial_dictis given,Placeholder will be considered as a jagged array (i.e. a non-rectangular ndim array).If
dict_keysis specified but none ofndim,shape,jaggedis provided, then Placeholder will be considered as a total dictionary-like structure with keys specified bydict_keys.If both
dict_keysandpartial_dict(set toTrue) are specified, and none ofndim,shape, orjaggedis provided, then Placeholder will be considered as a partial dictionary-like structure with keys specified bydict_keys.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
shapemust be a valid expression evaluating to a non-negative scalar.There is no need to provide
ndimifshapeis 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 keysdict_keys.partial_dict(bool, optional): Ifdict_keysis provided, specifies whether this placeholder represents a partial dictionary (i.e., not all keys are guaranteed to be present). Defaults toFalse.latex(str, optional): An optional LaTeX representation to be used in Jupyter notebook.When not provided,
nameis 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.DecisionVarfor 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. SeeCompilerfor more details on the expected format ofinstance_data.constraint_detection (
Optional[ConstraintDetectionConfig]): Configuration for automatic constraint hint detection. IfNone, the default configuration is used. Passfalseorjijmodeling.ConstraintDetectionConfig.disable()to disable constraint hint detection. SeeCompilerandConstraintDetectionConfigfor details.
- generate_random_dataset(_default: Any, _options: Any, _seed: Optional[int]) Any
Generates a dictionary of random
InstanceDataValuefor a given problem. To generateommx.v1.Instanceobject directly, useInstanceDataValue.generate_random_instanceinstead.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 inoptions.seed(optional): seed for random number generation.
Returns
dict: The dictionary from the name of placeholders to the generatedInstanceDataValueobjects. To be fed toInterpreter.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 ).
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:
Direct value of type
intorfloat- it corresponds to a singleton interval . In random generation context, this just means a constant fixed value.Use the functions from
jijmodeling.range,jijmodeling.range.size, orjijmodeling.range.valuemodules.Use functions from
jij.modeling.range.sizeto specify (non-negative) integer intervals, andjij.modeling.range.valuefor real intervals.jij.modeling.rangedynamically 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 -open(a, b): an open interval -closed_open(a, b): an upper half-open interval -open_closed(a, b): a lower half-open interval -greater_than(a): an open interval -at_least(a): a closed interval -less_than(a): an open interval -at_most(a): a closed interval
Use
rangebuiltin function: this is equivalent tojijmodeling.range.value.closed_open(a, b).Any python range object with
step = 1can be used as a size range; otherwise it results in runtime error.
Use a tuple: raw tuple
(a, b)is equivalent tojijmodeling.range.closed_open(a, b)ifaandbare eitherintorfloat.You can also use bound object as a tuple component; in such case, both tuple components must be one of the following:
A string
"Unbounded"means (in the first component) or (the second).A dictionary
{"Included": a}means the endpoint is inclusive.A dictionary
{"Excluded": a}means the endpoint is exclusive.
Examples: -
(1.2, 4)is equivalent toclosed_open(1.2, 4), -(-1, {"Included": 1})is equivalent toclosed(-1, 1), -(-5, {"Excluded": 4})is equivalent toclosed_open(-5, 4)and built in functionrange(-5, 4), -({"Excluded": 1}, {"Excluded": 2.5})is equivalent toopen(1, 2.5), -({"Included": -1}, "Unbounded")is equivalent toat_least(-1). -(5, "Unbounded")is INVALID;5must be bound object.
The range object: A dictionary of form
{"start": lb, "end": ub}, where bothlbandubare 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.Instancefor a given problem. See alsoInstanceDataValue.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 inProblem.generate_random_dataset()).default(optional): default range parameters for placeholders which is not specified inoptions.seed(optional): seed for random number generation.hints(optional): the hints to be detected during compilation seeInterpreter.eval_problemfor 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!
- 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. UseProblem.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
- __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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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 :
ExpressionA set-like expression to enumerate.Returns:
ExpressionA 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
exprmust 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.
predicatewill be called on each element inself. The resulting expression represents only the values for whichpredicateis 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.mapis useful whenfuncreturns scalar values, but in some situations one wants to write afuncthat returns other mappings/sequences instead. That is whereflat_mapshould be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced withsum(), etc.)You can also compare
flat_mapto a nested for-loop, or a generator expression that uses twoforclauses. 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.keys()andExpression.values().Examples: Simple matching of weights to their respective variables, as an alternative to just using
keys()or theCategoryLabel:>>> 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.values()andExpression.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
exprmust 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
exprmust 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
exprmust 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
selftofunc.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
selfwill be passed tofunc. When called on a sequence expression (eg. a 1-dimensional placeholder, or the result of functions likejijmodeling.product()orjijmodeling.items()), each element in the sequence is passed tofunc.This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like
Placeholders andDecisionVars. The resulting expression is then usually passed to a reducer, likejijmodeling.sum()(orExpression.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
Cin 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 :
ExpressionA tensor or jagged array expression to enumerate.Returns:
ExpressionAn 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
selfisn’t a valid sequence which can be multiplied, you will get an error when the resulting expression is added to aProblemand is type-checked.The optional
axisparameter 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()orjijmodeling.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 inshapewould 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
exprmust 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
exprmust 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
exprmust 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
selfisn’t a valid sequence which can be summed, you will get an error when the resulting expression is added to aProblemand is type-checked.The optional
axisparameter 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
xhas the same shape asWthrough 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
exprmust 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
exprmust 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:
ExpressionA 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.keys()andExpression.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 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 onExpressionand other JijModeling classes also returnExpressions. There’s no need to directly instantiate or convert anExpressionas 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
Expressionis added to aProblem, 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
ExpressionLikeandExpressionFunctionThere are dummy type aliases called
ExpressionLikeandExpressionFunction, 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 necessarilyExpressionobjects themselves. The meaning of these type aliases are as follows:ExpressionLike: Any type that can be converted to anExpression. This includes:Expressionitself,Numeric values like
intandfloat,DecisionVar,DependentVar, andPlaceholder,CategoryLabel, andtuples, lists, and dictionaries of them.
ExpressionFunction: Any function (callable) that takes one or moreExpressionarguments and returns anExpression. 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
- __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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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 :
ExpressionA set-like expression to enumerate.Returns:
ExpressionA 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
exprmust 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.
predicatewill be called on each element inself. The resulting expression represents only the values for whichpredicateis 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.mapis useful whenfuncreturns scalar values, but in some situations one wants to write afuncthat returns other mappings/sequences instead. That is whereflat_mapshould be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced withsum(), etc.)You can also compare
flat_mapto a nested for-loop, or a generator expression that uses twoforclauses. 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.keys()andExpression.values().Examples: Simple matching of weights to their respective variables, as an alternative to just using
keys()or theCategoryLabel:>>> 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.values()andExpression.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
exprmust 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
exprmust 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
exprmust 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
selftofunc.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
selfwill be passed tofunc. When called on a sequence expression (eg. a 1-dimensional placeholder, or the result of functions likejijmodeling.product()orjijmodeling.items()), each element in the sequence is passed tofunc.This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like
Placeholders andDecisionVars. The resulting expression is then usually passed to a reducer, likejijmodeling.sum()(orExpression.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
Cin 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 :
ExpressionA tensor or jagged array expression to enumerate.Returns:
ExpressionAn 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
selfisn’t a valid sequence which can be multiplied, you will get an error when the resulting expression is added to aProblemand is type-checked.The optional
axisparameter 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()orjijmodeling.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 inshapewould 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
DecisionVarandPlaceholder, 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
exprmust 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
exprmust 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
exprmust 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
selfisn’t a valid sequence which can be summed, you will get an error when the resulting expression is added to aProblemand is type-checked.The optional
axisparameter 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
xhas the same shape asWthrough 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
exprmust 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
exprmust 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:
ExpressionA 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.keys()andExpression.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
- 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
- infer(expr: ExpressionLike) 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 withinExpressions, and should generally work wherever anExpressionis expected. Operations will automatically convert as needed.Placeholders must belong to some namespace, i.e. a
Problem, so you cannot construct one directly. UseProblem.Placeholderor 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
Placeholderobject 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 , made up of . More details on these usages is provided in the following sections.Array placeholders,
shapeandndimYou 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
ndimorshapein the constructor method.ndimsimply 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
10shape 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
ndimorshapeis required to define an array placeholder, but if both are provided they must be consistent with eachother.When only
ndimis 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), andPlaceholder.shapewill 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-likeDecisionVars).This
CategoryLabelinstance is then passed to thedict_keysparameter 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
CategoryLabelmust have a corresponding value in the data. If you wish to create a partial dictionary, when only certain keys will have data, you must definepartial_dictasTruewhen creating the placeholder.The array and dictionary representations are mutually exclusive, and you cannot set
dict_keysalongsideshape/ndim. Doing so will lead to an exception.Attributes:
name(str): A name of the placeholder.dtype(DataType, optional): The data type (eg.DataType.INTorDataType.FLOAT) of the placeholder.ndim(int): The number of dimensions of the placeholder.shape(tupleofOptional[Expression], optional): The (partial) shape of the placeholder if given.jagged(boolean, defaut:False):Trueif 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):Trueif the placeholder is a partial dictionary. Ignored ifdict_keysis not given.description(str, optional): A description for user reference.
Raises:
TypeError: Raises if set a float value tondim.OverflowError: Raises if set a negative value tondim.
Examples: Create a scalar (or
ndimis0) 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
- __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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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
exprmust 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 :
ExpressionA set-like expression to enumerate.Returns:
ExpressionA 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
exprmust 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.
predicatewill be called on each element inself. The resulting expression represents only the values for whichpredicateis 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.mapis useful whenfuncreturns scalar values, but in some situations one wants to write afuncthat returns other mappings/sequences instead. That is whereflat_mapshould be used, “flattening” all sequences/iterators into a single linear sequence (which can then be reduced withsum(), etc.)You can also compare
flat_mapto a nested for-loop, or a generator expression that uses twoforclauses. 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.keys()andExpression.values().Examples: Simple matching of weights to their respective variables, as an alternative to just using
keys()or theCategoryLabel:>>> 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.values()andExpression.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
exprmust 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
exprmust 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
exprmust 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
selftofunc.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
selfwill be passed tofunc. When called on a sequence expression (eg. a 1-dimensional placeholder, or the result of functions likejijmodeling.product()orjijmodeling.items()), each element in the sequence is passed tofunc.This is mostly used alongside lambdas as a way to access individual values within array-like or dictionary-like
Placeholders andDecisionVars. The resulting expression is then usually passed to a reducer, likejijmodeling.sum()(orExpression.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
Cin 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 :
ExpressionA tensor or jagged array expression to enumerate.Returns:
ExpressionAn 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
selfisn’t a valid sequence which can be multiplied, you will get an error when the resulting expression is added to aProblemand is type-checked.The optional
axisparameter 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()orjijmodeling.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 inshapewould 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
exprmust 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
exprmust 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
exprmust 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
selfisn’t a valid sequence which can be summed, you will get an error when the resulting expression is added to aProblemand is type-checked.The optional
axisparameter 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
xhas the same shape asWthrough 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
exprmust 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
exprmust 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:
ExpressionA 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-likePlaceholders andDecisionVars. Using this with an invalid object will lead to an error when the resulting expression is added to aProblemand is type-checked.See also
Expression.keys()andExpression.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 toProblemSense.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
Placeholderrepresenting a binary number in this problem’s namespace.A shorthand for
Problem.Placeholder(dtype=DataType.BINARY), provided for clarity and convenience. SeeProblem.Placeholderfor 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.DecisionVarfor 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
shapemust 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 keysdict_keys.latex(str, optional): A LaTeX-name of the binary variable to be represented in Jupyter notebook.It is set to
nameby 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.
CategoryLabelobjects can be created viaProblem.CategoryLabel(). The concrete values should be given ininstance_datadictionary together with placeholder values when creating aCompilerobject or inProblem.eval(). Ininstance_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,
nameis 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
Constraintobject 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.DecisionVarfor 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
shapemust 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 keysdict_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
nameby default.
description(str, optional): A description of the continuous variable.
Raises
ModelingError: Raises if a bound is aPlaceholderorSubscriptobject whosendimis neither0nor the same value asndimof 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
DecisionVarand 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 asBINARY,INTEGER,CONTINUOUS), as well as defined lower and upper bounds.See
DecisionVardocumentation 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, orProblem.BinaryVar()for binary variables.Representation
Depending on the arguments described below, the representation of the decision variable will be determined as follows:
If none of
shapeordict_keysis provided, orshapeis(), DecisionVar will be considered as a scalar value (= array of dimension 0).If
shapeis provided anddict_keysis not provided, DecisionVar will be considered as a multi-dimensional array with fixed shape.If
dict_keysis provided withoutshape, DecisionVar will be considered as a dictionary-like structure with keys specified bydict_keys.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
shapemust 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 keysdict_keys.lower_boundandupper_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
nameby 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,
nameis 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
Placeholderrepresenting 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 ofDimis recommended just for clarity when defining a placeholder which will be used to define the length of multi-dimensional objects.See
Placeholderfor 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
Placeholderrepresenting a floating-point (real) number in this problem’s namespace.A shorthand for
Problem.Placeholder(dtype=DataType.FLOAT), provided for clarity and convenience. SeePlaceholderfor 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 defaultvertexisDataType.Naturalbut 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
Placeholderrepresenting an integer in this problem’s namespace.A shorthand for
Problem.Placeholder(dtype=DataType.INTEGER), provided for clarity and convenience. SeePlaceholderfor 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.DecisionVarfor 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
shapemust 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 keysdict_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
nameby default.
description(str, optional): A description of the integer variable.
Raises
ModelingError: Raises if a bound is aPlaceholderorSubscriptobject whosendimis neither0nor the same value asndimof 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
Placeholderrepresenting 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 ofLengthis recommended just for clarity when defining a placeholder which will be used to define the length of multi-dimensional objects.See
Placeholderfor 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
Placeholderrepresenting a natural number in this problem’s namespace.A shorthand for
Problem.Placeholder(dtype=DataType.NATURAL), provided for clarity and convenience. SeePlaceholderfor 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
DecisionVarfor 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
Problemusing the decorated API.This decorator takes as arguments the same parameters as a
Problemconstructor: a name, optionalProblemSense(defaults to minimize), and an optional description.This must decorate a function that takes
DecoratedProblemas the only argument and returns None. The resultingProblemwill 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. SeeCompilerfor more details on the expected format ofinstance_data.prune_unused_dec_vars(bool, optional): IfTrue, only include decision variables that appear in the objective or constraints. IfFalse(default), include all declared decision variables regardless of usage.constraint_detection (
Optional[ConstraintDetectionConfig]): Configuration for automatic constraint hint detection. IfNone, the default configuration is used. PassfalseorConstraintDetectionConfig.disableto disable constraint hint detection. SeeCompilerandConstraintDetectionConfigfor 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
InstanceDataValuefor a given problem. To generateommx.v1.Instanceobject directly, useInstanceDataValue.generate_random_instanceinstead.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 inoptions.seed(optional): seed for random number generation.
Returns
dict: The dictionary from the name of placeholders to the generatedInstanceDataValueobjects. To be fed toInterpreter.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 ).
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:
Direct value of type
intorfloat- it corresponds to a singleton interval . In random generation context, this just means a constant fixed value.Use the functions from
jijmodeling.range,jijmodeling.range.size, orjijmodeling.range.valuemodules.Use functions from
jij.modeling.range.sizeto specify (non-negative) integer intervals, andjij.modeling.range.valuefor real intervals.jij.modeling.rangedynamically 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 -open(a, b): an open interval -closed_open(a, b): an upper half-open interval -open_closed(a, b): a lower half-open interval -greater_than(a): an open interval -at_least(a): a closed interval -less_than(a): an open interval -at_most(a): a closed interval
Use
rangebuiltin function: this is equivalent tojijmodeling.range.value.closed_open(a, b).Any python range object with
step = 1can be used as a size range; otherwise it results in runtime error.
Use a tuple: raw tuple
(a, b)is equivalent tojijmodeling.range.closed_open(a, b)ifaandbare eitherintorfloat.You can also use bound object as a tuple component; in such case, both tuple components must be one of the following:
A string
"Unbounded"means (in the first component) or (the second).A dictionary
{"Included": a}means the endpoint is inclusive.A dictionary
{"Excluded": a}means the endpoint is exclusive.
Examples: -
(1.2, 4)is equivalent toclosed_open(1.2, 4), -(-1, {"Included": 1})is equivalent toclosed(-1, 1), -(-5, {"Excluded": 4})is equivalent toclosed_open(-5, 4)and built in functionrange(-5, 4), -({"Excluded": 1}, {"Excluded": 2.5})is equivalent toopen(1, 2.5), -({"Included": -1}, "Unbounded")is equivalent toat_least(-1). -(5, "Unbounded")is INVALID;5must be bound object.
The range object: A dictionary of form
{"start": lb, "end": ub}, where bothlbandubare 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.Instancefor a given problem. See alsoInstanceDataValue.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 inProblem.generate_random_dataset()).default(optional): default range parameters for placeholders which is not specified inoptions.seed(optional): seed for random number generation.hints(optional): the hints to be detected during compilation seeInterpreter.eval_problemfor 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
Namespaceassociated 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
Problemusing the decorated API.This must decorate a function that takes
DecoratedProblemas the only argument and returns None. You can callupdatemultiple 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 throughProblem.sense()- MAXIMIZE
- MINIMIZE
- class ProtobufError
- 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:Expressionitself,Numeric values like
intandfloat,DecisionVar,DependentVar, andPlaceholder,CategoryLabel, andtuples, lists, and dictionaries of them.