OR-TOOLS:具有交付模式的 PCVRP

OR-TOOLS: PCVRP with delivery patterns

请帮我解决周期性的有能力的车辆路径问题。

在 google 组中找到相同的问题 here

我要建模的内容:

每个客户每次发货的需求是相同的,每天执行一次发货

所以我们有一组客户必须由一个 depo 交付。多种车辆类型可用于该工作。服务日期是灵活的,因为只有频率是固定给客户的,但是有多种可能性来满足需求。

到目前为止我做了什么:

对于需求矩阵,我使用了相同的技巧。在 4 个客户 + 1 个仓库的情况下,需求矩阵可能如下所示

   [[0, 3, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0, 0, 3, 4, 5, 2, 0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2]]

第一个列表中的第二个条目 (3) 和第二个列表中的第 7 个条目 (3) 是针对同一客户的,只是在两个不同的日子。节点已复制。

到目前为止效果很好。但这不是我想做的。

我确实为每个客户每天手动分配需求,但我想通过为每个客户选择的交付模式分配需求。

模型可以将模式 [1,0,1] 分配给一个客户,频率为 2,将模式 [0,0,1] 分配给另一客户。这将导致有可能在第 3 天计划一次结合这两种需求的旅行。

我需要帮助来定义管理模式分配给客户的维度,从而产生“灵活”的需求矩阵。

感谢您的帮助。

完整代码:

"""Periodic Capacited Vehicles Routing Problem (PCVRP)."""

from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
import numpy as np

def dublicate_nodes(base_distance_matrix, num_days):
    matrix = []
    for i in range(num_days):
        day_element = []
        for node in range(len(base_distance_matrix)):
            node_element = []
            for day in range(num_days):
                node_element.append(base_distance_matrix[node])
            day_element.append(np.concatenate(node_element).tolist())
        matrix.extend(day_element)
    #print(matrix)
    return matrix

def depo_nodes(num_days, num_verhicles, num_nodes):
    depo_array = []
    for day in range(num_days):
        for veh in range(int(num_verhicles/num_days)):
            depo_array.append(day*num_nodes)
    #print(depo_array)
    return depo_array

def veh_types_costs(cost_array, num_per_type, num_days):
    cost_array_km = []
    for day in range(num_days):
        for i in range(len(cost_array)):
            for num in range(num_per_type[i]):
                cost_array_km.append(cost_array[i])
    #print(cost_array_km)
    return(cost_array_km)

def veh_capacity_matrix(num_vehicle_per_type, vehicle_capacity_type, num_days):
    matrix= []
    for index in range(num_days):
        matrix_element = []
        for day in range(num_days):
            for i, num in enumerate(num_vehicle_per_type):
                for times in range(num):
                    if day == index:
                        matrix_element.append(vehicle_capacity_type[i]);
                    else:
                        matrix_element.append(0)
        matrix.append(matrix_element)
    #print(matrix)
    return matrix


def create_data_model():
    data = {}
    data["num_days"] = 3 #Anzahl Tage

    ### Definition der Fahrezugtypen
    data["num_vehicle_per_type"] = [1, 2] #Anzahl Fahrzeuge pro Typ
    data["vehicle_costs_type_per_km"] = [1, 0.01] #Kosten pro km pro Fahrzeugtyp
    data["vehicle_costs_type_per_stop"] = [1, 1000] #Kosten pro Stop pro Fahrzeugtyp
    data['price_per_km'] = veh_types_costs(data["vehicle_costs_type_per_km"], data["num_vehicle_per_type"], data["num_days"]) #Matrix für price_per_km je Fahrzeug ertsellen
    data["price_per_stop"] = veh_types_costs(data["vehicle_costs_type_per_stop"], data["num_vehicle_per_type"], data["num_days"])
    data["vehicle_capacity_type"] = [10, 15]  # Kapaität pro Fahrzeugtyp
    data['vehicle_capacities_matrix'] = veh_capacity_matrix(data["num_vehicle_per_type"], data["vehicle_capacity_type"], data["num_days"]) #Kapazitäten pro Fahrzeugs pro Tag
    print('vehicle_capacities_matrix')
    print(data['vehicle_capacities_matrix'])

    data["num_vehicles_per_day"] = sum(data["num_vehicle_per_type"]) #Gesamtanzahl der Fahrzeuge pro Tag
    data['num_vehicles'] = data["num_days"] * data["num_vehicles_per_day"]# Gesamtanzahl der Fahrzeuge in gesamten Zeitraum

    ###Distanzmatrix bestimmen
    data["base_distance_matrix"] = [
        [
            0, 548, 776, 696, 582
        ],
        [
            548, 0, 684, 308, 194
        ],
        [
            776, 684, 0, 992, 878
        ],
        [
            696, 308, 992, 0, 114
        ],
        [
            582, 194, 878, 114, 0
        ]
    ] #Distanzmatrix mit allen Kunden einzeln
    data['distance_matrix'] = dublicate_nodes(data["base_distance_matrix"], data["num_days"])  # Distanzmatrix mit mehrfachen Nodes pro Kunden, je Tag ein Node

    ###Start und Ende festlegen
    data["num_nodes"] = len(data["base_distance_matrix"])  # Anzahl Kunden
    data['starts'] = depo_nodes(data["num_days"], data['num_vehicles'], data["num_nodes"]) #Deponodes (Start) für die einzelnen Fahrzeuge (Tage)
    data['ends'] = depo_nodes(data["num_days"], data['num_vehicles'], data["num_nodes"]) #Deponodes (Ende) für die einzelnen Fahrzeuge (Tage)

    ###Demand pro Kunde
    data['demands_matrix'] =     [[0, 3, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0, 3, 4, 5, 2, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2]] #Demandmatrix mit je einer list pro Tag
    return data


def print_solution(data, manager, routing, solution):
        """Prints solution on console."""
        total_distance = 0
        total_load = 0


        for vehicle_id in range(data['num_vehicles']):

            if vehicle_id % data["num_vehicles_per_day"] == 0:
                print(("------Tag {}------").format(int(vehicle_id/data["num_vehicles_per_day"])))

            if routing.IsVehicleUsed(assignment= solution, vehicle=vehicle_id) == False:
                continue


            index = routing.Start(vehicle_id)
            if vehicle_id >= data["num_vehicles_per_day"]:
                plan_output = 'Route for vehicle {}:\n'.format(abs(vehicle_id-data["num_vehicles_per_day"]*int(vehicle_id/data["num_vehicles_per_day"])))
            else:
                plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
            route_costs = 0
            route_load = 0
            while not routing.IsEnd(index):
                node_index = manager.IndexToNode(index)

                capacity_ID = int(vehicle_id/data["num_vehicles_per_day"])
                route_load += data['demands_matrix'][capacity_ID][node_index]
                plan_output += ' {0} Load({1}) -> '.format(node_index, route_load)
                previous_index = index
                index = solution.Value(routing.NextVar(index))
                route_costs += routing.GetArcCostForVehicle(
                    previous_index, index, vehicle_id)
            plan_output += ' {0} Load({1})\n'.format(manager.IndexToNode(index),
                                                     route_load)
            plan_output += 'Costs of the route: {}€\n'.format(route_costs)
            plan_output += 'Load of the route: {}\n'.format(route_load)
            print(plan_output)
            total_distance += route_costs
            total_load += route_load
        print('Total costs of all routes: {}€'.format(total_distance))
        print('Total load of all routes: {}'.format(total_load))


def main():
    """Periodic CVRP problem."""
    # Instantiate the data problem.
    data = create_data_model()

    # Create the routing index manager.
    manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['starts'],
                                           data['ends'])

    # Create Routing Model.
    routing = pywrapcp.RoutingModel(manager)

    ### Kostenfunktion je Fahrzeug festlegen ###
    def create_cost_callback(dist_matrix, km_costs, stop_costs):
        # Create a callback to calculate distances between cities.

        def distance_callback(from_index, to_index):
            from_node = manager.IndexToNode(from_index)
            to_node = manager.IndexToNode(to_index)
            return int(dist_matrix[from_node][to_node]) * (km_costs) + (stop_costs)

        return distance_callback

    for i in range(data['num_vehicles']):
        cost_callback = create_cost_callback(data['distance_matrix'], data["price_per_km"][i],
                                             data["price_per_stop"][i])  # Callbackfunktion erstellen
        cost_callback_index = routing.RegisterTransitCallback(cost_callback)  # registrieren
        routing.SetArcCostEvaluatorOfVehicle(cost_callback_index, i)  # Vehicle zuordnen


    #Define Capacities for Vehicles for every Day
    def create_demand_callback(demand_matrix, demand_index):
        # Create a callback to calculate capacity usage.

        def demand_callback(from_index):
            #Returns the demand of the node.
            # Convert from routing variable Index to demands NodeIndex.
            from_node = manager.IndexToNode(from_index)
            return demand_matrix[demand_index][from_node]

        return demand_callback

    for i in range(data["num_days"]): #Jedes Fahrzeug hat pro Tag eine andere Kapazität
        demand_callback = create_demand_callback(data['demands_matrix'], i)
        demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback)
        dimension_name = 'Capacity_day_{}'.format(i)

        routing.AddDimensionWithVehicleCapacity(
            demand_callback_index,
            0,  # null capacity slack
            data['vehicle_capacities_matrix'][i],  # vehicle maximum capacities
            True,  # start cumul to zero
            dimension_name)


    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC)
    search_parameters.time_limit.FromSeconds(1)

    # Solve the problem.
    solution = routing.SolveWithParameters(search_parameters)

    # Print solution on console.
    if solution:
        print_solution(data, manager, routing, solution)

    return solution

if __name__ == '__main__':
    solution_array = []
    solution = main()

所以我找到了解决问题的方法。

超过 40 个客户的问题的解决时间可能会更好。

我将不胜感激改进建议。

"""Periodic Capacited Vehicles Routing Problem with delivery pattern(PCVRP)."""

from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
import numpy as np
import random
import math
import pandas as pd

def dublicate_nodes(base_distance_matrix, num_days):
    matrix = []
    for i in range(num_days):
        day_element = []
        for node in range(len(base_distance_matrix)):
            node_element = []
            for day in range(num_days):
                node_element.append(base_distance_matrix[node])
            day_element.append(np.concatenate(node_element).tolist())
        matrix.extend(day_element)
    #print(matrix)
    return matrix

def depo_nodes(num_days, num_verhicles, num_nodes):
    depo_array = []
    for day in range(num_days):
        for veh in range(int(num_verhicles/num_days)):
            depo_array.append(day*num_nodes)
    #print(depo_array)
    return depo_array

def veh_types_costs(cost_array, num_per_type, num_days):
    cost_array_km = []
    for day in range(num_days):
        for i in range(len(cost_array)):
            for num in range(num_per_type[i]):
                cost_array_km.append(cost_array[i])
    #print(cost_array_km)
    return(cost_array_km)

def veh_capacity_matrix(num_vehicle_per_type, vehicle_capacity_type, num_days):
    matrix= []
    for index in range(num_days):
        matrix_element = []
        for day in range(num_days):
            for i, num in enumerate(num_vehicle_per_type):
                for times in range(num):
                    if day == index:
                        matrix_element.append(vehicle_capacity_type[i]);
                    else:
                        matrix_element.append(0)
        matrix.append(matrix_element)
    #print(matrix)
    return matrix

def dist_matrix(koordianten):
    matrix =[]


    for k_1 in koordianten:
        matrix_element = []
        for k_2 in koordianten:
            matrix_element.append(np.linalg.norm(k_1-k_2))
        matrix.append(matrix_element)
    #print(matrix)
    return matrix

def demand_matrix(demand_matrix_day,num_days):
    matrix = []
    for index in range(num_days):
        matrix_element = []
        for day in range(num_days):
            if day == index:
                matrix_element = matrix_element +demand_matrix_day
            else:
                matrix_element = matrix_element +(list(np.zeros(len(demand_matrix_day))))
        matrix.append(matrix_element)
    return matrix

def kunden_indizes(ID_list, num_days):
    indizes = {}
    for ID in ID_list:
        indizes[ID] = []

    for index, key in enumerate(indizes):
        for i in range(len(ID_list)*num_days):
            if (i % len(ID_list)) == index:
                indizes[key].append(i)

    #print(indizes)
    return indizes

def create_data_model(node_num):
    data = {}
    data["num_days"] = 5 #Anzahl Tage

    ###Kundenset
    num_IDs = node_num
    base = [0]

    data["IDs"] = list(range(0, num_IDs))
    #data["IDs"] = [0, 1, 2, 3, 4]
    print(data["IDs"])

    data["demand"] = [random.randint(1,30) for i in range(0,num_IDs)]
    #data["demand"] =[0, 16, 8, 1, 7]
    data["demand"][0] = 0
    print("demand", data["demand"])

    data["frequenz"] = [random.randint(1,5) for i in range(0,num_IDs)]
    #data["frequenz"] =[0, 3, 5, 2, 1]
    data["frequenz"][0] = 0
    print("freq ",data["frequenz"])

    summe_dem =0
    for index, demand in enumerate(data["demand"]):
        summe_dem += data["demand"][index] * data["frequenz"][index]

    print("DEMANDSUMME: ",summe_dem)

    data["koordianten"] = np.random.rand(num_IDs, 2)*1000
    #data["koordianten"] = np.array([(0, 0), (4, 0), (4, 4), (0, 4), (3, 3)])*100
    data["koordianten"][0] = (0,0)
    #print("koord ", data["koordianten"])

    data["PAT"] = {
        5:
            [[1, 1, 1, 1, 1]],
        4:
            [[0, 1, 1, 1, 1],
             [1, 0, 1, 1, 1],
             [1, 1, 0, 1, 1],
             [1, 1, 1, 0, 1],
             [1, 1, 1, 1, 0]],

        3: [[0, 1, 0, 1, 1],
            [1, 0, 1, 0, 1],
            [1, 1, 0, 1, 0],
            [0, 1, 1, 0, 1],
            [1, 0, 1, 1, 0],
            ],

        2: [[1, 0, 1, 0, 0],
            [0, 1, 0, 1, 0],
            [0, 0, 1, 0, 1],
            [1, 0, 0, 1, 0],
            [0, 1, 0, 0, 1]],

        1: [[1, 0, 0, 0, 0],
            [0, 1, 0, 0, 0],
            [0, 0, 1, 0, 0],
            [0, 0, 0, 1, 0],
            [0, 0, 0, 0, 1]],
    }

    ### Definition der Fahrezugtypen

    data["vehicle_costs_type_per_km"] = [1, 0.01] #Kosten pro km pro Fahrzeugtyp
    data["vehicle_costs_type_per_stop"] = [1, 1000] #Kosten pro Stop pro Fahrzeugtyp
    data["vehicle_capacity_type"] = [100, 200]  # Kapaität pro Fahrzeugtyp
    data["num_vehicle_per_type"] = [math.ceil(summe_dem /data["vehicle_capacity_type"][0]), math.ceil(summe_dem /data["vehicle_capacity_type"][1])]  # Anzahl Fahrzeuge pro Typ
    data['price_per_km'] = veh_types_costs(data["vehicle_costs_type_per_km"], data["num_vehicle_per_type"], data["num_days"]) #Matrix für price_per_km je Fahrzeug ertsellen
    data["price_per_stop"] = veh_types_costs(data["vehicle_costs_type_per_stop"], data["num_vehicle_per_type"], data["num_days"])

    data['vehicle_capacities_matrix'] = veh_capacity_matrix(data["num_vehicle_per_type"], data["vehicle_capacity_type"], data["num_days"]) #Kapazitäten pro Fahrzeugs pro Tag
    #print('vehicle_capacities_matrix')
    #print(data['vehicle_capacities_matrix'])

    data["num_vehicles_per_day"] = sum(data["num_vehicle_per_type"]) #Gesamtanzahl der Fahrzeuge pro Tag
    data['num_vehicles'] = data["num_days"] * data["num_vehicles_per_day"]# Gesamtanzahl der Fahrzeuge in gesamten Zeitraum

    ###Distanzmatrix bestimmen
    data["base_distance_matrix"] = dist_matrix(data["koordianten"])
    data['distance_matrix'] = dublicate_nodes(data["base_distance_matrix"], data["num_days"])  # Distanzmatrix mit mehrfachen Nodes pro Kunden, je Tag ein Node

    ###Start und Ende festlegen
    data["num_nodes"] = len(data["base_distance_matrix"])  # Anzahl Kunden
    data['starts'] = depo_nodes(data["num_days"], data['num_vehicles'], data["num_nodes"]) #Deponodes (Start) für die einzelnen Fahrzeuge (Tage)
    data['ends'] = depo_nodes(data["num_days"], data['num_vehicles'], data["num_nodes"]) #Deponodes (Ende) für die einzelnen Fahrzeuge (Tage)

    ###Demand pro Kunde
    data["kunden_indizes"] = kunden_indizes(data["IDs"], data["num_days"])

    data["demands_matrix"] = demand_matrix(demand_matrix_day=data["demand"], num_days=data["num_days"])
    #print(data["demands_matrix"])

    return data

def print_solution(data, manager, routing, solution):
        """Prints solution on console."""
        total_distance = 0
        total_load = 0



        for vehicle_id in range(data['num_vehicles']):

            if vehicle_id % data["num_vehicles_per_day"] == 0:
                print(("------Tag {}------").format(int(vehicle_id/data["num_vehicles_per_day"])))

            if routing.IsVehicleUsed(assignment= solution, vehicle=vehicle_id) == False:
                continue


            index = routing.Start(vehicle_id)
            if vehicle_id >= data["num_vehicles_per_day"]:
                plan_output = 'Route for vehicle {}:\n'.format(abs(vehicle_id-data["num_vehicles_per_day"]*int(vehicle_id/data["num_vehicles_per_day"])))
            else:
                plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
            route_costs = 0
            route_load = 0
            while not routing.IsEnd(index):
                node_index = manager.IndexToNode(index)

                capacity_ID = int(vehicle_id/data["num_vehicles_per_day"])
                route_load += data['demands_matrix'][capacity_ID][node_index]
                plan_output += ' {0} Load({1}) -> '.format(node_index, route_load)
                previous_index = index
                index = solution.Value(routing.NextVar(index))
                route_costs += routing.GetArcCostForVehicle(
                    previous_index, index, vehicle_id)
            plan_output += ' {0} Load({1})\n'.format(manager.IndexToNode(index),
                                                     route_load)
            plan_output += 'Costs of the route: {}€\n'.format(route_costs)
            plan_output += 'Load of the route: {}\n'.format(route_load)
            print(plan_output)
            total_distance += route_costs
            total_load += route_load
        print('Total costs of all routes: {}€'.format(total_distance))
        print('Total load of all routes: {}'.format(total_load))


def main(node_num):
    """Periodic CVRP problem."""
    # Instantiate the data problem.
    data = create_data_model(node_num)

    # Create the routing index manager.
    manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['starts'],
                                           data['ends'])

    # Create Routing Model.
    routing = pywrapcp.RoutingModel(manager)

    ### Kostenfunktion je Fahrzeug festlegen ###
    def create_cost_callback(dist_matrix, km_costs, stop_costs):
        # Create a callback to calculate distances between cities.

        def distance_callback(from_index, to_index):
            from_node = manager.IndexToNode(from_index)
            to_node = manager.IndexToNode(to_index)
            return int(dist_matrix[from_node][to_node]) * (km_costs) + (stop_costs)

        return distance_callback

    for i in range(data['num_vehicles']):
        cost_callback = create_cost_callback(data['distance_matrix'], data["price_per_km"][i],
                                             data["price_per_stop"][i])  # Callbackfunktion erstellen
        cost_callback_index = routing.RegisterTransitCallback(cost_callback)  # registrieren
        routing.SetArcCostEvaluatorOfVehicle(cost_callback_index, i)  # Vehicle zuordnen


    #Define Capacities for Vehicles for every Day
    def create_demand_callback(demand_matrix, demand_index):
        # Create a callback to calculate capacity usage.

        def demand_callback(from_index):
            #Returns the demand of the node.
            # Convert from routing variable Index to demands NodeIndex.
            from_node = manager.IndexToNode(from_index)
            return demand_matrix[demand_index][from_node]

        return demand_callback

    for i in range(data["num_days"]): #Jedes Fahrzeug hat pro Tag eine andere Kapazität
        demand_callback = create_demand_callback(data['demands_matrix'], i)
        demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback)
        dimension_name = 'Capacity_day_{}'.format(i)

        routing.AddDimensionWithVehicleCapacity(
            demand_callback_index,
            0,  # null capacity slack
            data['vehicle_capacities_matrix'][i],  # vehicle maximum capacities
            True,  # start cumul to zero
            dimension_name)

    #Drop visits that would exceed the frequency
    for index, key in enumerate(data["kunden_indizes"]):
        if index == 0:
            continue

        #routing.solver().Add(sum(routing.ActiveVar(manager.NodeToIndex(i)) for i in data["kunden_indizes"][key]) == data["frequenz"][index])

    bool_array = []
    for index, freq in enumerate(data["frequenz"]):
        if index == 0:
            continue
        bool_array_part =[]
        for index_pat, pat in enumerate(data["PAT"][freq]):
            #print(index,freq,index_pat)
            bool_name = str(index) +str(freq) + str(index_pat)
            bool_array_part.append(routing.solver().BoolVar(bool_name))
        bool_array.append(bool_array_part)
    #print(bool_array)

    for i in bool_array:
        routing.solver().Add(sum(i) == 1)

    node_array = []
    for index, freq in enumerate(data["frequenz"]):
        if index == 0:
            continue
        node_array_part = []
        for index_pat, pat in enumerate(data["PAT"][freq]):
            node_array_sub_part = []
            for index_day, day_value in enumerate(pat):
                if day_value == 1:
                    node_array_sub_part.append(data["kunden_indizes"][index][index_day])
            #print(node_array_part)
            node_array_part.append(node_array_sub_part)
        node_array.append(node_array_part)
    #print(node_array)

    for index, bool in enumerate(bool_array):
        for i in range(len(bool)):
            #print(node_array[index][i])
            #print(bool_array[index][i])
            routing.solver().Add(sum(routing.ActiveVar(manager.NodeToIndex(i)) for i in node_array[index][i]) * bool_array[index][i] == bool_array[index][i] * len(node_array[index][i]))


    #routing.solver().Add(routing.ActiveVar(manager.NodeToIndex(5)) == 1)

    penalty = 0
    for node in range(0, len(data['distance_matrix'])):
        if node in data["kunden_indizes"][0]:
            continue
        else:
            routing.AddDisjunction([manager.NodeToIndex(node)], penalty)


    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC)
    #search_parameters.time_limit.FromSeconds(300)

    # Solve the problem.
    solution = routing.SolveWithParameters(search_parameters)

    # Print solution on console.
    if solution:

        print_solution(data, manager, routing, solution)
        print()
        print("Statistics")
        print('  - wall time : %f s' % (int(routing.solver().WallTime())/1000))
        solvingtime = int(routing.solver().WallTime())/1000

    return solvingtime

if __name__ == '__main__':
    node_num_array = [10,20,30,40,50,60,70,80,90,100]
    solvingtime_array = []
    num_array =[]
    for i in node_num_array:
        for j in range(0,4):
            solvingtime = main(i)
            solvingtime_array.append(solvingtime)
            num_array.append(i)
            print(i, "-->",solvingtime)
    print(solvingtime_array)
    print(num_array)
    df_results = pd.DataFrame(data= {"num_nodes":num_array, "solvingtime":solvingtime_array})
    
            #encoding="latin_1", sep=";")
    print(df_results)