Skip to main content

How to ensure truck leaves from starting node?

Answered

Comments

6 comments

  • Official comment
    Simranjit Kaur
    • Gurobi Staff
    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 why not try our AI Gurobot?.
  • Jaromił Najman
    • Gurobi Staff

    Hi John,

    The first syntax error comes from a set of problem in your code.

    First you define the set \(\texttt{set_time}\) and use it as variable index. What you actually mean (I guess), is to use \(\texttt{range(tmax[k])}\) which will produce a variable for every time step \(t \in \{0,\dots,t^k_{\max}\}\). Next, the indices when defining the variables are in wrong order compared to how you want to use them. 
    Then, the terms

    for t in set_time 

    and

    (tmax[k]-1)

    seem off place when reading the constraint you tried to implement in your previous post.

    You should try to better understand what the time set and the nodes set \(G\) mean in your problem formulation. For now, a working code would be

    import gurobipy as gp
    from gurobipy import GRB

    mdl = gp.Model('test')

    location, distance, cost= gp.multidict({("A", "B"):[100,123],
    ("A","C"): [70,134],
    ("B","D"): [82,345],
    ("C","D"): [95,234],
    ("C","E"): [100,453],
    ("E","F"): [77,345],
    ("E","B"): [85,643],
    ("F","C"): [50,332]})

    mxspeed = 120
    p_max = 5
    fuel_saving = .1
    speed = [100, 70, 82, 95, 77, 80, 85, 50]
    G = ['A','B','C','D','E','F']
    trucks, tmax, origin, destination = gp.multidict( {
    'truck1': [2000,'A', 'D'],
    'truck2': [2500,'A', 'E'],
    'truck3': [3400,'B', 'D'] } )

    x= {}
    for k in trucks:
    x[k] = mdl.addVars(tmax[k], location, vtype=GRB.BINARY, name="location")

    for k in trucks:
    truck_start = mdl.addConstr( gp.quicksum( gp.quicksum( x[k][t,e[0],e[1]] for e in location if origin[k] == e[0]) for t in range(tmax[k]-1)) == 1, name="truck_start_"+str(k))

    Regarding the new constraint. It contains 3 \(\forall\) statements. You can think of those as \(\texttt{for}\)-loops, i.e., you need 3 \(\texttt{for}\)-loops to construct the constraints one by one. This can be done as

    for k in trucks:
    for t in range(tmax[k]-1):
    for i in G:
    if i != origin[k] and i != destination[k]:
    mdl.addConstr( gp.quicksum( x[k][t, l[0],l[1]] for l in location if l[1] == i)- gp.quicksum( x[k][t+1,l[0],l[1]] for l in location if l[0] == i) == 0, name="new_constraint_"+str(k))

    Note that you have to check that you loop only over the nodes that are not in the origin or destination set of each truck. Here again, the set \(\texttt{set_time}\) you used seems off place as it holds only a few discrete values.

    Best regards,
    Jaromił

    0
  • John Raphy Karippery
    • Gurobi-versary
    • Investigator
    • Collaborator

    Thank you for helping me.

    I have a lot of confusion with a time parameter.

    Does that mean the Objective function will be something like this? 


    mdl.setObjective(quicksum(cost[i,j] * t for i, j in location for t in range(tmax[k])))

    or 


    mdl.setObjective(quicksum(quicksum(cost[i,j] * t for i, j in location )for t in range(tmax[k])))

    the objective function of our problem consisting of the sum of all truck fuel cost incurring on all edges during every time period.

    Is this code correct? 

    Thank you again. 

    0
  • Jaromił Najman
    • Gurobi Staff

    Given the objective in the article you referenced

    \[\min \sum_t \sum_{e_{ij}\in E} c_{t,ij} \]

    you have to define variable costs for each edge \(e_{ij}\) at each possible time step \(t\). You could do this as

    import gurobipy as gp
    from gurobipy import GRB

    mdl = gp.Model('test')
    location, distance= gp.multidict({("A", "B"):[100],
    ("A","C"): [70],
    ("B","D"): [82],
    ("C","D"): [95],
    ("C","E"): [100],
    ("E","F"): [77],
    ("E","B"): [85],
    ("F","C"): [50]})

    timesteps = 4 # maximum number of timesteps

    c = mdl.addVars(timesteps, location, vtype=GRB.CONTINUOUS, name="costs")

    mdl.setObjective(gp.quicksum( gp.quicksum( c[t,l[0],l[1]] for l in location ) for t in range(timesteps) ), GRB.MINIMIZE)

    Best regards,
    Jaromił

     

    0
  • John Raphy Karippery
    • Gurobi-versary
    • Investigator
    • Collaborator

    Thank you for your help

    I have small changes in the objective function.

    \begin{equation}
    \ Min\ Z=\ \sum_t \sum_{e_{i,j}\ \in E}{x_{i,j}t}
    \end{equation}

    we have to define a time window for each truck. it means that we need a constant time for the early start and a constant for a late finish. AND WE HAVE TO DEFINE THE TIME CONSTRAINT OR IN OUR CASE WE NEED TO MINIMIZE TIME.

    trucks, start ,deadline, origin, destination = gp.multidict( {
    'truck1': [0, 100,'A', 'D'],
    'truck2': [0, 125,'A', 'E'],
    'truck3': [0, 110,'B', 'D'] } )


    x = mdl.addVars(location, trucks, vtype = GRB.BINARY, name = 'x' )
    mdl.setObjective(gp.quicksum(gp.quicksum(x[k,i,j]*t for i, j in location for k in trucks) for t in deadline))

    I think this makes more sence.
    please check the code is right.

    Thank you 

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi John,

    I cannot tell whether the objective makes sense on the modeling level. Regarding the code, you have defined the \(x\) variables and the \(\texttt{location}\) set differently in your previous messages and posts, so you have to access them the same way as before. Unless, these \(x\) variables shall be different from the ones you used in your previous messages and posts.

    Altogether, I would recommend to first fully write down the model you want to implement on a piece of paper (or similar), i.e., define the objective function, all constraints, all variables first, and start the implementation only if you are sure that the model you developed provides the properties you want.

    Best regards,
    Jaromił

    0

Post is closed for comments.