PySCIPOpt  5.1.1
Python Interface for the SCIP Optimization Suite
read_tsplib.py
Go to the documentation of this file.
1 
3 """
4 Functions provided:
5  * read_tsplib - read a symmetric tsp instance
6  * read_atsplib - asymmetric
7 
8 Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012
9 """
10 
11 import gzip
12 import math
13 
14 
15 def distL2(x1, y1, x2, y2):
16  """Compute the L2-norm (Euclidean) distance between two points.
17 
18  The distance is rounded to the closest integer, for compatibility
19  with the TSPLIB convention.
20 
21  The two points are located on coordinates (x1,y1) and (x2,y2),
22  sent as parameters"""
23  xdiff = x2 - x1
24  ydiff = y2 - y1
25  return int(math.sqrt(xdiff * xdiff + ydiff * ydiff) + .5)
26 
27 
28 def distL1(x1, y1, x2, y2):
29  """Compute the L1-norm (Manhattan) distance between two points.
30 
31  The distance is rounded to the closest integer, for compatibility
32  with the TSPLIB convention.
33 
34  The two points are located on coordinates (x1,y1) and (x2,y2),
35  sent as parameters"""
36  return int(abs(x2 - x1) + abs(y2 - y1) + .5)
37 
38 
39 def distLinf(x1, y1, x2, y2):
40  """Compute the Linfty distance between two points (see TSPLIB documentation)"""
41  return int(max(abs(x2 - x1), abs(y2 - y1)))
42 
43 
44 def distATT(x1, y1, x2, y2):
45  """Compute the ATT distance between two points (see TSPLIB documentation)"""
46  xd = x2 - x1
47  yd = y2 - y1
48  rij = math.sqrt((xd * xd + yd * yd) / 10.)
49  tij = int(rij + .5)
50  if tij < rij:
51  return tij + 1
52  else:
53  return tij
54 
55 
56 def distCEIL2D(x1, y1, x2, y2):
57  """returns smallest integer not less than the distance of two points"""
58  xdiff = x2 - x1
59  ydiff = y2 - y1
60  return int(math.ceil(math.sqrt(xdiff * xdiff + ydiff * ydiff)))
61 
62 
63 def distGEO(x1, y1, x2, y2):
64  print("Implementation is wrong")
65  assert False
66  PI = 3.141592
67  deg = int(x1 + .5)
68  min_ = x1 - deg
69  lat1 = PI * (deg + 5. * min_ / 3) / 180.
70  deg = int(y1 + .5)
71  min_ = y1 - deg
72  long1 = PI * (deg + 5. * min_ / 3) / 180.
73  deg = int(x2 + .5)
74  min_ = x2 - deg
75  lat2 = PI * (deg + 5. * min_ / 3) / 180.
76  deg = int(y2 + .5)
77  min_ = y2 - deg
78  long2 = PI * (deg + 5. * min_ / 3) / 180.
79 
80  RRR = 6378.388
81  q1 = math.cos(long1 - long2);
82  q2 = math.cos(lat1 - lat2);
83  q3 = math.cos(lat1 + lat2);
84  return int(RRR * math.acos(.5 * ((1. + q1) * q2 - (1. - q1) * q3)) + 1.)
85 
86 
88  c = {}
89  i, j = 1, 1
90  while True:
91  line = f.readline()
92  for data in line.split():
93  c[j, i] = int(data)
94  j += 1
95  if j > i:
96  i += 1
97  j = 1
98  if i > n:
99  return range(1, n + 1), c, None, None
100 
101 
103  c = {}
104  i, j = 1, 2
105  while True:
106  line = f.readline()
107  for data in line.split():
108  c[i, j] = int(data)
109  j += 1
110  if j > n:
111  i += 1
112  j = i + 1
113  if i == n:
114  return range(1, n + 1), c, None, None
115 
116 
118  c = {}
119  i, j = 1, 1
120  while True:
121  line = f.readline()
122  for data in line.split():
123  c[i, j] = int(data)
124  j += 1
125  if j > n:
126  i += 1
127  j = i
128  if i == n:
129  return range(1, n + 1), c, None, None
130 
131 
133  c = {}
134  i, j = 1, 1
135  while True:
136  line = f.readline()
137  for data in line.split():
138  if j > i:
139  c[i, j] = int(data)
140  j += 1
141  if j > n:
142  i += 1
143  j = 1
144  if i == n:
145  return range(1, n + 1), c, None, None
146 
147 
148 def read_tsplib(filename):
149  "basic function for reading a symmetric problem in the TSPLIB format"
150  "data is stored in an upper triangular matrix"
151  "NOTE: some distance types are not handled yet"
152  if filename[-3:] == ".gz":
153  f = gzip.open(filename, "rt")
154  else:
155  f = open(filename)
156 
157  line = f.readline()
158  while line.find("DIMENSION") == -1:
159  line = f.readline()
160  n = int(line.split()[-1])
161 
162  while line.find("EDGE_WEIGHT_TYPE") == -1:
163  line = f.readline()
164 
165  if line.find("EUC_2D") != -1:
166  dist = distL2
167  elif line.find("MAN_2D") != -1:
168  dist = distL1
169  elif line.find("MAX_2D") != -1:
170  dist = distLinf
171  elif line.find("ATT") != -1:
172  dist = distATT
173  elif line.find("CEIL_2D") != -1:
174  dist = distCEIL2D
175  # elif line.find("GEO") != -1:
176  # print("geographic"
177  # dist = distGEO
178  elif line.find("EXPLICIT") != -1:
179  while line.find("EDGE_WEIGHT_FORMAT") == -1:
180  line = f.readline()
181  if line.find("LOWER_DIAG_ROW") != -1:
182  while line.find("EDGE_WEIGHT_SECTION") == -1:
183  line = f.readline()
184  return read_explicit_lowerdiag(f, n)
185  if line.find("UPPER_ROW") != -1:
186  while line.find("EDGE_WEIGHT_SECTION") == -1:
187  line = f.readline()
188  return read_explicit_upper(f, n)
189  if line.find("UPPER_DIAG_ROW") != -1:
190  while line.find("EDGE_WEIGHT_SECTION") == -1:
191  line = f.readline()
192  return read_explicit_upperdiag(f, n)
193  if line.find("FULL_MATRIX") != -1:
194  while line.find("EDGE_WEIGHT_SECTION") == -1:
195  line = f.readline()
196  return read_explicit_matrix(f, n)
197  print("error reading line " + line)
198  raise (Exception)
199  else:
200  print("cannot deal with '%s' distances" % line)
201  raise Exception
202 
203  while line.find("NODE_COORD_SECTION") == -1:
204  line = f.readline()
205 
206  x, y = {}, {}
207  while 1:
208  line = f.readline()
209  if line.find("EOF") != -1 or not line: break
210  (i, xi, yi) = line.split()
211  x[i] = float(xi)
212  y[i] = float(yi)
213 
214  V = x.keys()
215  c = {} # dictionary to hold n times n matrix
216  for i in V:
217  for j in V:
218  c[i, j] = dist(x[i], y[i], x[j], y[j])
219 
220  return V, c, x, y
221 
222 
223 def read_atsplib(filename):
224  "basic function for reading a ATSP problem on the TSPLIB format"
225  "NOTE: only works for explicit matrices"
226 
227  if filename[-3:] == ".gz":
228  f = gzip.open(filename, 'r')
229  data = f.readlines()
230  else:
231  f = open(filename, 'r')
232  data = f.readlines()
233 
234  for line in data:
235  if line.find("DIMENSION") >= 0:
236  n = int(line.split()[1])
237  break
238  else:
239  raise IOError("'DIMENSION' keyword not found in file '%s'" % filename)
240 
241  for line in data:
242  if line.find("EDGE_WEIGHT_TYPE") >= 0:
243  if line.split()[1] == "EXPLICIT":
244  break
245  else:
246  raise IOError("'EDGE_WEIGHT_TYPE' is not 'EXPLICIT' in file '%s'" % filename)
247 
248  for k, line in enumerate(data):
249  if line.find("EDGE_WEIGHT_SECTION") >= 0:
250  break
251  else:
252  raise IOError("'EDGE_WEIGHT_SECTION' not found in file '%s'" % filename)
253 
254  c = {}
255  # flatten list of distances
256  dist = []
257  for line in data[k + 1:]:
258  if line.find("EOF") >= 0:
259  break
260  for val in line.split():
261  dist.append(int(val))
262 
263  k = 0
264  for i in range(n):
265  for j in range(n):
266  c[i + 1, j + 1] = dist[k]
267  k += 1
268 
269  return n, c
270 
271 
272 if __name__ == "__main__":
273  import sys
274 
275  # Parse argument
276  if len(sys.argv) < 2:
277  print('Usage: %s instance' % sys.argv[0])
278  exit(1)
279 
280  from read_tsplib import read_tsplib
281 
282  V, c, x, y = read_tsplib(sys.argv[1])
283  print(len(V), "vertices,", len(c), "arcs")
284  print("distance matrix:")
285  for i in V:
286  for j in V:
287  if j > i:
288  print(c[i, j], )
289  elif j < i:
290  print(c[j, i], )
291  else:
292  print(0, )
293  print
294  print
read_tsplib.distCEIL2D
def distCEIL2D(x1, y1, x2, y2)
Definition: read_tsplib.py:56
read_tsplib.read_explicit_upper
def read_explicit_upper(f, n)
Definition: read_tsplib.py:102
read_tsplib.read_atsplib
def read_atsplib(filename)
Definition: read_tsplib.py:223
read_tsplib.read_explicit_lowerdiag
def read_explicit_lowerdiag(f, n)
Definition: read_tsplib.py:87
read_tsplib.distGEO
def distGEO(x1, y1, x2, y2)
Definition: read_tsplib.py:63
read_tsplib.read_tsplib
def read_tsplib(filename)
Definition: read_tsplib.py:148
read_tsplib.distLinf
def distLinf(x1, y1, x2, y2)
Definition: read_tsplib.py:39
read_tsplib.distATT
def distATT(x1, y1, x2, y2)
Definition: read_tsplib.py:44
read_tsplib.read_explicit_upperdiag
def read_explicit_upperdiag(f, n)
Definition: read_tsplib.py:117
read_tsplib.distL2
def distL2(x1, y1, x2, y2)
Definition: read_tsplib.py:15
read_tsplib.distL1
def distL1(x1, y1, x2, y2)
Definition: read_tsplib.py:28
read_tsplib
Definition: read_tsplib.py:1
read_tsplib.read_explicit_matrix
def read_explicit_matrix(f, n)
Definition: read_tsplib.py:132