Connect lines that have common points

Question:

I have a list of lines like this:

Lines = ['1', '2', '3', '4', '5', '6', '7', '8']

each line has two points I and J:

LinesDetail = {
    '1': {
        'I': '100',
        'J': '101'},
    '2': {
        'I': '101',
        'J': '102'},
    '3': {
        'I': '256',
        'J': '257'},
    '4': {
        'I': '257',
        'J': '258'},
    '5': {
        'I': '258',
        'J': '259'},
    '6': {
        'I': '304',
        'J': '305'},
    '7': {
        'I': '305',
        'J': '306'},
    '8': {
        'I': '102',
        'J': '103'}}

As you see in the picture, some of these lines have mutual points
so they are connected to each other and I need to know which lines are connected to each other.

I tried while loop but I don’t have the basic idea of how to solve this kind of problems.

Lines

and the result would be:

result = [["1","2","8"],["3","4","5"],["6","7"]]

All Lines Are Vertical

Answers:

This is a graph problem of finding connected components. A possible interpretation is that the outer keys are labels and the inner dictionaries are the edges (and inner dict values are the nodes). If dependency is not an issue, Python has a nice API networkx that deals with graphs. Specifically, one can use the UnionFind data structure to find the disjoint subsets.

from networkx.utils.union_find import UnionFind

# reverse the label-edge mapping to get a mapping from nodes to edge labels
edges = {}
for k, d in LinesDetail.items():
    for v in d.values():
        edges.setdefault(v, []).append(k)

# construct union-find data structure
c = UnionFind()
for lst in edges.values():
    c.union(*lst)

# get the disjoint sets as sorted lists
result = list(map(sorted, c.to_sets()))
result
# [['1', '2', '8'], ['3', '4', '5'], ['6', '7']]
Answered By: cottontail

Not the most optimal solution, but putting it out there since I worked on it

LinesDetail = {
    '1': {
        'I': '100',
        'J': '101'},
    '2': {
        'I': '101',
        'J': '102'},
    '3': {
        'I': '256',
        'J': '257'},
    '4': {
        'I': '257',
        'J': '258'},
    '5': {
        'I': '258',
        'J': '259'},
    '6': {
        'I': '304',
        'J': '305'},
    '7': {
        'I': '305',
        'J': '306'},
    '8': {
        'I': '102',
        'J': '103'}}
Lines = ['1', '2', '3', '4', '5', '6', '7', '8']

results = []
for item in Lines:
    match_this = LinesDetail[item]['J']
    list_form = []
    for key, value in LinesDetail.items():
        if match_this == value['I']:
            results.append([item, key])
needed_list = []                
for i in range(0, len(results)-1):    
    if results[i][1] == results[i+1][0]:

        yes_list = results[i][:1] + results[i+1]

        needed_list.append(yes_list)
    else:
        try:
            if results[i][1] == results[i+2][0]:
                continue
        except:
            needed_list.append(results[i+1])

        
print(needed_list)

output:

[['1', '2', '8'], ['3', '4', '5'], ['6', '7']]
Answered By: Kavi Harjani