Part of my model states that the initial value of a time series should always equal the last. When modelling this for just one time series, the constraint is added no problem.
m.add_constraint(var_1[-1] == var_1[0])
But I am trying to add it to multiple time series with the following:
var_1 = m.continuous_var_dict([(i, j) for i in timesteps for j in timeseries], name = 'var_1 ')
m.add_constraints(var_1[-1, j] == var_1[0, j] for j in series)
But this time, I run into the error:
File "...\docplex\mp\model.py", line 4190, in add_constraints
return self._lfactory._new_constraint_block1(cts)
File "...\docplex\mp\mfactory.py", line 972, in _new_constraint_block1
ctseq = list(cts)
File "...\main.py", line 324, in <genexpr>
m.add_constraints(var_1[-1, j] == var_1[0, j] for j in series)
KeyError: (-1, 0)
Could anyone offer any advice? All the best!
Part of my model states that the initial value of a time series should always equal the last. When modelling this for just one time series, the constraint is added no problem.
m.add_constraint(var_1[-1] == var_1[0])
But I am trying to add it to multiple time series with the following:
var_1 = m.continuous_var_dict([(i, j) for i in timesteps for j in timeseries], name = 'var_1 ')
m.add_constraints(var_1[-1, j] == var_1[0, j] for j in series)
But this time, I run into the error:
File "...\docplex\mp\model.py", line 4190, in add_constraints
return self._lfactory._new_constraint_block1(cts)
File "...\docplex\mp\mfactory.py", line 972, in _new_constraint_block1
ctseq = list(cts)
File "...\main.py", line 324, in <genexpr>
m.add_constraints(var_1[-1, j] == var_1[0, j] for j in series)
KeyError: (-1, 0)
Could anyone offer any advice? All the best!
Share Improve this question asked Mar 31 at 22:40 TrevTrev 175 bronze badges2 Answers
Reset to default 1In the one-dimension case, the code uses the Python shortcut to access th elast element of a list using -1.
In the 2-dimensional case, you are building a dictionary indexed by tuples of indices. not a list. Hence the -1 shortcut does not work anymore; there is no "last" element in a dictionary. The dicitonary does not contain any key of the form (-1, ,j) for any row j.
Doplex provides the Model.continuous_var_matrix
to simplify building such matrices. Then to add your constraint, you just have to provide the indices of the last tuples in each "row".
The following code shows how to post the "last equals first" constraint using explicit value for the last index of the row.
timesteps = 5
timeseries = range(10)
# one dimension
vars1 = m.continuous_var_list(timeseries, name="x")
print(f"-- vars[-1] is the last element of the list: {vars1[-1]}")
vars2 = m.continuous_var_matrix(timesteps, timeseries, name="vars2")
last_step = max(timesteps)
m.add_constraints(vars2[last_step, j] == vars2[0,j] for j in timeseries)
m.print_information()
The output shows that in the second case, we added 10 constraints (timeseries) to the model
-- vars[-1] is the last element of the list: x_9
Model: docplex_model1
- number of variables: 60
- binary=0, integer=0, continuous=60
- number of constraints: 10
- linear=10
- parameters: defaults
- objective: none
- problem type is: LP
This looks like an out of bound
from docplex.mp.model import Model
m= Model(name='model')
series=range(-1,10)
var_1 = m.continuous_var_dict([(i, j) for i in series for j in series], name = 'var_1 ')
m.add_constraints(var_1[-1, j] == var_1[0, j] for j in series)
sol=m.solve(log_output=True)
for v in m.iter_continuous_vars():
print(v," = ",v.solution_value)
works fine
PS:
Have you tried to use OPL as CPLEX API ? Much easier to use than docplex python IMHO