Skip to main content

Building MIP Model GurobiPy become slow

Answered

Comments

10 comments

  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Do you compare different Gurobi versions? Or something else?
    In which setting is it possible to build and run the model, and in which setting do you get the out-of-memory error?

    0
  • Assia Kamal-idrissi
    Gurobi-versary
    Conversationalist
    First Question

    Im' using the same version of Gurobi which 10.0.3. 
    I'm trying to reexecute the same program in machine with 56 Threads and 500 GB. Its staks in reading the license. Afther that, I got the message "out of memory" (the screenshot below).  Is is related to the cache? 
    I suppose that each time I build a model, it is stored somewhere?

    Thank you.

    0
  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Can you share the code that shows how you re-execute? Do you use the same model object? Do you use the same data?

    0
  • Assia Kamal-idrissi
    Gurobi-versary
    Conversationalist
    First Question

    I'm using the same model object and same data. Here is the model:


    def CVRP(df,time_matrix_truck,customers, nodes, trucks, truck_capacity):
        mdl = Model('CVRP3')
        arc_k = {(i, j , k) for i in nodes for j in nodes for k in trucks if i != j}
        xt = mdl.addVars(arc_k, vtype=GRB.BINARY, name='x')
        mdl.modelSense = GRB.MINIMIZE
        mdl.setObjective(grb.quicksum(time_matrix_truck[i][j] * xt[i, j, k] if i!=j else 0 for i in nodes 
                                      for j in nodes for k in trucks))
        # Constraint 1- Customer is only served once by only one vehicle
        for j in customers:
            mdl.addConstr(grb.quicksum(xt[i, j, k] for i in nodes if i != j for k in trucks) == 1)
        # Constraint 2- Vehicle must depart from and return to deport
        for k in trucks:
            mdl.addConstr(grb.quicksum(xt[0, j, k] for j in customers) == 1)
            #mdl.addConstr(grb.quicksum(xt[i, 0, k] for i in customers) == 1)
        # Constraint 3- Only one vehicle enters and leaves each customer location
        for k in trucks:
            for j in nodes:
                mdl.addConstr(grb.quicksum(xt[i, j, k] if i != j else 0 for i in nodes) 
                              - grb.quicksum(xt[j, i, k] if i != j else 0 for i in nodes) == 0)
        #Constraint 4- Demand must not exceed vehicle cdrone_capacity
        for k in trucks:
            mdl.addConstr(grb.quicksum(df.demand[j] * xt[i, j, k] for i in nodes for j in customers if i != j) <= truck_capacity)
        # Constraint 6: Subtour Elimination
        subtours = []
        for i in nodes[2:]:
            subtours += itertools.combinations(customers, i)
        # Create a list to hold the subtour elimination constraints
        subtour_constraints = []
        for s in subtours:
            for k in trucks:
                subtour_constraints.append(mdl.addConstr(grb.quicksum(xt[i, j, k] if i != j else 0 for i, j in itertools.permutations(s, 2)) <= len(s) - 1))
        return mdl, xt

    And the parameters:
    def solving_model(mdl):
       
        mdl.Params.Presolve = 0
        mdl.Params.TimeLimit = 3600
        mdl.Params.MIPGap = 0.1
        mdl.Params.Threads = 32
        mdl.Params.NodefileStart = 0.5 


        solution = mdl.optimize()
        runTime = mdl.Runtime
        status = mdl.status
        # Check the status and print the results
        if status == grb.GRB.OPTIMAL:
            print('Total Time Travelled:', mdl.objVal)
            print('Running Time:', runTime)
        else:
            print('No optimal solution found')
        return status, runTime
    0
  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Can you also share how you call CVRP and solving_model for the first and the second run?

    0
  • Assia Kamal-idrissi
    Gurobi-versary
    Conversationalist
    First Question

    Yes, sure!

    def main():
        file_path = "/Exps/SA/expSetP/40P/P-n40-k5.vrp"
        dataI = load_data(file_path)
        n = dataI[0]
        nT = int(dataI[1])
        truck_capacity = dataI[2]
        data = dataI[3]
        print(
            "instance: ", n, " customers ", nT, " trucks", truck_capacity, " truck capacity"
        )
        print("-----------------------------DATA--------------------------------")
        print(data)
        distance_truck = distance_matrix_truck(data)
        speedT = 11.176
        time_truck = time_matrix(distance_truck, speedT)
        # Define sets
        #     customers = [x for x in range(1, n)]
        # print("-----------------Customers Set----------\n", customers)
        #     nodes = [0] + customers
        print("-----------------Nodes Set----------\n", nodes)
        trucks = [x for x in range(1, nT + 1)]
        # Modelling
        #     dic_res = dict()
        list_vars = []
        resC = CVRP(data, time_truck, customers, nodes, trucks, truck_capacity)
        mdlT = resC[0]
        xt = resC[1]
        dic_res[mdlT] = xt
        numIter = 1
        for mdl in dic_res:
            print("===================model==========:", mdl)
            name = mdl.ModelName
            if name == "CVRP3":
                xt = dic_res[mdl]
                xd = None
                solving_model(mdl)
                plot_solution(nodes, mdl, data, xt, xd, nT, nD)
                runTimeTot = 0


    if __name__ == "__main__":
        main()
    0
  • Assia Kamal-idrissi
    Gurobi-versary
    Conversationalist
    First Question

    I figure out that the license will finish by Oct 7, 2024. Is the issue related to the fact that the license will expire very soon?

    Thank you

     

    Assia

     

    0
  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    The out-of-memory error is not related to the fact that the license will expire in some days.

    I do not see in the code snippet you sent that the loop \(\texttt{for mdl in dic_res}\) is executed more than once. Could you try to share a (minimal) reproducible example?

    0
  • Assia Kamal-idrissi
    Gurobi-versary
    Conversationalist
    First Question

    I tested on otehr machine. I takes more time to display licence of Gurobi.

    Here is the data:
    NAME : P-n40-k5
    COMMENT : (Augerat et al, Min no of trucks: 5, Best value: 458)
    TYPE : CVRP
    DIMENSION : 40
    EDGE_WEIGHT_TYPE : EUC_2D
    CAPACITY : 140
    NODE_COORD_SECTION
    1 30 40
    2 37 52
    3 49 49
    4 52 64
    5 20 26
    6 40 30
    7 21 47
    8 17 63
    9 31 62
    10 52 33
    11 51 21
    12 42 41
    13 31 32
    14 5 25
    15 12 42
    16 36 16
    17 52 41
    18 27 23
    19 17 33
    20 13 13
    21 57 58
    22 62 42
    23 42 57
    24 16 57
    25 8 52
    26 7 38
    27 27 68
    28 30 48
    29 43 67
    30 58 48
    31 58 27
    32 37 69
    33 38 46
    34 46 10
    35 61 33
    36 62 63
    37 63 69
    38 32 22
    39 45 35
    40 59 15
    DEMAND_SECTION
    1 0
    2 7
    3 30
    4 16
    5 9
    6 21
    7 15
    8 19
    9 23
    10 11
    11 5
    12 19
    13 29
    14 23
    15 21
    16 10
    17 15
    18 3
    19 41
    20 9
    21 28
    22 8
    23 8
    24 16
    25 10
    26 28
    27 7
    28 15
    29 14
    30 6
    31 19
    32 11
    33 12
    34 23
    35 26
    36 17
    37 6
    38 9
    39 15
    40 14
    DEPOT_SECTION
     1
     -1
    EOF

     

     

    Here is a simple main:

    def main():
        file_path = "P-n40-k5.vrp"
        dataI = load_data(file_path)
        n = dataI[0]
        nT = int(dataI[1]) 
        truck_capacity = dataI[2]
        data = dataI[3]
        print("instance: ", n," customers ",nT," trucks", truck_capacity, " truck capacity")
        print("-----------------------------DATA--------------------------------")
        print(data)
        distance_truck = distance_matrix_truck(data)
        speedT = 11.176
        time_truck = time_matrix(distance_truck, speedT)
        customers = [x for x in range(1, n)]
        print("customers ", customers)
        nodes = [0] + customers
        print("-----------------Nodes Set----------\n", nodes)
        trucks = [x for x in range(1, nT+1)]

        mdl = CVRP(data, time_truck, customers, nodes, trucks, truck_capacity)
        print("===================model==========:", mdl)
        solving_model(mdl)

    if __name__ == "__main__":
        main()
    0
  • Marika Karbstein
    Gurobi Staff Gurobi Staff

    Now I understand: it is not the problem that you re-execute the same code twice in one run, and the second time, it gets stuck and crashes with an out-of-memory error.
    Instead, you want to run a code that you think worked before.
    Please note that your number of subtour-constraints explodes with the number of nodes in your model.
    For 21 nodes, the number of subtours is  2,097,130. For 40 nodes, it is already 1,099,511,627,735.
    Hence, this formulation does not work for larger instances.
    So, I assume when you ran the code successfully, you considered a smaller instance with fewer nodes.

    Note: Here are Jupyter notebooks that discuss different ways to model the Capacitated VRP and the VRP.

    0

Please sign in to leave a comment.