-1

I want a Path connecting points like this: enter image description here

From what I have tried this is the results I was able to achieve in Python: enter image description here

Looks Fairly simple. Is it possible?

3 Answers3

1
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')
osmanmo
  • 26
  • 3
  • This requires installing ortools (pip install ortools). Now at the top just change the variables points and starting, that is the location where you want to begin your route. It should solve your problem – osmanmo Mar 16 '21 at 18:24
  • Thank you works for me – Kumail Raza May 18 '21 at 17:50
0

do you have the lines connect from point to point by shortest rout each time? Looks like it is something like that. I would recommend that you mark each point you place so you can make everything connect following the way that you placed everything.

paulko
  • 11
  • 2
0

It looks like a traveling salesman problem. I looked online, and discovered a library for traveling salesman problem. https://pypi.org/project/python-tsp/. it should work in creating an efficient non-overlapping route. Once it gives you a permutation, use those points and organize your new point list.

Example:

points2=[]
for i in permutation:
    points2.append(points[i])

After, you can plot points2.

Frightera
  • 2,334
  • 2
  • 7
  • 16
osmanmo
  • 26
  • 3