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.dtype
isDataType.INTEGER
if the type of the value is integer elsedtype
isDataType.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
(list
ofOptional[Expression]
, optional): The (partial) shape of the placeholder if given.dtype
(DataType
, optional): The data type (DataType.INT
orDataType.FLOAT
) of the placeholder.jagged
(boolean
, defaut:False
):True
if 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
. Thendim
must be set to a non-negative value and must concide with the length ofshape
if both specified. IfNone
is given, you must specifyshape
explicitly and the length ofshape
will 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.INT
orDataType.FLOAT
) of the placeholder. Used for random data generation.jagged
(boolean
, defaut:False
):True
if 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 toname
by 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
, orSubscript
object 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
name
by 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}
whereaxis
is 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}
whereaxis
is 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
shape
must 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
name
by 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
shape
must 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
name
by 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
shape
must 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
name
by 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
shape
must 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
name
by 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
shape
must 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
name
by 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
int
orfloat
- 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.value
modules.- Use functions from
jij.modeling.range.size
to specify (non-negative) integer intervals, andjij.modeling.range.value
for real intervals.jij.modeling.range
dynamically determines the type of the range based on the input. - These three modules provides the following combinators (see the module documents for more details.):
closed(a, b)
: a closed interval $[a, b]$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
range
builtin function: this is equivalent tojijmodeling.range.value.closed_open(a, b)
.- Any python range object with
step = 1
can be used as a size range; otherwise it results in runtime error.
- Any python range object with
Use a tuple: raw tuple
(a, b)
is equivalent tojijmodeling.range.closed_open(a, b)
ifa
andb
are eitherint
orfloat
.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;5
must be bound object.
- The range object: A dictionary of form
{"start": lb, "end": ub}
, where bothlb
andub
are 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.
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_data
from 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...>
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]