-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathinstance_generator.py
More file actions
115 lines (88 loc) · 3.58 KB
/
Copy pathinstance_generator.py
File metadata and controls
115 lines (88 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# Instance generation for the moultiple couriers problem
import os.path
import numpy as np
import random
import argparse
from utils import *
# Minizinc library classes to create the distances matrix
from minizinc import Model, Solver, Instance
N_INSTANCES = 1
couriers_items = [(3, 10)] # list of generation
SYMMETRIC = False
def generate_instance(n_couriers, n_items, filename, seed=42, max_courier_load=30):
"""
This function takes in input the number of couriers and the number of items,
it generates and saves the instance
:return:
"""
random.seed(seed)
np.random.seed(seed)
# Couriers size list
couriers_size = [random.randint(max_courier_load-5, max_courier_load) for _ in range(n_couriers)]
# Max item size for the instance
total_size = sum(couriers_size)
max_item_size = total_size // n_items
# Objects size list
objects_size = [random.randint(max_item_size-3, max_item_size + 1) for _ in range(n_items)]
# Generate the distances matrix
distances = get_distances(n_items, seed)
# Create the instance file
f = open(filename + ".txt", 'w')
f.write(str(n_couriers) + '\n')
f.write(str(n_items) + '\n')
f.write(' '.join(str(e) for e in couriers_size) + '\n')
f.write(' '.join(str(e) for e in objects_size) + '\n')
for line in distances:
f.write(' '.join(str(e) for e in line) + '\n')
f.close()
def get_distances(n_items, seed):
'''
Calls a minizinc model to generate the distances matrix
in such a way that it respects the triangular inequality
:param n_items: number of items (shapes the matrix)
:param seed: seed for the random generator of the miniZinc model
:return: the distances matrix
'''
# Create the model
model = Model("./instance_generator.mzn")
solver = Solver.lookup("gecode")
instance = Instance(solver, model)
# Set the model parameters
instance["symmetric"] = SYMMETRIC
instance["n"] = n_items
result = instance.solve(random_seed = seed)
distance = result["matrix"]
return distance
def generate_graph_instace(filename, data):
f = open(filename + ".dzn", 'w')
n_couriers, n_items, couriers_size, objects_size, starting_nd, ending_nd, weights, n_edges = data
f.write("courier = " + str(n_couriers) + ';\n')
f.write("items = " + str(n_items) + ';\n')
f.write("courier_size = " + str(couriers_size) + ';\n')
f.write("item_size = " + str(objects_size) + ';\n')
f.write("starting_nd = " + str(starting_nd) + ';\n')
f.write("ending_nd = " + str(ending_nd) + ';\n')
f.write("weights = " + str(weights) + ';\n')
f.write("n_edges = " + str(n_edges) + ';\n')
f.close()
def generator(path, pair_dimension):
"""
The function takes in input the path where it will be saved the instances and pair dimension
which is a list of couple (number_couriers, number_items) in order to generate different instances for
a different dimension for items and couriers
"""
if not os.path.exists(path):
os.makedirs(path)
for el in pair_dimension:
for i in range(N_INSTANCES):
courier = el[0]
item = el[1]
generate_instance(courier,item, path + "instance_" + str(courier) + "_" + str(item) + "_" + str(i), seed=i+1)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", help="Directory where the instance txt files will be created", default="input",
type=str)
args = parser.parse_args()
generator("./" + args.input + "/", couriers_items)
if __name__ == '__main__':
main()