-
Notifications
You must be signed in to change notification settings - Fork 1
/
Parser.py
90 lines (82 loc) · 3.94 KB
/
Parser.py
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
# TSPLibe parser Implementation provided by Smail KOURTA, refactored into a command line program by Smail KOURTA
import matplotlib.pyplot as plt
# import networkx as nx
import numpy as np
import math
import pandas as pd
class TSPInstance:
specsKeywords = ['NAME', 'TYPE', 'COMMENT', 'DIMENSION', 'CAPACITY', 'EDGE_WEIGHT_TYPE', 'DISPLAY_DATA_TYPE',
'EDGE_WEIGHT_FORMAT', 'EDGE_DATA_FORMAT', 'NODE_COORD_TYPE', 'DISPLAY_DATA_TYPE', 'EOF']
dataKeywords = ['NODE_COORD_SECTION', 'DEPOT_SECTION', 'DEMAND_SECTION', 'EDGE_DATA_SECTION',
'FIXED_EDGES_SECTION', 'DISPLAY_DATA_SECTION', 'TOUR_SECTION', 'EDGE_WEIGHT_SECTION']
curLine = ""
def __getitem__(self, key):
return getattr(self, key)
def __init__(self, path):
self.rawData = open(path)
self.readSpecs()
def readSpecs(self):
specsSection = []
self.curLine = self.rawData.readline().rstrip()
while (not (self.curLine in self.dataKeywords)):
specsSection.append(self.curLine)
self.curLine = self.rawData.readline().rstrip()
strippedSpecSection = [lin.split(': ') for lin in specsSection]
for i in range(len(strippedSpecSection)):
setattr(self, strippedSpecSection[i][0], strippedSpecSection[i][1])
def readData(self):
if (self.curLine == "EDGE_WEIGHT_SECTION"):
if (self['EDGE_WEIGHT_FORMAT'] == "FULL_MATRIX"):
temp = []
for i in range(int(self['DIMENSION'])):
lin = [int(i) for i in self.rawData.readline().split()]
lin = [i if i > 0 else float('inf') for i in lin]
temp.append(lin)
setattr(self, 'data', temp)
self.curLine = self.rawData.readline().rstrip()
if self.curLine == "DISPLAY_DATA_SECTION":
if self['DISPLAY_DATA_TYPE'] == "TWOD_DISPLAY":
temp = []
for i in range(int(self['DIMENSION'])):
lin = [float(i)
for i in self.rawData.readline().split()]
lin.pop(0)
temp.append(lin)
setattr(self, 'diplay_data', temp)
if (self.curLine == "NODE_COORD_SECTION"):
if self['EDGE_WEIGHT_TYPE'] == "GEO" or self['EDGE_WEIGHT_TYPE'] == "EUC_2D":
coords = []
for i in range(int(self['DIMENSION'])):
lin = [float(i) for i in self.rawData.readline().split()]
coord = (lin[1], lin[2])
coords.append(coord)
setattr(self, 'display_data', coords)
data = []
for i in range(len(coords)):
row = []
for j in range(len(coords)):
if i == j:
row.append(float("inf"))
else:
# Calculer et ajouter la distance Geo entre les coordonnées
if self['EDGE_WEIGHT_TYPE'] == "GEO":
row.append(self.geo_dist(coords[i], coords[j]))
if self['EDGE_WEIGHT_TYPE'] == "EUC_2D":
row.append(self.euc2d_dist(
coords[i], coords[j]))
data.append(row)
setattr(self, 'data', data)
def geo_dist(self, i, j):
RRR = 6378.388
lat1 = math.radians(i[0])
lon1 = math.radians(i[1])
lat2 = math.radians(j[0])
lon2 = math.radians(j[1])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = math.sin(dlat / 2) ** 2 + math.cos(lat1) * \
math.cos(lat2) * math.sin(dlon / 2) ** 2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
return RRR * c
def euc2d_dist(self, i, j):
return round(((i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2) ** 0.5)