Dear Vincent,
Many thanks for your clarifying and suggestion for naming the model. As the use of the functional form has had some limitations, specifically in colab, I am managing to write the model in the simple form for ease of use, defining the syntax, and having access to its related examples. Please, see this
link. In the next step, I will come back to functional form. :)
Let's say, in this form we can define the original model and its related outputs. It works fine. Then we have tried to achieve the value of the variables by:
for v in mdl.iter_binary_vars():
print(v," = ",v.solution_value)
It seems the method works. As we need to access the variable's value in the subgradient method, it is so important. Also, I have seen another method to invoke the variable's value that would be convenient to use. It is something like this, but when I run the code the following error is shown:
for i in range(len(tasks)):
for j in range(len(machines)):
print(m.x[i,j].solution_value)
=error===================================
'SolveSolution' object has no attribute 'x'
Would you say please, what is the difference between the first and the second method to invoke the variable's value?
The expression that we will need to write to calculate the Gamma looks like: gamma(i) = 1 - sum{j, x.value(i,j)} and what I have tried is:
for i in range(len(tasks)):
gamma[i] = 1- ([j.solution_value] for j in lr.iter_binary_vars())
=error===============================
TypeError: unsupported operand type(s) for -: 'int' and 'generator'
About the KPI's, we could define this for the second objective (LR) based on your mentioned function and it works very well, but when I want to define multiple KPI's, for the first objective (original model) and the second one simultaneously, it shows that the multiple KPI's has not been allowed. I was wondering if, how we can define multiple KPI's to store the objective function's values (original and LR in the different values)?
Regards
------------------------------
Abbas Omidi
------------------------------
Original Message:
Sent: Mon December 20, 2021 04:49 AM
From: Vincent Beraudier
Subject: Issue to the naming constraints on docplex
m1 is the model, m2 is the solution. It is not easy to follow with such a naming.
m and s would be easier ;-)
* Accessing the x array variables.
``` def GAP()``` return the model mdl. You can return the model and the variables like this ``` return mdl, x```
It will return it as a tuple which can then be accessed via ``` m1, x = GAP() ```
or you can "attach" the x array on the model itself in the GAP method when you create it with ``` mdl.x = x ``` then you will access it with ```x_solution = m1.get_var_value(m2.x[("j1", "m1")])```
*About the KPI
the method Model.minimize is a setter which returns nothing. So kpi is None.
------------------------------
Vincent Beraudier
Original Message:
Sent: Sat December 18, 2021 02:04 AM
From: Abbas Omidi
Subject: Issue to the naming constraints on docplex
Dear Vincent,
Thanks so much for your replying. Before using what you provided in the previous post I would like to know, how we can access the decision variable outside of the function? In my case, I defined a function to call the optimization model and return its attributes.
def GAP(): # Declare variables mdl = Model(name='GAP') idx_x = [(i,j) for i in tasks for j in machines] x = mdl.binary_var_dict(idx_x, name="x"); ''' the model '''if __name__ == '__main__': m1 = GAP()
In the next step, when I want to invoke this variable outside of the defined function I have some issues:
x_solution = m2.get_var_value(m2.x[("j1", "m1")])
In this situation, the x variable cannot be achieved and the solver produces an error as:
AttributeError: 'SolveSolution' object has no attribute 'x'
Also, when I write the kpi function in the first definition that you suggested it works fine, but in the second form it produces the following note:
kpi= mdl.minimize(mdl.sum(x[i,j]*c[i,j] for i in tasks for j in machines));mdl.add_kpi(kpi, "MIP_kpi")============================================DOcplexException: Cannot interpret this as a KPI: None. expecting expression, variable or function
Regards
------------------------------
Abbas Omidi
Original Message:
Sent: Fri December 17, 2021 04:46 AM
From: Vincent Beraudier
Subject: Issue to the naming constraints on docplex
```m2.get_var_value``` is a (undocumented) method.
You need to use arguments with it, for example like ```m2.get_var_value(x[("j1", "m1")])```
The documented method is Solution.get_value
I think your code for the LR expression should be something like:
u = {}for i,t in enumerate(tasks): u[t] = m3.get_constraint_by_index(i).dual_valuekpi = mdl.sum( x[(i,j)]*c[(i,j)] for i in tasks for j in machines) + mdl.sum( u[i]*(1- mdl.sum(x[(i,j)] for j in machines )) for i in tasks)mdl.add_kpi(kpi, "LR_kpi")sol = mdl.solve()kpi_value = sol.kpi_value_by_name("LR_kpi")
------------------------------
Vincent Beraudier
Original Message:
Sent: Thu December 16, 2021 09:21 AM
From: Abbas Omidi
Subject: Issue to the naming constraints on docplex
Dear Vincent,
Many thanks for your comments. It works fine.
Another issue I have faced is that when I want to invoke the value of the decision variables outside of the defined function I cannot get the correct results. The following notation is shown by the solver:
x_solution = m2.get_var_valueprint(x_solution)variables ================================================<bound method SolveSolution.get_var_value of docplex.mp.solution.SolveSolution(obj=18,values={x_j1_m1:1,x_j2_m1:1,x_j..>
Also, I would like to write the LR dual function as follows:
sum{i in tasks, j in machines} x(i,j)*c(i,j) + sum{i in tasks} u(i)*[1-sum{j in machines} x(i,j)]
PS: I have tried to write a minimal working example on colab in this link. Please see that.
Regards
------------------------------
Abbas Omidi
Original Message:
Sent: Wed December 15, 2021 10:30 AM
From: Vincent Beraudier
Subject: Issue to the naming constraints on docplex
```mdl.sum(x[i,j] for j in machines) == 1 for i in tasks``` is a generator.
But docplex and Python deals with iterables so you need to put it into a list via ```[ ]```
So
mdl.add_constraints([mdl.sum(x[i,j] for j in machines) == 1 for i in tasks], "assign");
should work.
------------------------------
Vincent Beraudier
Original Message:
Sent: Mon December 13, 2021 09:37 AM
From: Abbas Omidi
Subject: Issue to the naming constraints on docplex
Dear community team,
I am trying to use docplex on google colab to solve an optimization problem in which I need to label the constraints to invoke their dual values. What I am trying to do is:
mdl.add_constraints(mdl.sum(x[i,j] for j in machines) == 1 for i in tasks, "assign");
When I run the model I get this error:
File "<ipython-input-55-ebac7052607c>", line 46 mdl.add_constraints(mdl.sum(x[i,j] for j in machines) == 1 for i in tasks, "assign"); ^SyntaxError: Generator expression must be parenthesized
As I have seen some examples that define the labeling as I mentioned and they work fine, I was wondering if, where I am doing wrong?
My second question is, how we can invoke the variable's value by relaxing the original problem?
LP = LinearRelaxer.make_relaxed_model(mdl)LP.print_information()results= LP.solve(log_output=True)print("-------------------------------------")LP.report()print("-------------------------------------")X =LP.solution.get_value_dict(x)print(X)
The error is:
DOcplexException Traceback (most recent call last)<ipython-input-57-da511e6cc21e> in <module>() 78 LP.report() 79 print("-------------------------------------")---> 80 X =LP.solution.get_value_dict(x) 81 print(X)7 frames/usr/local/lib/python3.7/dist-packages/docplex/mp/error_handler.py in fatal(self, msg, args) 208 resolved_message = resolve_pattern(msg, args) 209 docplex_error_stop_here()--> 210 raise DOcplexException(resolved_message) 211 212 def fatal_limits_exceeded(self, nb_vars, nb_constraints):DOcplexException: Cannot mix objects from different models in new_binary_constraint. obj1=x_j1_m2, obj2=x_j1_m2
Regards
------------------------------
Abbas Omidi
------------------------------
#DecisionOptimization