Fuzzy Logic Constraints in Gurobi
AnsweredDear All,
I'm trying to insert the trapezoidal fuzzy logic as the capacity constraints in my VRP code. The initial Python code is like this:
def f(r):
a,b,c,d = (20, 30, 40, 50)
if a <= r <= b:
return ((r-a)/(b-a))
if b <= r <= c:
return 1
if c <= r <= d:
return (1-((r-a)/(b-a)))
Then the problem appeared because we have to do vectorization rather than a <= r <= b.
I'm still stuck in the vectorization for this fuzzy logic modelling.
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum, or try Gurobot, our chatbot interface offering instant, expert-level support. -
Hi Putri,
It is not clear to me what exactly you are trying to achieve. Could you please elaborate more on what exactly you are trying to model/implement in Gurobi?
Best regards,
Jaromił0 -
Hi, sorry for the unclear question. I want to ask how to model the membership value of fuzzy logic in Gurobi. In my case, I want to assign the membership value (mv) based on the current quantity (x) with the parameter (a) = desired capacity and (b) = maximum capacity.
if the current quantity in vehicle <=a, then mv = 1
if the current quantity in vehicle < b, then mv = 1/ ((b-x)/(b-a))
then the mv will be included in the obj function:
mdl.setObjective(quicksum(y[i,j,k]*traveltime[i,j]*mv[k] for i,j,k in q))
note: I have 4 vehicles; i,j represent the nodes and k represent the vehicle
0 -
Hi Putri,
Thank your for the clarification. What you are trying to model is the piecewise-linear function
\[\begin{align*}
z = \begin{cases} \frac{r-a}{b-a}&, a \leq r \leq b \\ 1&, b \leq r \leq c\\ 1 - \frac{r-a}{b-a} &, c \leq r \leq d\end{cases}
\end{align*}\]This can be implemented using the addGenConstrPWL method. I would recommend having a look at our documentation on piecewise-linear objectives where we explain modeling piecewise-linear functions.
In general, you will have to add an auxiliary variable \(z\) and compute values at the border points of the segments of the above piecewise-linear function and feed this information to the addGenConstrPWL method.
Best regards,
Jaromił0 -
Hi Jaromil, thank you for your answer. I found this page https://stackoverflow.com/questions/64265698/add-constraint-in-gurobipy-using-conditional-decision-variable and followed the suggestion there.
It works well until I modified the code for my research and I got this error:

I've been using 'mdl' for the whole code, and this is the only error. Could you please help me?
0 -
Hi Putri,
Python's error messages can be a bit cryptic here, and often point to the code after the issue, not the issue itself. In this case it looks like you just have a mismatched bracket at this line which causes the syntax error:
mdl.addConstr((quicksum(x[i,k]) <= z.prod([3000, 3500]))
# ^ this second bracket isn't neededBest regards,
Simon0 -
Hi Simon,
It works! Thank you.
0 -
Hi Putri,
Please note that with the constraints from the stackexchange post, you are modeling nothing different than a piecewise-linear function, which can be modeled automatically using Gurobi's addGenConstrPWL method. In case that you are going to model this logic more often, I would recommend having a closer look at piecewise-linear functions and their modeling in Gurobi to make your model construction easier and less error prone.
Best regards,
Jaromił0 -
Hi Jaromil,
I think so. I revised the constraints into the following:

but I encountered a problem to define this. The x[i,k] is the current capacity and m[k] will be the returned value according to the position of x[i,k] .
0 -
Hi Putri,
Your input does not work because you have to provide real values for x points and y points of the PWL function, i.e., no optimization variables are allowed as input for the 3rd and 4th arguments, see addGenConstrPWL documentation.
Adding your function as a PWL constraint would look something like
mdl.addGenConstrPWL(r, x, [20,30,40,40,50], [(20-20)/(30-20),(30-20)/(30-20),1,1-(40-20)/(30-20),1-(40-20)/(30-20)])
Note that I added two values for the point \(r=40\), because there is a jump at \(r=40\) from \(1\) to \(1-\frac{40-20}{30-20} = -1\). You can find all details in our documentation on piecewise-linear objectives.
Best regards,
Jaromił0 -
Hi Jaromil,
Thank you for your great help! It's much simpler and it works!
0
Post is closed for comments.
Comments
11 comments