Python 中没有重叠的路径连接点
Path Connecting Points without overlapping in Python
我想要一个像这样连接点的路径:
enter image description here
根据我的尝试,这是我在 Python 中能够实现的结果:
enter image description here
看起来很简单。可能吗?
你每次都让线路以最短路径从一个点连接到另一个点吗?看起来是这样的。我建议你标记你放置的每个点,这样你就可以按照你放置所有东西的方式连接所有东西。
看起来像旅行商问题。我上网查了一下,发现了一个关于旅行商问题的图书馆。 https://pypi.org/project/python-tsp/。它应该可以创建有效的非重叠路线。一旦它给你一个排列,使用这些点并组织你的新点列表。
示例:
points2=[]
for i in permutation:
points2.append(points[i])
之后,你可以绘制points2
。
points=[[2031.0974638138432, 8871.788899127823],
[1946.0939073523768, 8687.702718346474],
[1868.9610243990464, 8542.951197953029],
[2061.006139498597, 8393.47953820238],
[2163.3253106537886, 8264.46188196409],
[2541.119051912334, 8232.994153653774],
[2785.1108448732557, 8292.782817554034],
[2967.711185007007, 8424.947266512696],
[2967.711185007007, 8602.739911576653],
[2709.552146487491, 8752.211571327301],
[2429.355105791343, 8808.853442507185],
[2150.732166552858, 8744.34463924972],
[2087.7665291581216, 8531.937522878434],
[2402.594716131818, 8379.319070407408],
[2638.7157524747163, 8461.135134180222],
[2446.670637375166, 8541.377851316203],
[2492.849155914053, 8630.642922304622],
[2444.788613747456, 8669.072915834848],
[2366.462005771966, 8620.088463227232]]
starting=5
import math
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def create_data_model(points,starting):
"""Stores the data for the problem."""
data = {}
# Locations in block units
data['locations'] = points
data['num_vehicles'] = 1
data['depot'] = starting
return data
def compute_euclidean_distance_matrix(locations):
"""Creates callback to return distance between points."""
distances = {}
for from_counter, from_node in enumerate(locations):
distances[from_counter] = {}
for to_counter, to_node in enumerate(locations):
if from_counter == to_counter:
distances[from_counter][to_counter] = 0
else:
# Euclidean distance
distances[from_counter][to_counter] = (int(
math.hypot((from_node[0] - to_node[0]),
(from_node[1] - to_node[1]))))
return distances
def print_solution(manager, routing, solution):
"""Prints solution on console."""
index = routing.Start(0)
plan_output = []
route_distance = 0
while not routing.IsEnd(index):
plan_output.append(manager.IndexToNode(index))
previous_index = index
index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
return plan_output
def main(points,starting=0):
"""Entry point of the program."""
# Instantiate the data problem.
data = create_data_model(points,starting)
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['locations']),
data['num_vehicles'], data['depot'])
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
distance_matrix = compute_euclidean_distance_matrix(data['locations'])
def distance_callback(from_index, to_index):
"""Returns the distance between the two nodes."""
# Convert from routing variable Index to distance matrix NodeIndex.
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return distance_matrix[from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
# Define cost of each arc.
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
# Solve the problem.
solution = routing.SolveWithParameters(search_parameters)
# Print solution on console.
if solution:
return print_solution(manager, routing, solution)
if __name__ == '__main__':
permutation = main(points,starting=starting)
points2=[]
for i in permutation:
points2.append(points[i])
x,y = map(list,zip(*points2))
from matplotlib import pyplot as plt
plt.plot(x,y,'-o')
我想要一个像这样连接点的路径: enter image description here
根据我的尝试,这是我在 Python 中能够实现的结果: enter image description here
看起来很简单。可能吗?
你每次都让线路以最短路径从一个点连接到另一个点吗?看起来是这样的。我建议你标记你放置的每个点,这样你就可以按照你放置所有东西的方式连接所有东西。
看起来像旅行商问题。我上网查了一下,发现了一个关于旅行商问题的图书馆。 https://pypi.org/project/python-tsp/。它应该可以创建有效的非重叠路线。一旦它给你一个排列,使用这些点并组织你的新点列表。
示例:
points2=[]
for i in permutation:
points2.append(points[i])
之后,你可以绘制points2
。
points=[[2031.0974638138432, 8871.788899127823],
[1946.0939073523768, 8687.702718346474],
[1868.9610243990464, 8542.951197953029],
[2061.006139498597, 8393.47953820238],
[2163.3253106537886, 8264.46188196409],
[2541.119051912334, 8232.994153653774],
[2785.1108448732557, 8292.782817554034],
[2967.711185007007, 8424.947266512696],
[2967.711185007007, 8602.739911576653],
[2709.552146487491, 8752.211571327301],
[2429.355105791343, 8808.853442507185],
[2150.732166552858, 8744.34463924972],
[2087.7665291581216, 8531.937522878434],
[2402.594716131818, 8379.319070407408],
[2638.7157524747163, 8461.135134180222],
[2446.670637375166, 8541.377851316203],
[2492.849155914053, 8630.642922304622],
[2444.788613747456, 8669.072915834848],
[2366.462005771966, 8620.088463227232]]
starting=5
import math
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def create_data_model(points,starting):
"""Stores the data for the problem."""
data = {}
# Locations in block units
data['locations'] = points
data['num_vehicles'] = 1
data['depot'] = starting
return data
def compute_euclidean_distance_matrix(locations):
"""Creates callback to return distance between points."""
distances = {}
for from_counter, from_node in enumerate(locations):
distances[from_counter] = {}
for to_counter, to_node in enumerate(locations):
if from_counter == to_counter:
distances[from_counter][to_counter] = 0
else:
# Euclidean distance
distances[from_counter][to_counter] = (int(
math.hypot((from_node[0] - to_node[0]),
(from_node[1] - to_node[1]))))
return distances
def print_solution(manager, routing, solution):
"""Prints solution on console."""
index = routing.Start(0)
plan_output = []
route_distance = 0
while not routing.IsEnd(index):
plan_output.append(manager.IndexToNode(index))
previous_index = index
index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
return plan_output
def main(points,starting=0):
"""Entry point of the program."""
# Instantiate the data problem.
data = create_data_model(points,starting)
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['locations']),
data['num_vehicles'], data['depot'])
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
distance_matrix = compute_euclidean_distance_matrix(data['locations'])
def distance_callback(from_index, to_index):
"""Returns the distance between the two nodes."""
# Convert from routing variable Index to distance matrix NodeIndex.
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return distance_matrix[from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
# Define cost of each arc.
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
# Solve the problem.
solution = routing.SolveWithParameters(search_parameters)
# Print solution on console.
if solution:
return print_solution(manager, routing, solution)
if __name__ == '__main__':
permutation = main(points,starting=starting)
points2=[]
for i in permutation:
points2.append(points[i])
x,y = map(list,zip(*points2))
from matplotlib import pyplot as plt
plt.plot(x,y,'-o')