Select connected subsets of integer pairs?











up vote
6
down vote

favorite
1












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!










share|improve this question


























    up vote
    6
    down vote

    favorite
    1












    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!










    share|improve this question
























      up vote
      6
      down vote

      favorite
      1









      up vote
      6
      down vote

      favorite
      1






      1





      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!










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 6 at 15:34









      Kagaratsch

      4,53631246




      4,53631246






















          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







          share|improve this answer























          • 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


















          up vote
          6
          down vote













          Gather[list, IntersectingQ]



          {{{1, 2}, {1, 3}, {2, 5}, {1, 5}},

          {{6, 7}, {6, 9}, {4, 6}}}







          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "387"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            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
































            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







            share|improve this answer























            • 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















            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







            share|improve this answer























            • 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













            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







            share|improve this answer














            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








            share|improve this answer














            share|improve this answer



            share|improve this answer








            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 function Length[#] > 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












            • @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
















            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










            up vote
            6
            down vote













            Gather[list, IntersectingQ]



            {{{1, 2}, {1, 3}, {2, 5}, {1, 5}},

            {{6, 7}, {6, 9}, {4, 6}}}







            share|improve this answer

























              up vote
              6
              down vote













              Gather[list, IntersectingQ]



              {{{1, 2}, {1, 3}, {2, 5}, {1, 5}},

              {{6, 7}, {6, 9}, {4, 6}}}







              share|improve this answer























                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}}}







                share|improve this answer












                Gather[list, IntersectingQ]



                {{{1, 2}, {1, 3}, {2, 5}, {1, 5}},

                {{6, 7}, {6, 9}, {4, 6}}}








                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 6 at 20:01









                kglr

                170k8193398




                170k8193398






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    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




















































































                    這個網誌中的熱門文章

                    Xamarin.form Move up view when keyboard appear

                    Post-Redirect-Get with Spring WebFlux and Thymeleaf

                    Anylogic : not able to use stopDelay()