jijmodeling
1from ._jijmodeling import * # type: ignore
Error while creating a model.
Error while interpreting the model.
Failed to encode the object to a buffer.
Failed to decode the buffer to an instance.
A class for creating a number literal
The NumberLit class is used to create a number literal.
Its instance is automatically generated by the return value of
arithmetic or mathematical functions taking a number literal and
an object defined by jijmodeling as arguments.
Attributes
value(int | float): A numeric value.dtype(DataType): A type of the value.dtypeisDataType.INTEGERif the type of the value is integer elsedtypeisDataType.FLOAT.
Args
value(int | float): A numeric value.
Examples
Create a number literal with a integer value 123.
>>> import jijmodeling as jm
>>> v = jm.NumberLit(123)
>>> assert v.value == 123
>>> assert v.dtype == jm.DataType.INTEGER
Create a number literal with a float value 1.23.
>>> import jijmodeling as jm
>>> v = jm.NumberLit(1.23)
>>> assert v.value == 1.23
>>> assert v.dtype == jm.DataType.FLOAT
A class for creating a placeholder
The Placeholder class is used to create a placeholder. It is a symbol to be replaced by a numerical value when you solve an optimization problem.
The index operator ([]) of a placeholder with ndim >= 1 returns a Subscript object.
Attributes
name(str): A name of the placeholder.ndim(int): The number of dimensions of the placeholder.shape(listofOptional[Expression], optional): The (partial) shape of the placeholder if given.dtype(DataType, optional): The data type (DataType.INTorDataType.FLOAT) of the placeholder.jagged(boolean, defaut:False):Trueif the placeholder will be treated as a jagged array in random data generation. Ignored for scalars.description(str, optional): A description of the placeholder.
Args
name(str): A name of the placeholder.ndim(Optional[int]): The number of dimensions of the placeholder. Defaults to0. Thendimmust be set to a non-negative value and must concide with the length ofshapeif both specified. IfNoneis given, you must specifyshapeexplicitly and the length ofshapewill be used.shape(list[Optional[Expression]], optional): The (partial) shape of the placeholder. Used for random data generation.dtype(DataType, optional): The data type (DataType.INTorDataType.FLOAT) of the placeholder. Used for random data generation.jagged(boolean, defaut:False):Trueif the placeholder will be treated as a jagged array in random data generation. Ignored for scalars.latex(str, optional): A LaTeX-name of the placeholder to be represented in Jupyter notebook. It is set tonameby default.description(str, optional): A description of the placeholder.
Raises
TypeError: Raises if set a float value tondim.OverflowError: Raises if set a negative value tondim.
Examples
Create a scalar (or ndim is 0) placeholder whose name is "a".
>>> import jijmodeling as jm
>>> a = jm.Placeholder("a")
Create a 2-dimensional placeholder whose name is "m".
>>> import jijmodeling as jm
>>> m = jm.Placeholder("m", ndim=2)
Create a 1-dimensional placeholder with the index of 123.
>>> import jijmodeling as jm
>>> a = jm.Placeholder("a", ndim=2)
>>> a[123]
Placeholder(name='a', ndim=2)[NumberLit(value=123)]
A class representing a half-open interval.
The Range class is used to represent a half-open interval [start, end).
This class does not have a constructor because it should be created by the Element class.
Attributes
Note
This class does not contain any decision variable.
A class for creating an element
The Element class is used to create an element.
It is used in the following cases:
- an index of summation $\displaystyle \sum$ (
SumOp) - an index of product $\displaystyle \prod$ (
ProdOp) - a bound variable of the universal quantifier $\forall$ (
Forall)
Elements specify a set to which they belong. The set can be:
- A half-open range, where the lower bound is included and the upper bound is excluded.
- A
Placeholder,Element, orSubscriptobject withndim >= 1.
Ranges are generally specified with tuples as (start, end). For
convenience, passing a single number or scalar object as the argument is
interpreted as the end of a range starting from zero.
The index operator ([]) of an element with ndim >= 1 returns a Subscript object.
Attributes
name(str): A name of the element.ndim(int): The number of dimensions of the element. The value is one less than the value ofbelong_to.ndim.description(str): A description of the element.belong_to: A set the element belongs to.
Args
name(str): A name of the element.belong_to: A set the element belongs to.latex(str, optional): A LaTeX-name of the element to be represented in Jupyter notebook.- It is set to
nameby default.
- It is set to
description(str, optional): A description of the element.
Examples
Note that belong_to is a positional argument, not a keyword
argument, and so does not need to be written out. This is done in some
of these examples for clarity.
Create an element that belongs to a half-open range.
>>> import jijmodeling as jm
>>> i = jm.Element("i", belong_to=(0,10))
If you pass a scalar as the belong_to argument, the set that the element belongs to is a range starting at 0 going up to that value.
>>> import jijmodeling as jm
>>> i = jm.Element("i", 10)
>>> assert jm.is_same(i, jm.Element("i", belong_to=(0,10)))
The applies not just to numbers, but certain scalars, like Placeholder (with ndim == 0).
>>> import jijmodeling as jm
>>> n = jm.Placeholder("N")
>>> i = jm.Element("i", n)
>>> assert jm.is_same(i, jm.Element("i", belong_to=(0,n)))
Create an element that belongs to a 1-dimensional placeholder.
>>> import jijmodeling as jm
>>> E = jm.Placeholder("E", ndim=1)
>>> e = jm.Element("e", E)
Create a 1-dimensional element with the index of 123.
>>> import jijmodeling as jm
>>> a = jm.Placeholder("a", ndim=2)
>>> e = jm.Element("e", a)
>>> e[123]
Element(name='e', belong_to=Placeholder(name='a', ndim=2))[NumberLit(value=123)]
A class for representing a subscripted variable
The Subscript class is used to represent a variable with subscriptions.
Attributes
variable: A variable that has subscripts.subscripts(list): A list of subscripts.ndim(int): The number of dimensions of the subscripted variable.
Note
The Subscript class does not have a constructor.
A class for referring to the length of an array at a given axis.
The ArrayLength class is to refer to the number of elements of an axis in an array.
This class is not intended to be constructed directly. Instead, we
recommend using the len_at method of Placeholder, Element or
Subscript.
Attributes
array: A variable withndim >= 1.axis: An axis index. A $n$-dimensional variable has $n$ axes. Axis 0 is the array's outermost axis and $n-1$ is the innermost.description(str, optional): A description of the ArrayLength instance.
Raises
ModelingError: Raises if axis >= array.ndim.
Examples
Create a length of axis 0 in a 2-dimensional placeholder.
>>> import jijmodeling as jm
>>> a = jm.Placeholder("a", ndim=2)
>>> N = a.len_at(0, latex="N")
A class for representing a subscripted variable with dummy indices
The DummyIndexedVar class is an intermediate representation to support syntactic sugar of sum/prod with slices.
Note
The DummyIndexedVar class does not have a constructor.
Take a sum of the decision variable over the elements for which the slice is given and return a SumOp object.
Returns
SumOp: A SumOp object taken a sum of the decision variable over the elements for which the slice is given.
Note
An automatically created dummy index
- has a name of the form
__dummy_{decision_var.name}_{axis}whereaxisis the axis of the slice. - belongs to a range whose start defaults to 0 and end defaults to the length of the axis.
- has description of the form
dummy index at {axis} for {decision_var.name}. - has latex string of the form
\\ast_{axis}.
Examples
Create a SumOp object taken a sum of the 2-dim binary variable over the 0-th elements for which the slice is given.
>>> import jijmodeling as jm
>>> n = jm.Placeholder("n")
>>> x = jm.BinaryVar("x", shape=(n, n))
>>> i = jm.Element("__dummy_x_0", belong_to=n)
>>> j = jm.Element("j", belong_to=n)
>>> assert jm.is_same(x[:, j].sum(), jm.sum(i, x[i, j]))
Take a prod of the decision variable over the elements for which the slice is given and return a ProdOp object.
Returns
ProdOp: A ProdOp object taken a prod of the decision variable over the elements for which the slice is given.
Note
An automatically created dummy index
- has a name of the form
__dummy_{decision_var.name}_{axis}whereaxisis the axis of the slice. - belongs to a range whose start defaults to 0 and end defaults to the length of the axis.
- has description of the form
dummy index at {axis} for {decision_var.name}. - has latex string of the form
\\ast_{axis}.
Examples
Create a ProdOp object taken a prod of the 2-dim binary variable over the 0-th elements for which the slice is given.
>>> import jijmodeling as jm
>>> n = jm.Placeholder("n")
>>> x = jm.BinaryVar("x", shape=(n, n))
>>> i = jm.Element("__dummy_x_0", belong_to=n)
>>> j = jm.Element("j", belong_to=n)
>>> assert jm.is_same(x[:, j].prod(), jm.prod(i, x[i, j]))
A class for creating a binary variable
The BinaryVar class is used to create a binary variable.
The index operator ([]) of a binary variable with ndim >= 1 returns a Subscript object.
Attributes
name(str): A name of the binary variable.shape(tuple): A tuple with the size of each dimension of the binary variable. Empty if the variable is not multi-dimensional.description(str): A description of the binary variable.
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.
- Each item in
latex(str, optional): A LaTeX-name of the binary variable to be represented in Jupyter notebook.- It is set to
nameby default.
- It is set to
description(str, optional): A description of the binary variable.
Examples
Create a scalar binary variable whose name is "z".
>>> import jijmodeling as jm
>>> z = jm.BinaryVar("z")
Create a 2-dimensional binary variable whose name is "x" and has a 2x2 shape.
>>> import jijmodeling as jm
>>> x = jm.BinaryVar("x", shape=[2, 2])
Create a 1-dimensional binary variable with the index of 123.
>>> import jijmodeling as jm
>>> x = jm.BinaryVar("x", shape=[124])
>>> x[123]
BinaryVar(name='x', shape=[NumberLit(value=124)])[NumberLit(value=123)]
A class for creating an integer variable
The IntegerVar class is used to create an integer variable. The lower and upper bounds of the variable can be specified by:
- an integer value
- a float value
- a scalar expression that does not contains any decision variable
- a Placeholder object whose dimensionality is equal to that of this variable.
- a subscripted variable whose dimensionality is equal to that of this variable.
The index operator ([]) of a variable with ndim >= 1 returns a Subscript object.
Attributes
name(str): A name of the integer 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 integer variable.
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.
- Each item in
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.
- It is set to
description(str, optional): A description of the integer variable.
Raises
ModelingError: Raises if a bound is a Placeholder or Subscript object whose ndim
is neither 0 nor the same value as ndim of the integer variable.
Examples
Create a scalar integer variable whose name is "z" and domain is [-1, 1].
>>> import jijmodeling as jm
>>> z = jm.IntegerVar("z", 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).
>>> import jijmodeling as jm
>>> x = jm.IntegerVar("x", shape=[2, 2], lower_bound=0, upper_bound=2)
Create a 1-dimensional integer variable with the index of 123.
>>> import jijmodeling as jm
>>> x = jm.IntegerVar("x", shape=[124], lower_bound=0, upper_bound=2)
>>> x[123]
IntegerVar(name='x', shape=[NumberLit(value=124)], lower_bound=NumberLit(value=0), upper_bound=NumberLit(value=2))[NumberLit(value=123)]
A class for creating a continuous variable
The ContinuousVar class is used to create a continuous variable. The lower and upper bounds of the variable can be specified by:
- an integer value
- a float value
- a scalar expression that does not contains any decision variable
- a Placeholder object whose dimensionality is equal to that of this variable.
- a subscripted variable whose dimensionality is equal to that of this variable.
The index operator ([]) of a variable with ndim >= 1 returns a Subscript object.
Attributes
name(str): A name of the 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.
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.
- Each item in
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.
- It is set to
description(str, optional): A description of the continuous variable.
Raises
ModelingError: Raises if a bound is a Placeholder or Subscript object whose ndim is neither 0 nor the same value as ndim of the continuous variable.
Examples
Create a scalar continuous variable whose name is "z" and domain is [-1, 1].
>>> import jijmodeling as jm
>>> z = jm.ContinuousVar("z", lower_bound=-1, upper_bound=1)
Create a 2-dimensional continuous variable...
- whose name is "x".
- whose domain is [0, 2].
- where each dimension has length 2 (making this a 2x2 matrix).
>>> import jijmodeling as jm
>>> x = jm.ContinuousVar("x", shape=[2, 2], lower_bound=0, upper_bound=2)
Create a 1-dimensional continuous variable with the index of 123.
>>> import jijmodeling as jm
>>> x = jm.ContinuousVar("x", shape=[124], lower_bound=0, upper_bound=2)
>>> x[123]
ContinuousVar(name='x', shape=[NumberLit(value=124)], lower_bound=NumberLit(value=0), upper_bound=NumberLit(value=2))[NumberLit(value=123)]
A class for creating a semi-integer variable
The SemiIntegerVar class is used to create a semi-integer variable.
The lower and upper bounds of the variable can be specified by:
- an integer value
- a float value
- a scalar expression that does not contains any decision variable
- a Placeholder object whose dimensionality is equal to that of this variable.
- a subscripted variable whose dimensionality is equal to that of this variable.
The index operator ([]) of a semi-integer variable with ndim >= 1 returns a Subscript object.
Attributes
name(str): A name of the semi-integer 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 semi-integer variable.
Args
name(str): A name of the semi-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.
- Each item in
lower_bound: The lower bound of the variable.upper_bound: The upper bound of the variable.latex(str, optional): A LaTeX-name of the semi-integer variable to be represented in Jupyter notebook.- It is set to
nameby default.
- It is set to
description(str, optional): A description of the semi-integer variable.
Raises
ModelingError: Raises if a bound is a Placeholder or Subscript object whose ndim is neither 0
nor the same value as ndim of the semi-integer variable.
Examples
Create a scalar semi-integer variable whose name is "z" and domain is [-1, 1].
>>> import jijmodeling as jm
>>> z = jm.SemiIntegerVar("z", lower_bound=-1, upper_bound=1)
Create a 2-dimensional semi-integer variable...
- whose name is "x".
- whose domain is
[0, 2]. - where each dimension has length 2 (making this a 2x2 matrix).
>>> import jijmodeling as jm
>>> x = jm.SemiIntegerVar("x", shape=[2, 2], lower_bound=0, upper_bound=2)
Create a 1-dimensional semi-integer variable with the index of 123.
>>> import jijmodeling as jm
>>> x = jm.SemiIntegerVar("x", shape=[124], lower_bound=0, upper_bound=2)
>>> x[123]
SemiIntegerVar(name='x', shape=[NumberLit(value=124)], lower_bound=NumberLit(value=0), upper_bound=NumberLit(value=2))[NumberLit(value=123)]
A class for creating a semi-continuous variable
The SemiContinuousVar class is used to create a semi-continuous variable. Either the lower bound or the upper bound is set by the following object:
- an integer value
- a float value
- a scalar expression that does not contains any decision variable
- a Placeholder object whose dimensionality is equal to that of this variable.
- a subscripted variable whose dimensionality is equal to that of this variable.
The index operator ([]) of a semi-continuous variable with ndim >= 1 returns a Subscript object.
Attributes
name(str): A name of the semi-continuous variable.shape(tuple): A tuple with the size of each dimension of the semi-continuous 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 semi-continuous variable.
Args
name(str): A name of the semi-continuous 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.
- Each item in
lower_bound: The lower bound of the variable.upper_bound: The upper bound of the variable.latex(str, optional): A LaTeX-name of the semi-continuous variable to be represented in Jupyter notebook.- It is set to
nameby default.
- It is set to
description(str, optional): A description of the semi-continuous variable.
Raises
ModelingError: Raises if a bound is a Placeholder or Subscript object whose ndim
is neither 0 nor the same value as ndim of the semi-continuous variable.
Examples
Create a scalar semi-continuous variable whose name is "z" and domain is [-1, 1].
>>> import jijmodeling as jm
>>> z = jm.SemiContinuousVar("z", lower_bound=-1, upper_bound=1)
Create a 2-dimensional semi-continuous variable...
- whose name is "x".
- whose domain is
[0, 2]. - where each dimension has length 2 (making this a 2x2 matrix).
>>> import jijmodeling as jm
>>> x = jm.SemiContinuousVar("x", shape=[2, 2], lower_bound=0, upper_bound=2)
Create a 1-dimensional semi-continuous variable with the index of 123.
>>> import jijmodeling as jm
>>> x = jm.SemiContinuousVar("x", shape=[124], lower_bound=0, upper_bound=2)
>>> x[123]
SemiContinuousVar(name='x', shape=[NumberLit(value=124)], lower_bound=NumberLit(value=0), upper_bound=NumberLit(value=2))[NumberLit(value=123)]
A class for representing the absolute value
The AbsOp class is used to represent the absolute value.
The number of dimensions of the operand is zero.
Attributes
operand: The operand.
Note
The AbsOp class does not have a constructor.
A class for representing the ceil operator
The CeilOp class is used to represent the ceil operator.
The number of dimensions of the operand is zero.
Attributes
operand: The operand.
Note
The CeilOp class does not have a constructor.
A class for representing the floor operator
The FloorOp class is used to represent the floor operator.
The number of dimensions of the operand is zero.
Attributes
operand: The operand.
Note
The FloorOp class does not have a constructor.
A class for representing the base 2 logarithm
The Log2Op class is used to represent the base 2 logarithm.
The number of dimensions of the operand is zero.
Attributes
operand: The operand.
Note
The Log2Op class does not have a constructor.
A class for representing the base 10 logarithm
The Log10Op class is used to represent the base 10 logarithm.
The number of dimensions of the operand is zero.
Attributes
operand: The operand.
Note
The Log10Op class does not have a constructor.
A class for representing the natural logarithm
The LnOp class is used to represent the natural logarithm.
The number of dimensions of the operand is zero.
Attributes
operand: The operand.
Note
The LnOp class does not have a constructor.
A class for representing addition
The AddOp class is used to represent addition (+) of an arbitrary number of operands.
For example a + b + c + d would be one AddOp object.
The number of dimensions of each operand is zero.
Attributes
terms: A sequence of operands to be added.
Note
The AddOp class does not have a constructor. Its intended
instantiation method is by calling the addition operation on other
expressions.
A class for representing multiplication
The MulOp class is used to represent multiplication (*) of an arbitrary number of operands.
For example a * b * c * d would be one AddOp object.
The number of dimensions of each operand is zero.
Attributes
terms: A sequence of operands to be multiplied.
Note
The MulOp class does not have a constructor. Its intended
instantiation method is by calling the multiplication operation on other
expressions.
A class for representing modulo
The ModOp class is used to represent modulo (or remainder) (%).
The number of dimensions of each operand is zero.
Attributes
Note
The ModOp class does not have a constructor.
A class for representing the minimum value.
The MinOp class is used to represent the minimum value of operands.
The number of dimensions of each operand is zero.
Attributes
terms: A sequence of operands.
Note
The MinOp class does not have a constructor. Its intended
instantiation method is by calling the min function.
A class for representing the maximum value.
The MaxOp class is used to represent the minimum value of operands. The number of dimensions of each operand is zero.
Attributes
terms: A sequence of operands.
Note
The MaxOp class does not have a constructor. Its intended
instantiation method is by calling the max function.
A class for representing the power operator
The ModOp class is used to represent the power operator(**).
The number of dimensions of each operand is zero.
Attributes
Note
The PowOp class does not have a constructor.
A class for representing summation
The SumOp class is used to represent summation.
The number of dimensions of the opreand is zero.
Attributes
index: The index of summation.condition: The condition for the summation index.operand: The opreand.
Note
The SumOp class does not have a constructor.
A class for representing product
The ProdOp class is used to represent product.
The number of dimensions of the opreand is zero.
Attributes
Note
The ProdOp class does not have a constructor.
A class for representing logical AND
The AndOp class is used to represent logical AND (&) of an arbitrary number of operands.
For example a & b & c & d would be one AndOp object.
The number of dimensions of each operand is zero.
Attributes
terms: A sequence of operands to apply the AND operation.
Note
The AndOp class does not have a constructor.
A class for representing logical OR
The OrOp class is used to represent logical OR (|) of an arbitrary number of operands.
For example a | b | c | d would be one OrOp object.
The number of dimensions of each operand is zero.
Attributes
terms: A sequence of operands to apply the OR operation.
Note
The OrOp class does not have a constructor.
A class for representing logical XOR
The XorOp class is used to represent logical XOR (^) of an arbitrary number of operands.
For example a ^ b ^ c ^ d would be one XorOp object.
The number of dimensions of each operand is zero.
Attributes
terms-: A sequence of operands to apply the XOR operation.
Note
The XorOp class does not have a constructor.
A class for representing the equal operator
The EqualOp class is used to represent the equal operator (==).
The number of dimensions of each operand is zero.
Attributes
Note
The EqualOp class does not have a constructor.
A class for representing the not equal operator
The NotEqualOp class is used to represent the not equal operator (!=).
The number of dimensions of each operand is zero.
Attributes
Note
The NotEqualOp class does not have a constructor.
A class for representing the less than operator
The LessThanOp class is used to represent the less than operator (<).
The number of dimensions of each operand is zero.
Attributes
Note
The LessThanOp class does not have a constructor.
A class for representing the less than equal operator
The LessThanEqualOp class is used to represent the less than equal operator (<=).
The number of dimensions of each operand is zero.
Attributes
Note
The LessThanEqualOp class does not have a constructor.
A class for representing the greater than operator
The GreaterThanOp class is used to represent the greater than operator (>).
The number of dimensions of each operand is zero.
Attributes
Note
The GreaterThanOp class does not have a constructor.
A class for representing the greater than equal operator
The GreaterThanEqualOp class is used to represent the greater than equal operator (>=).
The number of dimensions of each operand is zero.
Attributes
Note
The GreaterThanEqualOp class does not have a constructor.
A class for creating an optimization problem
The Problem class is used to create an optimization problem.
Attributes
name(str): A name of the optimization problem.sense: 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.
custom_penalty_terms(dict): A dictionary that stores custom penalty terms.- A key is the name of a custom penalty and the value is the custom penalty object.
Args
name(str): A name of the optimization problem.sense(optional): Sense of the optimization problem. Defaults toProblemSense.MINIMIZE.
Returns the schema of the problem.
Returns
schema: The dictionary containing the schema of the problem.
Generates a dictionary of random InstanceDataValue for a given problem.
To generate ommx.v1.Instance object directly, use InstanceDataValue.generate_random_instance instead.
Args
options(optional): a dictionary of range parameters for each separate placeholders. The key must be the name of the placeholder and the value must be range parameter (as described in "Range Parameters and Range Syntax" below).default(optional): default range parameters for placeholders which is not specified inoptions.seed(optional): seed for random number generation.
Returns
dict: The dictionary from the name of placeholders to the generated InstanceDataValue objects. To be fed to Interpreter.eval_problem.
Range Parameters and Range Syntax
A range parameter is a dictionary consisting of the following fields:
size(optional): interval of natural numbers for the size of each array dimension (default:range(1, 6))value(optional): interval of real numbers for the value of each array element (default:range(-1.0, 1.0)- a uniform distribution on a closed interval $[-1.0, 1.0]$).
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 $[a, a] = {a}$. 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 $[a, b]$open(a, b): an open interval $(a, b)$closed_open(a, b): an upper half-open interval $[a, b)$open_closed(a, b): a lower half-open interval $(a, b]$greater_than(a): an open interval $(a, \infty)$at_least(a): a closed interval $[a, \infty)$less_than(a): an open interval $(-\infty, a)$at_most(a): a closed interval $(-\infty, a]$
- Use functions from
- 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.
- Any python range object with
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 $-\infty$ (in the first component) or $\infty$ (the second). - A dictionary
{"Included": a}means the endpoint is inclusive. - A dictionary
{"Excluded": a}means the endpoint is exclusive.
- A string
- 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
>>> N = jm.Placeholder("N", dtype=jm.DataType.INTEGER)
>>> c = jm.Placeholder("c", dtype=jm.DataType.FLOAT, shape=(N,))
>>> x = jm.BinaryVar("x", shape=(N,))
>>> i = jm.Element("i", belong_to=N)
>>> problem = jm.Problem("problem")
>>> 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])}
Generates random ommx.v1.Instance for a given problem.
See also InstanceDataValue.generate_random_dataset.
Args
options(optional): a dictionary of range parameters for each separate placeholders. The key must be the name of the placeholder and the value must be range parameter (as described in "Range Parameters and Range Syntax" section in~jijmodeling.Problem.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
>>> N = jm.Placeholder("N", dtype=jm.DataType.INTEGER)
>>> c = jm.Placeholder("c", dtype=jm.DataType.FLOAT, shape=(N,))
>>> x = jm.BinaryVar("x", shape=(N,))
>>> i = jm.Element("i", belong_to=N)
>>> problem = jm.Problem("problem")
>>> 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
An optimization sense
A class for creating a constraint
The Constraint class is used to create a constraint.
Attributes
name(str): A name of the constraint.sense: equal sign (=) or inequality sign (>=or<=) included in the expression.expression: The (in)equality equation of the constraint.forall(list): A list that stores forall indices.
Args
name(str): A name of the constraint.expression: The (in)equality equation of the constraint.forall: A list that stores forall indices. Defaults to None.
Raises
ModelingError: Raises if expression does not contain any decision variable.
Expression
Create an equality constraint that the sum of $N$ binary variables is equal to one.
>>> import jijmodeling as jm
>>> N = jm.Placeholder("N")
>>> i = jm.Element("i", belong_to=N)
>>> x = jm.BinaryVar("x", shape=(N,))
>>> repr(jm.Constraint("constraint", jm.sum(i, x[i]) == 1))
'Constraint(name="constraint", expression=sum(i in [0..N), x[i]) == 1)'
Create an inequality constraint with forall.
>>> import jijmodeling as jm
>>> N = jm.Placeholder("N")
>>> i = jm.Element("i", belong_to=N)
>>> j = jm.Element("j", belong_to=N)
>>> x = jm.BinaryVar("x", shape=(N, N))
>>> repr(jm.Constraint("constraint", jm.sum(i, x[i,j]) == 1, forall=j))
'Constraint(name="constraint", expression=sum(i in [0..N), x[i, j]) == 1, forall=[j])'
Create an inequality constraint with conditional forall.
>>> import jijmodeling as jm
>>> N = jm.Placeholder("N")
>>> i = jm.Element("i", belong_to=N)
>>> j = jm.Element("j", belong_to=N)
>>> x = jm.BinaryVar("x", shape=(N, N))
>>> repr(jm.Constraint("constraint", x[i,j] <= 2, forall=[i, (j, j != i)]))
'Constraint(name="constraint", expression=x[i, j] <= 2, forall=[i, (j, j != i)])'
Returns true if the constraint is an equality constraint.
Returns
bool: True if the constraint is an equality constraint. Otherwise, False.
Examples
>>> import jijmodeling as jm
>>> N = jm.Placeholder("N")
>>> i = jm.Element("i", belong_to=N)
>>> x = jm.BinaryVar("x", shape=(N,))
>>> constraint = jm.Constraint("constraint", jm.sum(i, x[i]) == 1)
>>> assert constraint.is_equality()
Returns true if the constraint is an inequality constraint.
Returns
bool: True if the constraint is an inequality constraint. Otherwise, False.
Examples
>>> import jijmodeling as jm
>>> N = jm.Placeholder("N")
>>> i = jm.Element("i", belong_to=N)
>>> x = jm.BinaryVar("x", shape=(N,))
>>> constraint = jm.Constraint("constraint", jm.sum(i, x[i]) <= 1)
>>> assert constraint.is_inequality()
Equality of a constraint
A class for creating a custom penalty term
The CustomPenaltyTerm class is used to create a custom penalty term.
Attributes
name(str): A name of the custom penalty term.expression: The expression of the custom penalty term.forall(list): A list that stores forall indices.
Args
name(str): A name of the custom penalty term.expression: The expression of the custom penalty term.forall: A list that stores forall indices. Defaults to None.
Raises
ModelingError: Raises if expression does not contain any decision variable.
Expression
Create a custom penalty term.
>>> import jijmodeling as jm
>>> N = jm.Placeholder("N")
>>> i = jm.Element("i", belong_to=N)
>>> x = jm.BinaryVar("x", shape=(N,))
>>> repr(jm.CustomPenaltyTerm("custom penalty term", (jm.sum(i, x[i]) - 1)**2)) # doctest: +ELLIPSIS
'CustomPenaltyTerm(name="custom penalty term", expression=((sum(i in [0..N), x[i]) - 1) ** 2))'
Create a custom penalty term with forall.
>>> import jijmodeling as jm
>>> N = jm.Placeholder("N")
>>> i = jm.Element("i", belong_to=N)
>>> j = jm.Element("j", belong_to=N)
>>> x = jm.BinaryVar("x", shape=(N, N))
>>> repr(jm.CustomPenaltyTerm("custom penalty term", (jm.sum(i, x[i,j]) - 1)**2, forall=j)) # doctest: +ELLIPSIS
'CustomPenaltyTerm(name="custom penalty term", expression=((sum(i in [0..N), x[i, j]) - 1) ** 2), forall=[j])'
Create a custom penalty term with conditional forall.
>>> import jijmodeling as jm
>>> N = jm.Placeholder("N")
>>> i = jm.Element("i", belong_to=N)
>>> j = jm.Element("j", belong_to=N)
>>> x = jm.BinaryVar("x", shape=(N, N))
>>> repr(jm.CustomPenaltyTerm("custom penalty term", (x[i,j] - 2)**2, forall=[i, (j, j != i)])) # doctest: +ELLIPSIS
'CustomPenaltyTerm(name="custom penalty term", expression=((x[i, j] - 2) ** 2), forall=[i, (j, j != i)])'
A class for evaluation.
The Evaluation class is to represent the result of evaluating a model.
Attributes: energy (numpy.ndarray): The value of energy of each sample. objective (numpy.ndarray): The value of an objective function of each sample. constraint_violations (dict[str, numpy.ndarray]): The constraint violation of each sample. constraint_forall (dict[str, numpy.ndarray]): The constraint forall of each sample. constraint_values (numpy.ndarray): The constraint value of each sample. penalty (dict[str, numpy.ndarray]): The penalty of each sample.
Convert into a dict.
Returns: dict: A dict whose keys are name of the Evaluation's fields.
Create a Evaluation object from the given dict.
If a key is not the name of the Evaluation fields, the value value is ignored.
Args: dict: A dict whose keys are name of the Evaluation fields.
Serialize the Evaluation object into a JSON string.
Returns: str: A JSON string.
Note: A numpy array is converted into a list.
Create a Evaluation object from the JSON string.
Args: json (str): A JSON string.
Returns: Evaluation: An Evaluation object.
Convert into a pandas DataFrame.
Returns: pandas.DataFrame: A pandas DataFrame.
Return the values for the each constraint.
The return value is a list of dictionaries. Each dictionary has the keys of the constraint names and the dictionary values. The dictionary values have the keys of the forall indices as tuple and the values for the forall indices.
Returns: A list of dictionaries.
A class for representing a record.
There are two types of solutions that can be given; dense solutions and sparse solutions. A dense solution is a dict whose key is a variable name and the value is a list of numpy.ndarray. A sparse solution is a dict whose key is a variable name and the value is a list of tuples with three elements, where the first element is a list of indices, the second element is a list of non-zero values, and the third element is a shape of the array. The length of the list of solutions must be the same as the length of the list of num_occurrences. Each index of the list of solutions corresponds to the same index of the list of non-zero values.
As an example, consider the following solutions:
{
"x": [
np.array([[0.0, 1.0, 0.0], [2.0, 0.0, 3.0]]),
np.array([[1.0, 0.0, 0.0], [2.0, 3.0, 4.0]])
],
"y": [
np.array([0.0, 0.0, 1.0]),
np.array([0.0, 1.0, 0.0])
]
}
This is a dense solution. The corresponding sparse solution is as follows:
{
"x": [
(([0, 1, 1], [1, 0, 2]), [1.0, 2.0, 3.0], (2, 3)),
(([0, 1, 1, 1], [0, 0, 1, 2]), [1.0, 2.0, 3.0, 4.0], (2, 3))
],
"y": [
(([2],), [1.0], (3,)),
(([1],), [1.0], (3,))
]
}
Attributes
solution(Union[Dict[str, List[numpy.ndarray]], Dict[str, List[Tuple[List[int], List[float], Tuple[int, ...]]]]]): A solution.num_occurrences(List[int]): A list of the number of occurrences in which the solution is observed.
Convert into a dict.
Returns
dict: A dict whose keys are "solution" and "num_occurrences".
Create a Record object from the given dict.
If a key is not one of "solution" or "num_occurrences", the value is ignored.
Args
dict: A dict of str to a list of dense solutions or sparse solutions.
Returns
A Record object.
Serialize the Record object into a JSON string.
Returns
str: A JSON string.
Note
A numpy array is serialized into a list.
Return true if the solution is dense.
Returns
bool: True if the solution is dense.
Return true if the solution is sparse.
Returns
bool: True if the solution is sparse.
A class for storing time to solve a problem.
Attributes
preprocess(float, optional): Time to preprocess the problem. Defaults to None.solve(float, optional): Time to solve the problem. Defaults to None.postprocess(float, optional): Time to postprocess the problem. Defaults to None.
Convert into a dict.
Returns
dict: A dict with keys "preprocess", "solve", and "postprocess".
Create a SolvingTime object from the given dict.
If a key is not one of "preprocess", "solve", or "postprocess", the value is ignored.
Args
dict (dict): A dict.
Returns
A SolvingTime object.
Serialize the SolvingTime object into a JSON string.
Returns
str: A JSON string.
Note
A numpy array is serialized into a list.
Create a SolvingTime object from the JSON string.
Args
json (str): A JSON string.
Returns
SolvingTime: A SolvingTime object.
A class for storing time of jijzept running.
Attributes
post_problem_and_instance_data(float, optional): Time to upload problem and instance_data to blob. Defaults to None.request_queue(float, optional): Time to send request to queue. Defaults to None.fetch_problem_and_instance_data(float, optional): Time to fetch problme and instance_data from blob. Defaults to None.fetch_result(float, optional): Time to fetch result. Defaults to None.deserialize_solution(float, optional): Time to deserialize json object. Defaults to None.
Convert into a dict.
Returns
dict: A dict whose keys are name of the SystemTime's fields.
Create a SystemTime object from the given dict.
If a key is not the name of the SystemTime fields, the value value is ignored.
Args
dict (dict): A dict.
Returns
A SystemTime object.
Serialize the SystemTime object into a JSON string.
Returns
str: A JSON string.
Note
A numpy array is serialized into a list.
Create a SystemTime object from the JSON string.
Args
json (str): A JSON string.
Returns
SystemTime: A SystemTime object.
A class for storing time to be measured.
Attributes
solve(SolvingTime): Time to solve the problem.system(SystemTime): Time to measure system time.total(float, optional): Total time to solve the problem. Defaults to None.
Convert into a dict.
Returns
dict: A dict whose keys are name of the MeasuringTime's fields.
Create a MeasuringTime object from the given dict.
If a key is not the name of the MeasuringTime fields, the value value is ignored.
Args
dict (dict): A dict.
Returns
A MeasuringTime object.
Serialize the MeasuringTime object into a JSON string.
Returns
str: A JSON string.
Note
A numpy array is serialized into a list.
Create a MeasuringTime object from the JSON string.
Args
json (str): A JSON string.
Returns
MeasuringTime: A MeasuringTime object.
A class for storing time of jijzept running.
Attributes
post_problem_and_instance_data(float, optional): Time to upload problem and instance_data to blob. Defaults toNone.request_queue(float, optional): Time to send request to queue. Defaults toNone.fetch_problem_and_instance_data(float, optional): Time to fetch problem andinstance_datafrom blob. Defaults toNone.fetch_result(float, optional): Time to fetch result. Defaults toNone.deserialize_solution(float, optional): Time to deserialize json object. Defaults toNone.
Serialize the SampleSet object into a JSON string.
Returns
str: A JSON string.
Note
A numpy array is converted into a list.
Convert into a pandas DataFrame.
Returns
pandas.DataFrame: A pandas DataFrame.
Return a SampleSet with only feasible solutions.
If there is no feasible solution, the record and evaluation are empty.
Args
rtol(float): The relative tolerance parameter. Defaults to1e-5.atol(float): The absolute tolerance parameter. Defaults to1e-8.
Returns
SampleSet: A SampleSet object with only feasible solutions or empty.
Note
The feasible solutions are determined by the following condition: $$ |0 - v| \leq \mathrm{atol} + \mathrm{rtol} \cdot |v| $$
Return a SampleSet with only infeasible solutions.
If there is no infeasible solution, the record and evaluation are empty.
Args
rtol(float): The relative tolerance parameter. Defaults to1e-5.atol(float): The absolute tolerance parameter. Defaults to1e-8.
Returns
SampleSet: A SampleSet object with only infeasible solutions or empty.
Note
The feasible solutions are determined by the following condition: $$ |0 - v| > \mathrm{atol} + \mathrm{rtol} \cdot |v| $$
Return a SampleSet with feasible solutions which has the lowest objective.
If there is no feasible solution, the record and evaluation are empty.
Args
rtol(float): The relative tolerance parameter. Defaults to1e-5.atol(float): The absolute tolerance parameter. Defaults to1e-8.
Returns
SampleSet: A SampleSet object with feasible solutions or empty.
Note
The feasible solutions are determined by the following condition: $$ |0 - v| \leq \mathrm{atol} + \mathrm{rtol} \cdot |v| $$
Return true if the solution is dense.
Returns
bool: True if the solution is dense.
Return true if the solution is sparse.
Returns
bool: True if the solution is sparse.
Interpreter of the JijModeling AST
This class is responsible for
- Creating OMMX instance from the AST.
- This means this module also has responsible to register decision variable ID for each decision variables in AST.
- Manage instance data to be substituted into the
Placeholder.
Examples
>>> import jijmodeling as jm
>>> import numpy as np
Create a new interpreter with scalar instance data
>>> interpreter = jm.Interpreter({"a": 1})
Insert instance data after creating the interpreter
>>> interpreter.insert_instance_data("b", 2) # scalar
Python list and numpy array are supported
>>> interpreter.insert_instance_data("c", [3, 4])
>>> interpreter.insert_instance_data("d", [[1, 2], [3, 4]])
>>> interpreter.insert_instance_data("e", np.array([3, 4]))
JaggedArray, non-uniform multi-dimensional array is also supported
>>> interpreter.insert_instance_data("f", [[[1, 2]], [[3, 4, 5]], [[6]]])
>>> interpreter.insert_instance_data("g", jm.JaggedArray([[[1, 2]], [[3, 4, 5]], [[6]]]))
You can get the instance data by using get_instance_data method
>>> interpreter.get_instance_data("a")
1.0
Array are normalized to numpy array
>>> interpreter.get_instance_data("c")
array([3., 4.])
>>> interpreter.get_instance_data("e")
array([3., 4.])
>>> interpreter.get_instance_data("f") # doctest: +ELLIPSIS
<jijmodeling.JaggedArray object at 0x...>
Update instance data and re-evaluate expressions
>>> a = jm.Placeholder("a")
>>> x = jm.BinaryVar("x")
>>> interpreter.eval_expr(a * x) # Original evaluation with a = 1
Function(x0)
>>> interpreter.insert_instance_data("a", 3) # Update value of 'a'
>>> interpreter.eval_expr(a * x) # Re-evaluate with updated value
Function(3*x0)
Evaluate the problem and returns ommx.v1.Instance.
Args
problem: ajijmodeling.Problemobject to compile.hints(optional): a list of constraint hints to be detected during evaluation. When omitted or givenNone, the default constraint hints are used. Pass empty list to disable hint detection entirely.
Returns
instance: an OMMX v1 instance object.
Jagged array, a multi-dimensional array where each element can be an array of different length.
Examples
>>> import jijmodeling as jm
>>> arr = jm.JaggedArray([[[1, 2], [3, 4, 5]], [[6]]])
# Three dimensional
>>> assert arr.dim == 3
# __getitem__ works
>>> assert arr[0, 0, 0] == 1.0
>>> assert arr[0, 0, 1] == 2.0
>>> assert arr[0, 1, 0] == 3.0
>>> assert arr[0, 1, 1] == 4.0
>>> assert arr[0, 1, 2] == 5.0
>>> assert arr[1, 0, 0] == 6.0
# out of range
>>> arr[0, 0, 2]
Traceback (most recent call last):
...
IndexError: Invalid index
# dimension mismatch
>>> arr[0, 0]
Traceback (most recent call last):
...
IndexError: Invalid index
>>> assert arr.size_at([]) == 2 # [[1, 2], [3, 4, 5]] and [[6]]
>>> assert arr.size_at([0]) == 2 # [1, 2] and [3, 4, 5]
>>> assert arr.size_at([1]) == 1 # [[6]]
>>> assert arr.size_at([0, 0]) == 2 # [1, 2]
>>> assert arr.size_at([0, 1]) == 3 # [3, 4, 5]
>>> assert arr.size_at([1, 0]) == 1 # [6]