JijModeling 2.10.0 Release Notes#
Feature Enhancements#
Specify category label elements directly as a list when generating random instances#
Previously, fixing category label values when generating random instances required specifying them under keys, as in {"C": {"keys": ["A", "B", "C"]}}. You can now specify them directly as a list.
import jijmodeling as jm
@jm.Problem.define("problem")
def problem(problem: jm.DecoratedProblem):
C = problem.CategoryLabel()
a = problem.Float(dict_keys=C)
x = problem.BinaryVar(dict_keys=C)
problem += (a * x).sum()
problem.generate_random_dataset(
seed=42,
options={"C": ["A", "B", "C"]} # Equivalent to {"C": {"keys": [...]}}
)
{'a': {'A': -4.161370289401178,
'B': -1.210197493373315,
'C': 1.800434110281392},
'C': ['A', 'B', 'C']}
Lists are supported only for category labels. Other placeholders must still use the existing format.
Additional LaTeX display customization#
Constructors for Placeholder, DecisionVar, NamedExpr and CategoryLabel now accept element_latex and subscript_styles
as additional configuration parameters to how these objects are displayed in \(\LaTeX\), in addition to latex the latex parameter.
element_latex sets a standard name for indices ranging over that object (such as when doing sums) to replace our automatically
assigned names (eg. i, j, etc.). Note that this may override whatever name the user writes in a lambda or for clause
problem = jm.Problem("problem")
N = problem.Natural("N", element_latex="n")
c = problem.Float("c", shape=N)
x = problem.BinaryVar("x", shape=N)
problem += jm.sum(c * x)
problem += c.map(lambda v: v * 2).sum()
problem
For tuple sets, element_latex accepts a list of names. Elements not assigned a name will fallback
to regular naming behavior.
subscript_styles allows customizing how the subscripts are actually displayed, eg. changing it to
a superscript, parentheses, or bracket-style display. For multi-dimensional arrays, passing a single
style applies it to all indices, but you can also pass a list, so that each index position is
displayed in a different style.
problem = jm.Problem("problem")
N = problem.Natural("N")
x = problem.BinaryVar("x", shape=(N, N), subscript_styles=jm.SubscriptStyle.BRACKET)
y = problem.BinaryVar(
"y", shape=(N, N), subscript_styles=[jm.SubscriptStyle.SUP, jm.SubscriptStyle.SUB]
)
problem += x[0, 1] + y[0, 1]
problem
Bugfixes#
Bugfix 1: Include category label information in randomly generated datasets#
Fixed an issue where randomly generated datasets did not include the category label definitions themselves.
Previously, the following dataset did not contain C, causing eval to fail. Starting with this release, the example runs successfully.
import jijmodeling as jm
@jm.Problem.define("problem")
def problem(problem: jm.DecoratedProblem):
C = problem.CategoryLabel()
a = problem.Float(dict_keys=C)
x = problem.BinaryVar(dict_keys=C)
problem += (a * x).sum()
dataset = problem.generate_random_dataset(
seed=42,
options={"C": {"keys": ["A", "B", "C"]}}
)
dataset
{'a': {'A': -4.161370289401178,
'B': -1.210197493373315,
'C': 1.800434110281392},
'C': ['A', 'B', 'C']}
problem.eval(dataset)
Instance(raw=<builtins.Instance object at 0x7ab1130c00>, annotations={})
Accept empty lists and arrays as placeholder inputs#
Previously, empty arrays or lists could be provided as instance data for one-dimensional arrays, but caused compilation errors for arrays with two or more dimensions.
Starting with this release, if the array shape allows empty data, the input is interpreted as a multidimensional array with at least one unspecified axis of length 0.
@jm.Problem.define("p")
def problem(problem: jm.DecoratedProblem):
cuts = problem.Float(ndim=2)
problem.eval({"cuts": []}) # Interpreted as a 0 x 0 array
Instance(raw=<builtins.Instance object at 0x7ab1131b00>, annotations={})
Fix constraint detection errors when specifying fixed_variables#
Fixed an issue where using fixed_variables to fix decision variables in one-hot or SOS1 constraints could raise internal error E-CE0007 when constraint detection was enabled.
The following example now compiles successfully with constraint detection enabled:
import jijmodeling as jm
problem = jm.Problem("one-hot with fixed variables")
x = problem.BinaryVar("x", shape=(3,))
problem += problem.Constraint("onehot", x[0] + x[1] + x[2] == 1)
problem.eval({}, fixed_variables={"x": {0: 0}})
Instance(raw=<builtins.Instance object at 0x7ab1132700>, annotations={})
If fixed values make these constraints infeasible, such as by fixing all variables in a one-hot constraint to 0, error E-CE0022 now reports the constraint name and the reason.