Select connected subsets of integer pairs?
up vote
6
down vote
favorite
Given a list of integer pairs such as
list = { {1,2},{1,3},{2,5},{1,5},{6,7},{6,9},{4,6} };
What is a quick way to separate the pairs into groups in which every element shares at least one integer with at least one other element, in Mathematica? e.g.:
separate[list]
{ { {1,2},{1,3},{2,5},{1,5} } , { {6,7},{6,9},{4,6} } }
Thanks for any suggestion!
list-manipulation function-construction
add a comment |
up vote
6
down vote
favorite
Given a list of integer pairs such as
list = { {1,2},{1,3},{2,5},{1,5},{6,7},{6,9},{4,6} };
What is a quick way to separate the pairs into groups in which every element shares at least one integer with at least one other element, in Mathematica? e.g.:
separate[list]
{ { {1,2},{1,3},{2,5},{1,5} } , { {6,7},{6,9},{4,6} } }
Thanks for any suggestion!
list-manipulation function-construction
add a comment |
up vote
6
down vote
favorite
up vote
6
down vote
favorite
Given a list of integer pairs such as
list = { {1,2},{1,3},{2,5},{1,5},{6,7},{6,9},{4,6} };
What is a quick way to separate the pairs into groups in which every element shares at least one integer with at least one other element, in Mathematica? e.g.:
separate[list]
{ { {1,2},{1,3},{2,5},{1,5} } , { {6,7},{6,9},{4,6} } }
Thanks for any suggestion!
list-manipulation function-construction
Given a list of integer pairs such as
list = { {1,2},{1,3},{2,5},{1,5},{6,7},{6,9},{4,6} };
What is a quick way to separate the pairs into groups in which every element shares at least one integer with at least one other element, in Mathematica? e.g.:
separate[list]
{ { {1,2},{1,3},{2,5},{1,5} } , { {6,7},{6,9},{4,6} } }
Thanks for any suggestion!
list-manipulation function-construction
list-manipulation function-construction
asked Nov 6 at 15:34
Kagaratsch
4,53631246
4,53631246
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
5
down vote
accepted
G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}, {6, 9}, {4, 6}}];
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#]>0 &
]
{{{4, 6}, {6, 7}, {6, 9}}, {{1, 2}, {1, 3}, {2, 5}, {1, 5}}}
If "quick" was meant as "quick at runtime", then you should better avoid Graph
and use SparseArray
:
componentEdges[edges_] := Module[{B},
B = Transpose[With[{m = Length[edges], n = Max[edges]},
(* this builds a sparse array directly from row pointers, column indices, and nonzero values; undocumentd *)
SparseArray @@ {Automatic, {m, n}, 0, {1, {
Range[0, 2 m, 2],
Partition[Flatten[edges], 1]
},
ConstantArray[1, 2 m]}}
]];
Select[
Table[
edges[[Flatten[(SparseArray[Partition[c, 1] -> 1, Length[B]].B)["NonzeroPositions"]]]],
{c, SparseArray`StronglyConnectedComponents[B.B[Transpose]]}],
Length[#] > 0 &]
];
Just for comparison, the Graph
-based approach:
componentEdges0[edges_] := With[{G = Graph[edges]},
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#] > 0 &]
];
And here a usage example along with timings:
edges = Developer`ToPackedArray[List @@@ EdgeList[RandomGraph[{10000, 60000}]]];
a = componentEdges0[edges]; // RepeatedTiming // First
b = componentEdges[edges]; // RepeatedTiming // First
Sort[Sort /@ a] == Sort[Sort /@ b]
0.13
0.0084
True
But G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}}]; Select[List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G], Length[#] > 0 &] where {6, 7} shares no elts with others returns the {6, 7} {{{1, 2}, {1, 3}, {2, 5}, {1, 5}}, {{6, 7}}}
– Rabbit
Nov 6 at 20:37
@Rabbit Well, one could fix that by using the selector functionLength[#] > 1 &
. But I doubt that OP had that in mind...
– Henrik Schumacher
Nov 6 at 20:42
add a comment |
up vote
6
down vote
Gather[list, IntersectingQ]
{{{1, 2}, {1, 3}, {2, 5}, {1, 5}},
{{6, 7}, {6, 9}, {4, 6}}}
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}, {6, 9}, {4, 6}}];
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#]>0 &
]
{{{4, 6}, {6, 7}, {6, 9}}, {{1, 2}, {1, 3}, {2, 5}, {1, 5}}}
If "quick" was meant as "quick at runtime", then you should better avoid Graph
and use SparseArray
:
componentEdges[edges_] := Module[{B},
B = Transpose[With[{m = Length[edges], n = Max[edges]},
(* this builds a sparse array directly from row pointers, column indices, and nonzero values; undocumentd *)
SparseArray @@ {Automatic, {m, n}, 0, {1, {
Range[0, 2 m, 2],
Partition[Flatten[edges], 1]
},
ConstantArray[1, 2 m]}}
]];
Select[
Table[
edges[[Flatten[(SparseArray[Partition[c, 1] -> 1, Length[B]].B)["NonzeroPositions"]]]],
{c, SparseArray`StronglyConnectedComponents[B.B[Transpose]]}],
Length[#] > 0 &]
];
Just for comparison, the Graph
-based approach:
componentEdges0[edges_] := With[{G = Graph[edges]},
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#] > 0 &]
];
And here a usage example along with timings:
edges = Developer`ToPackedArray[List @@@ EdgeList[RandomGraph[{10000, 60000}]]];
a = componentEdges0[edges]; // RepeatedTiming // First
b = componentEdges[edges]; // RepeatedTiming // First
Sort[Sort /@ a] == Sort[Sort /@ b]
0.13
0.0084
True
But G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}}]; Select[List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G], Length[#] > 0 &] where {6, 7} shares no elts with others returns the {6, 7} {{{1, 2}, {1, 3}, {2, 5}, {1, 5}}, {{6, 7}}}
– Rabbit
Nov 6 at 20:37
@Rabbit Well, one could fix that by using the selector functionLength[#] > 1 &
. But I doubt that OP had that in mind...
– Henrik Schumacher
Nov 6 at 20:42
add a comment |
up vote
5
down vote
accepted
G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}, {6, 9}, {4, 6}}];
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#]>0 &
]
{{{4, 6}, {6, 7}, {6, 9}}, {{1, 2}, {1, 3}, {2, 5}, {1, 5}}}
If "quick" was meant as "quick at runtime", then you should better avoid Graph
and use SparseArray
:
componentEdges[edges_] := Module[{B},
B = Transpose[With[{m = Length[edges], n = Max[edges]},
(* this builds a sparse array directly from row pointers, column indices, and nonzero values; undocumentd *)
SparseArray @@ {Automatic, {m, n}, 0, {1, {
Range[0, 2 m, 2],
Partition[Flatten[edges], 1]
},
ConstantArray[1, 2 m]}}
]];
Select[
Table[
edges[[Flatten[(SparseArray[Partition[c, 1] -> 1, Length[B]].B)["NonzeroPositions"]]]],
{c, SparseArray`StronglyConnectedComponents[B.B[Transpose]]}],
Length[#] > 0 &]
];
Just for comparison, the Graph
-based approach:
componentEdges0[edges_] := With[{G = Graph[edges]},
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#] > 0 &]
];
And here a usage example along with timings:
edges = Developer`ToPackedArray[List @@@ EdgeList[RandomGraph[{10000, 60000}]]];
a = componentEdges0[edges]; // RepeatedTiming // First
b = componentEdges[edges]; // RepeatedTiming // First
Sort[Sort /@ a] == Sort[Sort /@ b]
0.13
0.0084
True
But G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}}]; Select[List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G], Length[#] > 0 &] where {6, 7} shares no elts with others returns the {6, 7} {{{1, 2}, {1, 3}, {2, 5}, {1, 5}}, {{6, 7}}}
– Rabbit
Nov 6 at 20:37
@Rabbit Well, one could fix that by using the selector functionLength[#] > 1 &
. But I doubt that OP had that in mind...
– Henrik Schumacher
Nov 6 at 20:42
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}, {6, 9}, {4, 6}}];
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#]>0 &
]
{{{4, 6}, {6, 7}, {6, 9}}, {{1, 2}, {1, 3}, {2, 5}, {1, 5}}}
If "quick" was meant as "quick at runtime", then you should better avoid Graph
and use SparseArray
:
componentEdges[edges_] := Module[{B},
B = Transpose[With[{m = Length[edges], n = Max[edges]},
(* this builds a sparse array directly from row pointers, column indices, and nonzero values; undocumentd *)
SparseArray @@ {Automatic, {m, n}, 0, {1, {
Range[0, 2 m, 2],
Partition[Flatten[edges], 1]
},
ConstantArray[1, 2 m]}}
]];
Select[
Table[
edges[[Flatten[(SparseArray[Partition[c, 1] -> 1, Length[B]].B)["NonzeroPositions"]]]],
{c, SparseArray`StronglyConnectedComponents[B.B[Transpose]]}],
Length[#] > 0 &]
];
Just for comparison, the Graph
-based approach:
componentEdges0[edges_] := With[{G = Graph[edges]},
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#] > 0 &]
];
And here a usage example along with timings:
edges = Developer`ToPackedArray[List @@@ EdgeList[RandomGraph[{10000, 60000}]]];
a = componentEdges0[edges]; // RepeatedTiming // First
b = componentEdges[edges]; // RepeatedTiming // First
Sort[Sort /@ a] == Sort[Sort /@ b]
0.13
0.0084
True
G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}, {6, 9}, {4, 6}}];
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#]>0 &
]
{{{4, 6}, {6, 7}, {6, 9}}, {{1, 2}, {1, 3}, {2, 5}, {1, 5}}}
If "quick" was meant as "quick at runtime", then you should better avoid Graph
and use SparseArray
:
componentEdges[edges_] := Module[{B},
B = Transpose[With[{m = Length[edges], n = Max[edges]},
(* this builds a sparse array directly from row pointers, column indices, and nonzero values; undocumentd *)
SparseArray @@ {Automatic, {m, n}, 0, {1, {
Range[0, 2 m, 2],
Partition[Flatten[edges], 1]
},
ConstantArray[1, 2 m]}}
]];
Select[
Table[
edges[[Flatten[(SparseArray[Partition[c, 1] -> 1, Length[B]].B)["NonzeroPositions"]]]],
{c, SparseArray`StronglyConnectedComponents[B.B[Transpose]]}],
Length[#] > 0 &]
];
Just for comparison, the Graph
-based approach:
componentEdges0[edges_] := With[{G = Graph[edges]},
Select[
List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G],
Length[#] > 0 &]
];
And here a usage example along with timings:
edges = Developer`ToPackedArray[List @@@ EdgeList[RandomGraph[{10000, 60000}]]];
a = componentEdges0[edges]; // RepeatedTiming // First
b = componentEdges[edges]; // RepeatedTiming // First
Sort[Sort /@ a] == Sort[Sort /@ b]
0.13
0.0084
True
edited Nov 6 at 21:50
answered Nov 6 at 15:37
Henrik Schumacher
44.9k265130
44.9k265130
But G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}}]; Select[List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G], Length[#] > 0 &] where {6, 7} shares no elts with others returns the {6, 7} {{{1, 2}, {1, 3}, {2, 5}, {1, 5}}, {{6, 7}}}
– Rabbit
Nov 6 at 20:37
@Rabbit Well, one could fix that by using the selector functionLength[#] > 1 &
. But I doubt that OP had that in mind...
– Henrik Schumacher
Nov 6 at 20:42
add a comment |
But G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}}]; Select[List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G], Length[#] > 0 &] where {6, 7} shares no elts with others returns the {6, 7} {{{1, 2}, {1, 3}, {2, 5}, {1, 5}}, {{6, 7}}}
– Rabbit
Nov 6 at 20:37
@Rabbit Well, one could fix that by using the selector functionLength[#] > 1 &
. But I doubt that OP had that in mind...
– Henrik Schumacher
Nov 6 at 20:42
But G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}}]; Select[List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G], Length[#] > 0 &] where {6, 7} shares no elts with others returns the {6, 7} {{{1, 2}, {1, 3}, {2, 5}, {1, 5}}, {{6, 7}}}
– Rabbit
Nov 6 at 20:37
But G = Graph[{{1, 2}, {1, 3}, {2, 5}, {1, 5}, {6, 7}}]; Select[List @@@ EdgeList[Subgraph[G, #]] & /@ ConnectedComponents[G], Length[#] > 0 &] where {6, 7} shares no elts with others returns the {6, 7} {{{1, 2}, {1, 3}, {2, 5}, {1, 5}}, {{6, 7}}}
– Rabbit
Nov 6 at 20:37
@Rabbit Well, one could fix that by using the selector function
Length[#] > 1 &
. But I doubt that OP had that in mind...– Henrik Schumacher
Nov 6 at 20:42
@Rabbit Well, one could fix that by using the selector function
Length[#] > 1 &
. But I doubt that OP had that in mind...– Henrik Schumacher
Nov 6 at 20:42
add a comment |
up vote
6
down vote
Gather[list, IntersectingQ]
{{{1, 2}, {1, 3}, {2, 5}, {1, 5}},
{{6, 7}, {6, 9}, {4, 6}}}
add a comment |
up vote
6
down vote
Gather[list, IntersectingQ]
{{{1, 2}, {1, 3}, {2, 5}, {1, 5}},
{{6, 7}, {6, 9}, {4, 6}}}
add a comment |
up vote
6
down vote
up vote
6
down vote
Gather[list, IntersectingQ]
{{{1, 2}, {1, 3}, {2, 5}, {1, 5}},
{{6, 7}, {6, 9}, {4, 6}}}
Gather[list, IntersectingQ]
{{{1, 2}, {1, 3}, {2, 5}, {1, 5}},
{{6, 7}, {6, 9}, {4, 6}}}
answered Nov 6 at 20:01
kglr
170k8193398
170k8193398
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f185448%2fselect-connected-subsets-of-integer-pairs%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password