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