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.
and the result would be:
result = [["1","2","8"],["3","4","5"],["6","7"]]
All Lines Are Vertical
CodePudding user response:
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']]
CodePudding user response:
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']]