I am trying to accomplish the following task:
Given a list of coordinates of n
points in the plane, I need to find subsets of all points that share the same x-coordinate OR same y-coordinate. For instance, for the list:
data = {{1,2},{3,1},{1,5},{6,2},{7,3},{4,4},{5,4},{0,0},{2,3},{6,7}}
I get:
set1 = {{1, 2}, {1, 5}, {6, 2}, {6, 7}} set2 = {{0, 0}} set3 = {{2, 3}, {7, 3}} set4 = {{3, 1}} set5 = {{4, 4}, {5, 4}}
Notice for example in set1
that {1, 5}
and {6, 2}
are in the same set linked indirectly. I have written some "naive implementation" consisting of the two modules shown below. I understand that the use of Append
is not a good idea. The code below works, and produces good results for relatively small data sets, but obviously does not scale very well. A data set of 1000 points takes about 150 seconds to run on my computer...
findLinks[list_] := Module[{},
newList = {list[[1]]};
xList = {list[[1, 1]]};
yList = {list[[1, 2]]};
For[i = 1., i <= Length[list], i++,
For[j = i, j <= Length[list], j++,
If[(list[[i, 1]] == list[[j, 1]] ||
list[[i, 2]] == list[[j, 2]]) && (MemberQ[xList,
list[[j, 1]]] || MemberQ[yList, list[[j, 2]]]),
newList = Append[newList, list[[i]]];
newList = Append[newList, list[[j]]];
xList = Append[xList, list[[i, 1]]];
yList = Append[yList, list[[i, 2]]];
xList = Append[xList, list[[j, 1]]];
yList = Append[yList, list[[j, 2]]];
];
];
];
DeleteDuplicates[newList]
];
getClusters[list_] := getClusters[list] = Module[{list1, list2},
finalClusters = {};
list1 = list;
While[Length[list1] >= 1,
list2 = findLinks[list1];
finalClusters = Append[finalClusters, list2];
(*Deletes from list1 those elements of list2... *)
list1 = Complement[list1, list2];
];
finalClusters
];
getClusters[data]
I am trying to implement another solution using Select
or linked lists, but so far I am not getting anywhere. Any ideas about how to speed up this task?