Skip to content
Snippets Groups Projects
Commit d70484378115 authored by Patrice Journoud's avatar Patrice Journoud
Browse files

suppression des fichiers obsolete après la réorganisation de pytsp

parent d7ef7a63cd55
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 497 deletions
import itertools
from pytsprf.interface.tsp_able import TspAble
class TspBruteForce(TspAble):
def load_matrix(self):
self.size = len(self.points)
self.matrix = [
[0 for i in range(self.size)]
for j
in range(self.size)
]
i = 0
for x in self.points:
j = i + 1
for y in self.points[j:]:
res = self.distance_getter.get_distance(x, y)
if res == 0:
print('WARNING: distance between', x, 'and', y, 'is 0')
self.matrix[i][j] = res
self.matrix[j][i] = res
j += 1
i += 1
def __init__(self, name, points, distance_getter):
TspAble.__init__(self, name, points, distance_getter)
def get_route(self):
best_path = None
best_distance = float("inf")
for path in itertools.permutations(range(1, self.size - 1)):
path = (0,) + path + (self.size - 1,)
i = 0
cur_distance = 0
while i < self.size - 1:
cur_distance += self.matrix[path[i]][path[i + 1]]
i += 1
if cur_distance < best_distance:
best_distance = cur_distance
best_path = path
return best_path
def get_cost(self, route):
wroute = route + (0,)
cost = 0
for i in range(len(wroute) - 1):
row = wroute[i]
col = wroute[i + 1]
cost = cost + self.matrix[row][col]
return cost/1000.00
from pytsprf.gps.gpsdistancegetter import GpsDistanceGetter
from pytsprf.osrm.osrmdistancegetter import OsrmDistanceGetter
class DistanceGetterFactory(object):
def __init__(self, is_test_mode=False):
self.is_test_mode = is_test_mode
def get_instance(self):
if self.is_test_mode:
return GpsDistanceGetter()
else:
return OsrmDistanceGetter()
import math
from pytsprf.interface.distance_getter_able import DistanceGetterAble
class GpsDistanceGetter(DistanceGetterAble):
def __init__(self):
DistanceGetterAble.__init__(self, "gps")
# The following formulas are adapted from the Aviation Formulary
# http://williams.best.vwh.net/avform.htm
self.nmperlat = 60.00721
self.nmperlong = 60.10793
self.rad = math.pi / 180.0
# milesPerNauticalMile = 1.15078
self.kmpernm = 1.85200
def get_distance(self, start, end):
"""We assume that coords are 2-tuples
in the form (43.83032, 4.359950)
Distance between the two points in meters
"""
lat1 = start[0]
lon1 = start[1]
lat2 = end[0]
lon2 = end[1]
yDistance = 1000 * (lat2 - lat1) * self.nmperlat
xDistance = 1000 * (
math.cos(lat1 * self.rad) + math.cos(lat2 * self.rad)
) * (lon2 - lon1) * (self.nmperlong / 2)
distance = math.sqrt(yDistance**2 + xDistance**2)
return distance * self.kmpernm
class DistanceGetterAble(object):
def __init__(
self, name
):
self.name = name
def get_distance(self, start, end):
"""
start is the start point located by a tuple of latitude, longitude
ex: (43.83032, 4.359950)
end is the destination point
Distance returned by this method is the distance calculated between
the two points is required to be given in KM
"""
print("DistanceGetterAble / get_distance / Not implemented method")
class TspAble(object):
def load_matrix(self):
raise NotImplementedError
def __init__(
self, name, points, distance_getter
):
self.name = name
self.points = points
self.distance_getter = distance_getter
self.load_matrix()
def get_route(self):
print("TspAble / get_route / Not implemented method")
class OrtoolsDistanceMatrix(object):
"""create a matrix will all your points and prepares all the distances
for the solver.
This class computes 'gps' distances considering the earth as a flat sphere
without mountains or valleys
"""
def __init__(self, points, distance_getter):
"""takes a list of points as arguments. Those points are (lat, lon)
tuples.
"""
self.size = len(points)
self.matrix = {}
for i, spoint in enumerate(points):
self.matrix[i] = {}
for j, dpoint in enumerate(points):
self.matrix[i][j] = distance_getter.get_distance(
(spoint.lat, spoint.lon),
(dpoint.lat, dpoint.lon)
)
def distance(self, from_node, to_node):
return self.matrix[from_node][to_node]
def get_matrix(self):
return self.matrix
# Copyright 2015 XCG, Florent Aide
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This program is heavily inspired by the TSP example distributed under the
# same license by google in it's or-tools project
# see here for more info: https://github.com/google/or-tools
#
# This program makes use of the google library for the TSP solving
# but uses OSMR to calculate real distances between points
"""Traveling Salesman Implementation.
This is an implementation using the routing library python wrapper to solve
a Traveling Salesman Problem.
The description of the problem can be found here:
http://en.wikipedia.org/wiki/Travelling_salesman_problem.
The optimization engine uses local search to improve solutions, first
solutions being generated using a cheapest addition heuristic.
Optionally one can randomly forbid a set of random connections between
nodes (forbidden arcs).
"""
from ortools.constraint_solver import pywrapcp
from pytsprf.ortoolswrap.ortools_distance_matrix import OrtoolsDistanceMatrix
from pytsprf.point import Point
from pytsprf.interface.tsp_able import TspAble
class TspOrtools(TspAble):
def load_matrix(self):
points_ = [Point(start, end) for start, end in self.points]
self.matrix = OrtoolsDistanceMatrix(
points_,
self.distance_getter
)
def __init__(
self, name, points, distance_getter
):
TspAble.__init__(self, name, points, distance_getter)
def get_route(
self, light_propagation=False, forbidden_connections=None
):
param = pywrapcp.RoutingParameters()
param.use_light_propagation = light_propagation
pywrapcp.RoutingModel.SetGlobalParameters(param)
tsp_size = self.matrix.size
# TSP of size tsp_size
# Nodes are indexed from 0 to FLAGS_tsp_size - 1,
# by default the start of
# the route is node 0.
# Second argument number of routes = 1 to build a single route.
routing = pywrapcp.RoutingModel(tsp_size, 1)
parameters = pywrapcp.RoutingSearchParameters()
# Setting first solution heuristic (cheapest addition).
parameters.first_solution = 'PathCheapestArc'
# Disabling Large Neighborhood Search, comment out to activate it.
parameters.no_lns = True
# if you want to come back to the start set this to False
parameters.no_tsp = False
# the matrix must implement the distance callback
matrix_callback = self.matrix.distance
routing.SetArcCostEvaluatorOfAllVehicles(matrix_callback)
# Forbid node connections
if forbidden_connections:
for connection in forbidden_connections:
from_node, to_node = connection
if routing.NextVar(from_node).Contains(to_node):
print(
'Forbidding connection %s --> %s' %
(from_node, to_node)
)
routing.NextVar(from_node).RemoveValue(to_node)
# Solve, returns a solution if any.
assignment = routing.SolveWithParameters(parameters, None)
if assignment:
# Solution cost.
print(assignment.ObjectiveValue())
# Inspect solution.
# Only one route here;
# otherwise iterate from 0 to routing.vehicles() - 1
route_number = 0
node = routing.Start(route_number)
route = []
while not routing.IsEnd(node):
route.append(node)
node = assignment.Value(routing.NextVar(node))
route.append(0)
return route
else:
print('No solution found.')
def get_cost(self, route):
cost = 0
for i in range(len(route) - 1):
row = route[i]
col = route[i+1]
cost = cost + self.matrix.matrix.get(row).get(col)
return cost/1000.00
class OsrmConf(object):
def __init__(self, host='osrm1.formelie.org'):
# TODO get the configuration from a file
self.host = host
self.secure = True
def __str__(self):
return "distance-getter = %s, server = %s, secure = %s" % \
(self.get_name(), self.get_server(), self.get_secure())
import requests
from pytsprf.interface.distance_getter_able import DistanceGetterAble
from pytsprf.conf import get as get_init_file_key
class OsrmDistanceGetter(DistanceGetterAble):
def __init__(self, host=None, scheme=None):
DistanceGetterAble.__init__(self, "osrm")
if (host is None):
self.load_hostname()
else:
self.host = host
if (scheme is None):
self.load_scheme()
else:
self.scheme = scheme
def load_hostname(self):
key = "osrm.hostname"
value = get_init_file_key(key)
self.host = value
def load_scheme(self):
key = "osrm.scheme"
value = get_init_file_key(key)
self.scheme = value
def get_distance(self, start, end):
"""We assume that coords are OSRM locate/nearest results. ie: 2-tuples
in the form (43.83032, 4.359950)
:param start: a 2-tuple containing a (lat, long) and representing the
start of your travel. ex: (43.83032, 4.359950)
:type start: list or tuple
:param end: a 2-tuple containing a (lat, long) and representing the
end of your travel. ex: (43.83032, 4.359950)
:type end: list or tuple
:returns: the real distance between start and end as calculated by your
OSRM server or None if the server cannot be reached or does not find a
solution
:raises: Nothing
"""
try:
r = requests.get(
'%(scheme)s://%(host)s/viaroute?'
'loc=%(s_lat)s,%(s_lng)s&'
'loc=%(e_lat)s,%(e_lng)s&alt=false' % {
's_lat': start[0],
's_lng': start[1],
'e_lat': end[0],
'e_lng': end[1],
'host': self.host,
'scheme': self.scheme,
}
)
status = r.status_code
except requests.ConnectionError:
print("OSRM Server busy. Try again later.")
status = 0
if status == 200:
data = r.json()
if data['status'] == 0:
return data['route_summary']['total_distance']
print(
"OSRM server can't find a route between points. Please verify that"
" your coords are the result of a OSRM locate/nearest requests."
)
return None
import requests
from pytsprf.conf import get as get_init_file_key
class OsrmViaroute(object):
def __init__(self, host=None, scheme=None):
if (host is None):
self.load_hostname()
else:
self.host = host
if (scheme is None):
self.load_scheme()
else:
self.scheme = scheme
def load_hostname(self):
key = "osrm.hostname"
value = get_init_file_key(key)
self.host = value
def load_scheme(self):
key = "osrm.scheme"
value = get_init_file_key(key)
self.scheme = value
def get_osrm_viaroute(self, points):
"""We assume that coords are OSRM locate/nearest results. ie: 2-tuples
in the form (43.83032, 4.359950)
:param start: a 2-tuple containing a (lat, long) and representing the
start of your travel. ex: (43.83032, 4.359950)
:type start: list or tuple
:param end: a 2-tuple containing a (lat, long) and representing the
end of your travel. ex: (43.83032, 4.359950)
:type end: list or tuple
:returns: the real distance between start and end as calculated by your
OSRM server or None if the server cannot be reached or does not find a
solution
:raises: Nothing
"""
url = "%s://%s/viaroute?" % (self.scheme, self.host,)
i = 0
npoints = len(points)
for pointi in points:
url += "loc=%s,%s" % (pointi[0], pointi[1],)
if (i < npoints - 1):
url += "?"
i += 1
url += "?compression=false"
try:
r = requests.get(url)
status = r.status_code
except requests.ConnectionError:
print("OSRM Server busy. Try again later.")
status = 0
if status == 200:
data = r.json()
if data['status'] == 0:
return data['route_geometry']
print(
"OSRM server can't find a route between points. Please verify that"
" your coords are the result of a OSRM locate/nearest requests."
)
return None
class Point(object):
def __init__(self, latitude, longitude):
self.lat = latitude
self.lon = longitude
from pytsprf.brute_force.tsp_brute_force import TspBruteForce
from pytsprf.ortoolswrap.tsp_ortools import TspOrtools
class RouteSolverFactory(object):
def __init__(self, points, distance_getter):
self.max_points_for_brute_force_selection = 5
self.points = points
self.distance_getter = distance_getter
def get_instance(self):
is_bruteforce = (
len(self.points) < self.max_points_for_brute_force_selection
)
if is_bruteforce:
return TspBruteForce(
'brute_force', self.points, self.distance_getter
)
else:
return TspOrtools(
'ortools', self.points, self.distance_getter
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment