What is SampleSet
Here, we introduce an object called SampleSet that is returned by JijZept. The SampleSet contains the solution and various related information obtained by JijZept. We will use the following mathematical model and JijSolver to show the information contained in the SampleSet.
import jijmodeling as jm
N = jm.Placeholder('N')
a = jm.Placeholder('a', ndim=2)
x = jm.BinaryVar('x', shape=(N,N))
i = jm.Element('i', belong_to=(0, N))
j = jm.Element('j', belong_to=(0, N))
problem = jm.Problem('Simple Problem')
problem += jm.sum([i, j], a[i, j]*x[i, j])
problem += jm.Constraint('onehot-row', x[:, j].sum() == 1, forall=j)
problem += jm.Constraint('onehot-col', x[i, :].sum() == 1, forall=i)
problem

The instance data for this mathematical model is as follows:
instance_data={'N': 3, 'a': [[1, 2, 3], [4, 5, 6], [7, 8, 9]]}
then use JijSolver to find the solution.
import jijzept as jz
solver = jz.JijSolver(config='config.toml')
response = solver.sample_model(problem, instance_data)
The SampleSet can be retrieved by using the get_sampleset() method.
sampleset = response.get_sampleset()
sampleset
SampleSet(data=[Sample(run_id="5df937c2-b6d8-41a2-b28c-08940cf34b4f", num_occurrences=1, run_info={}, var_values={"x": SparseVarValues(name="x", values={(0, 1): 1, (1, 2): 1, (2, 0): 1}, shape=(3, 3), var_type=VarType.CONTINUOUS)}, eval=EvaluationResult(objective=15, constraints={"onehot-col": Violation(name="onehot-col", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0}), "onehot-row": Violation(name="onehot-row", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0})}, penalties={}))], set_id="fe215485-2518-49ed-a200-ba71e4b6b169", set_info={}, run_info={}, measuring_time=MeasuringTime(solving_time=SolvingTime(compiling_time=0, transpiling_time=0, preprocess_time=0, solving_time=0, decoding_time=0, postprocess_time=0), system_time=SystemTime(posting_time=None, request_queuing_time=None, fetching_problem_time=None, fetching_result_time=None, deserialize_time=None)), run_times={})
SampleSet.data contains an array of Sample objects, each containing a single solution obtained by the solver and information associated with it. Some JijZeptSolvers allow to get multiple solutions at once, in which case multiple Samples are contained in the array.
This time, we will see the information stored in the 0th sample.
sample = sampleset.data[0]
sample
Sample(run_id="5df937c2-b6d8-41a2-b28c-08940cf34b4f", num_occurrences=1, run_info={}, var_values={"x": SparseVarValues(name="x", values={(0, 1): 1, (1, 2): 1, (2, 0): 1}, shape=(3, 3), var_type=VarType.CONTINUOUS)}, eval=EvaluationResult(objective=15, constraints={"onehot-col": Violation(name="onehot-col", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0}), "onehot-row": Violation(name="onehot-row", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0})}, penalties={}))
VarValues
Let's start by looking at the var_values property. This is a dictionary type, with keys representing the names of decision variables. Each key is associated with a SparseVarValues object, containing detailed information about each variable.
sample.var_values
{'x': SparseVarValues(name="x", values={(0, 1): 1, (1, 2): 1, (2, 0): 1}, shape=(3, 3)}
In the case of a problem with multiple decision variables, an item for each decision variable is added to the dictionary of var_values property.
SparseVarValues.name
The SparseVarValues.name property contains the name of the decision variable. In this case, "x" corresponds to the decision variable jm.BinaryVar('x', shape=(N,N)) of the mathematical model defined above.
SparseVarValues.values
The SparseVarValues.values property contains the value for each index of the decision variable. In the above output result, this means that x[0, 1], x[1, 2], x[2, 0] took the value 1 and the rest took the value 0. Please note that only indices with non-zero values are stored.
SparseVarValues.shape
The SparseVarValues.shape property contains the shape of the decision variable. The above output result shows that the decision variable is a 2-dimensional list with 3 rows and 3 columns.
Using the to_dense method, you can check the decision variables by dense representation as follows:
sample.var_values['x'].to_dense()
array([[0., 1., 0.],
[0., 0., 1.],
[1., 0., 0.]])
EvaluationResult
Next, let's take a closer look at the eval property. This property contains crucial information regarding the evaluation of the mathematical model based on the solution obtained by the solver. It details the objective function's value and indicates whether the solution satisfies or breaches the constraints.
sample.eval
EvaluationResult(objective=15, constraints={"onehot-col": Violation(name="onehot-col", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0}), "onehot-row": Violation(name="onehot-row", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0})}, penalties={})
EvaluationResult.objective
The Evaluation.objective property contains the value of the objective function, which is calculated by the solution.
sample.eval.objective
15.0
EvaluationResult.constraints
The EvaluationResult.constraint contains a dictionary whose key is the name of the constraint condition and whose value is Violation with information about how much the constraint condition is violated.
sample.eval.constraints
{'onehot-row': Violation(name="onehot-row", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0}),
'onehot-col': Violation(name="onehot-col", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0})}
Violation
Let's look at the details of Violation for the constraint condition 'onehot-row'.
Violation(name="onehot-row", total_violation=0, expr_values={(0,): 0, (1,): 0, (2,): 0})
The Violation.name property is the name of a constraint. For example, 'onehot-row' corresponds to the constraint condition jm.Constraint('onehot-row', x[:, j].sum () == 1, forall=j) of the mathematical model defined above.
The Violation.total_violation property stores the value representing how much the constraint condition is violated. In the case of the constraint condition 'onehot-row', it is calculated as follows.
Now let's look at the result of the calculation.
sample.eval.constraint['onehot-row'].total_violation
0.0
The result is 0, which means that the constraint condition is satisfied.
The Violation.expr_values property contains a dictionary whose key is the forall index and
its value is the value representing how much the constraint condition of each forall index is violated.
sample.eval.constraints['onehot-row'].expr_values
{(0,): 0, (1,): 0, (2,): 0}
This dictionary shows that when the forall index j is 0, 1, and 2, respectively, the value is 0, 0, and 0. It means that the constraints are satisfied for all indices.
In this notes, violation means a value representing how much the constraint condition is violated.
In general, the violation of the equality constraint condition is calculated by , and the violation of the inequality constraint condition is calculated by . When calculating the violations of multiple constraint conditions, it is calculated by taking the sum of the violation of each.
In the above calculation for 'onehot-row', the violation of each forall index j is calculated by , then the violation of 'onehot-row' is calculated by the sum along index j.
EvaluationResult.penalties
When using the penalty term jijmodeling.CustomPenaltyTerm, EvaluationResult.penalties contains a dictionary whose key is the name of the penalty term and whose value is Violation with information about how much the penalty term is violated. This Violation is the same as explaned in the Violation section.
Quick Reference
SampleSet
SampleSet contains the solutions and various related infomations obtained from JijZept.
| Attribute | Description |
|---|---|
data | A list of Sample. See Sample for details. |
measuring_time | Information about the time taken for solving. See MeasuringTime for details. |
set_info | Metadata obtained from JijZeptSolver. Depending on JijZeptSolver, it may include a list of constraint names that were treated as obvious constraints. |
feasibles() | Returns a SampleSet containing only feasible solutions. |
Sample
Sample contains single solution and related information obtained from the JijZept.
| Attribute | Description |
|---|---|
num_occurrence | Stores the number of times the same solution was obtained at once. |
var_values | Contains information about the decision variables in the solution. See SparseVarValues for details. |
eval | Stores values related to the evaluation of the solution. See EvaluationResult for details. |
to_dense() | Returns the decision variables by dense representation. |
SparseVarValues
SparseVarValues contains information about the decision variables.
| Attribute | Description |
|---|---|
name | Stores the name of the decision variable. See SparseVarValues.name for details. |
values | Contains values for each index of the decision variable. See SparseVarValues.values for details. |
shape | Stores a tuple indicating the shape of the decision variable. See SparseVarValues.shape for details. |
var_type | Stores the type of the decision variable. |
to_dense() | Returns the decision variable by dense representation. See the note for usage. |
var_type will be effective in the future. Currently, all decision variables are set to var_type=VarType.CONTINUOUS.
EvaluationResult
EvaluationResult stores information about the evaluation of the solution.
| Attribute | Description |
|---|---|
objective | Stores the value of the objective function. |
constraints | Contains information on how much the constraint conditions is violated. See EvaluationResult.constraints for details. |
penalties | Stores information on how much the penalty terms is violated. See Evaluation.penalties for details. |
MeasuringTime
MeasuringTime contains information about the time taken for solving.
| Attribute | Description |
|---|---|
total() | Returns the time taken for solving in the entire JijZept. |
view_solving_time() | Returns the time taken for each operation performed by JijZeptSolver during solving. |
view_system_time() | Returns the time taken by the JijZept client for each request. |
MeasuringTime will be effective in the future. Currently, the values values may or may not be stored for each JijZeptSolver.