Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find if list of coordinates form a loop

So I have a list of points that generally form a sort of circular shape except there are often little offshoots from the circle that are essentially just lines from say the border of the circle going in a certain direction. I want to create a function that when given this list of coordinates/points finds whether there exists a complete path in this set of points.

I've thought about creating a start point and finding whether there exists a path that doesn't repeat points (ie (1,1) -> (2, 1) -> (1,1) disallowed) and could get back to the start point; however, if the start point is in an offshoot of the circle, this wouldn't work.

For instance, a list of coordinates

[[0, 0], [0, 1], [1, 2], [2, 3], [3, 3], [3, 4], [4, 4], [3, 2], [3, 1], [3, 0], [2, -1], [1, -1], [0, -1]] 

would form a complete path while if I take out [1, -1] it would not form a complete path.

like image 610
jshackle Avatar asked Dec 10 '25 21:12

jshackle


1 Answers

What you're looking for is a simple cycle. The graph theory package networkx provides a method for finding those in simple_cycles. All we need to do is a tiny bit of leg work to set up the graph:

import networkx as nx

def has_simple_cycle(l, start):
    G = nx.DiGraph()
    G.add_edges_from((v1, v2) for v1 in l for v2 in l if v1 != v2 and max(abs(v1[0] - v2[0]), abs(v1[1] - v2[1])) <= 1)
    return any(start in c and len(c) > 2 for c in nx.simple_cycles(G))

On your given examples:

In [26]: has_simple_cycle(l=[(0, 0), (0, 1), (1, 2), (2, 3), (3, 3), (3, 4), (4, 4), (3, 2), (3, 1), (3, 0), (2, -1), (1, -1), (0, -1)], start=(0, 0))
Out[26]: True

In [27]: has_simple_cycle(l=[(0, 0), (0, 1), (1, 2), (2, 3), (3, 3), (3, 4), (4, 4), (3, 2), (3, 1), (3, 0), (2, -1), (0, -1)], start=(0, 0))
Out[27]: False
like image 150
fuglede Avatar answered Dec 12 '25 12:12

fuglede