Skip to main content

Create truth table of two events

Answered

Comments

4 comments

  • Maliheh Aramon
    • Gurobi Staff Gurobi Staff

    Hi Huib, 

    How should the constraints look like for the scenarios where p = 0 and/or q = 0?

    Do you want to model the constraints below?

    • If p = 0, then q = 0 and r = 1

    If this is the case, you should add the following to your implementation:

    m.addGenConstrIndicator(p, False, q == 0)
    m.addGenConstrIndicator(p, False, r == 1)


    Is this what you are looking for?

    Best regards,
    Maliheh

    0
  • Huib Meulenbelt
    • Investigator
    • Gurobi-versary
    • Conversationalist

    Hi,

    There are two scenarios for `p`

    If p = 1` then r_p_min ≤ r ≤ r_p_max  

    I created this constraint by writing:

    m.addGenConstrIndicator(p, True, r_p_min <= r)
    m.addGenConstrIndicator(p, True, r <= r_p_max)

    Now, I want to model the constraints for the case where `p = 0`

    If p = 0` then r_p_min > r  OR  r > r_p_max  

    I tried the following, but this doesn't work

    m.addGenConstrIndicator(p, False, r_p_min > r)
    m.addGenConstrIndicator(p, False, r > r_p_max)

    Please advice

     

    0
  • Maliheh Aramon
    • Gurobi Staff Gurobi Staff

    I am still struggling to understand what p and q really mean in your optimization problem. It is hard for me to comprehend your problem as an optimization problem. 

    Just focusing on this constraint:

    If p = 0` then r_p_min > r  OR  r > r_p_max  

    Assuming \(r\), \(r_{p, min}\), and \(r_{p, max}\) are integer, one approach is to define two binary variables \(y_1\) and \(y_2\) and \(M\) as a sufficiently large value. Then write:

    \[\begin{align} r \leq (r_{p, min} - 1) + M (1 - y_1) & \notag \\ r  \geq  (r_{p, max} + 1) - M (1- y_2) & \notag \\ y_1 + y_2 \geq 1 - p & \notag \\ y_1 + y_2 \leq 1 + p \end{align}\] 

    If \(p = 0\), the last two constraints ensure \(y_1 + y_2 = 1\) meaning that exactly one of the \(y\)s equals 1. 

    • If \(y_1 = 1, y_2=0\), then \( r \leq (r_{p, min} - 1\)) is enforced and the constraint \(r  \geq  (r_{p, max} + 1) - M\) is redundant.
    • If \(y_1 = 0, y_2=1\), then \( r \leq (r_{p, min} -1) + M\) is redundant and \(r  \geq  (r_{p, max} + 1) \) is enforced. 

    Instead of the last two constraints, you can also use Gurobi's indicator constraint and implement \(\text{if}~ p = 0, \text{then}~ y_1 + y_2 = 1\).
     

    Gurobi has an AI tool called Gurobi AI Modeling Assistant that you might find useful when exploring how to model your problem.

    Best regards,

    Maliheh

    1
  • Huib Meulenbelt
    • Investigator
    • Gurobi-versary
    • Conversationalist

    Hi Maliheh,

    Thank you for your solution. I am getting now the output that I expect

     

    import itertools
    from gurobipy import Model, GRB
    
    
    truth_table = dict.fromkeys(itertools.product([1, 0], repeat=2), 0)
    
    
    r_max = 6
    
    r_p_min = 1.5
    r_p_max = 6
    r_q_min = 4
    r_q_max = 4
    
    M = 10000
    
    model = Model()
    
    p = model.addVar(vtype=GRB.BINARY)
    q = model.addVar(vtype=GRB.BINARY)
    r = model.addVar(vtype=GRB.INTEGER, lb=0, ub=r_max)
    
    i = model.addVar(vtype=GRB.BINARY)
    j = model.addVar(vtype=GRB.BINARY)
    n = model.addVar(vtype=GRB.BINARY)
    m = model.addVar(vtype=GRB.BINARY)
    
    model.addConstr(r <= (r_p_min - 1) + M * (1 - i))
    model.addConstr(r >= (r_p_max + 1) - M * (1 - j))
    model.addGenConstrIndicator(p, False, i + j == 1)
    model.addGenConstrIndicator(p, True, r_p_min <= r)
    model.addGenConstrIndicator(p, True, r <= r_p_max)
    
    model.addConstr(r <= (r_q_min - 1) + M * (1 - n))
    model.addConstr(r >= (r_q_max + 1) - M * (1 - m))
    model.addGenConstrIndicator(q, False, n + m == 1)
    model.addGenConstrIndicator(q, True, r_q_min <= r)
    model.addGenConstrIndicator(q, True, r <= r_q_max)
    
    model.Params.PoolSearchMode = 2
    model.optimize()
    
    for s in range(model.SolCount):
        model.setParam(GRB.Param.SolutionNumber, s)
        truth_table[p.Xn, q.Xn] = 1
        print(f'r: {r.Xn}, p: {p.Xn}, q: {q.Xn}')
    
    print(truth_table)
    0

Please sign in to leave a comment.