Create lists of equivalences from pairs

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
9
down vote

favorite
2












I have a list of pairs, e.g.,



ex1=1,2,1,3,2,3, 4,5, 6,7,6,8, 7,8


that I would like to merge into the list



output=1,2,3,4,5,6,7,8


via the transitive property. More explicitly, if i,jis a pair in the original list, then i and j should both be in the same list. Furthermore, if i,j and j,k are pairs, then i, j, and k should all be in the same list. Another way to view this problem is that we begin with lists of binary equivalences and wish to construct all the equivalence classes.



In the case that the original list of pairs satisfies the property that if i,j is listed as a pair then j,i is also listed, e.g.,



ex2=1,2,2,1,1,3,3,1, 2,3,3,2, 4,5,5,4, 6,7,7,6,6,8,8,6,7,8,8,7


then the following function works:



equivClasses[listOfPairs_]:=listOfPairs//GatherBy[#, First]&//Map[Fold[Union], #, 1]&// Union


However, this function fails when the reverse of each pair doesn't necessarily appear, e.g., equivClasses[ex1]=1,2,3,2,3,.... We can manufacture such a new list easily, e.g., by



newList=(Sort/@ex1)~Join~(ReverseSort/@ex1)//Union


and then calling equivClasses as before.



Q1 Is the above function equivClasses reasonable? It feels a bit kludgy to me, in particular insofar as the code creates $n$-copies of each sublist of length $n$ before Union-ing them away.



Q2 The scope in which this problem has arisen is somewhat large and computationally expensive. The list of pairs that I can generate contains ~10^5 pairs of integers and takes ~10min if I only generate the pairs i,j with i < j. I can certainly do the Sort...~Join~ReverseSort business, this seems a bit inefficient insofar as it doubles the memory usage (although this step does run reasonably fast, about 0.005sec on my machine). How can I optimize this code?



Q3 Particularly problematic is the case when the list of pairs doesn't include all pairwise comparisons, e.g., 1,2,2,3 which should still get sorted into 1,2,3. What can I do in this case?










share|improve this question

















  • 1




    closely related: Using Gather to rearrange my data, Computing the equivalence classes of the symmetric transitive closure of a relation
    – kglr
    Oct 3 at 19:41














up vote
9
down vote

favorite
2












I have a list of pairs, e.g.,



ex1=1,2,1,3,2,3, 4,5, 6,7,6,8, 7,8


that I would like to merge into the list



output=1,2,3,4,5,6,7,8


via the transitive property. More explicitly, if i,jis a pair in the original list, then i and j should both be in the same list. Furthermore, if i,j and j,k are pairs, then i, j, and k should all be in the same list. Another way to view this problem is that we begin with lists of binary equivalences and wish to construct all the equivalence classes.



In the case that the original list of pairs satisfies the property that if i,j is listed as a pair then j,i is also listed, e.g.,



ex2=1,2,2,1,1,3,3,1, 2,3,3,2, 4,5,5,4, 6,7,7,6,6,8,8,6,7,8,8,7


then the following function works:



equivClasses[listOfPairs_]:=listOfPairs//GatherBy[#, First]&//Map[Fold[Union], #, 1]&// Union


However, this function fails when the reverse of each pair doesn't necessarily appear, e.g., equivClasses[ex1]=1,2,3,2,3,.... We can manufacture such a new list easily, e.g., by



newList=(Sort/@ex1)~Join~(ReverseSort/@ex1)//Union


and then calling equivClasses as before.



Q1 Is the above function equivClasses reasonable? It feels a bit kludgy to me, in particular insofar as the code creates $n$-copies of each sublist of length $n$ before Union-ing them away.



Q2 The scope in which this problem has arisen is somewhat large and computationally expensive. The list of pairs that I can generate contains ~10^5 pairs of integers and takes ~10min if I only generate the pairs i,j with i < j. I can certainly do the Sort...~Join~ReverseSort business, this seems a bit inefficient insofar as it doubles the memory usage (although this step does run reasonably fast, about 0.005sec on my machine). How can I optimize this code?



Q3 Particularly problematic is the case when the list of pairs doesn't include all pairwise comparisons, e.g., 1,2,2,3 which should still get sorted into 1,2,3. What can I do in this case?










share|improve this question

















  • 1




    closely related: Using Gather to rearrange my data, Computing the equivalence classes of the symmetric transitive closure of a relation
    – kglr
    Oct 3 at 19:41












up vote
9
down vote

favorite
2









up vote
9
down vote

favorite
2






2





I have a list of pairs, e.g.,



ex1=1,2,1,3,2,3, 4,5, 6,7,6,8, 7,8


that I would like to merge into the list



output=1,2,3,4,5,6,7,8


via the transitive property. More explicitly, if i,jis a pair in the original list, then i and j should both be in the same list. Furthermore, if i,j and j,k are pairs, then i, j, and k should all be in the same list. Another way to view this problem is that we begin with lists of binary equivalences and wish to construct all the equivalence classes.



In the case that the original list of pairs satisfies the property that if i,j is listed as a pair then j,i is also listed, e.g.,



ex2=1,2,2,1,1,3,3,1, 2,3,3,2, 4,5,5,4, 6,7,7,6,6,8,8,6,7,8,8,7


then the following function works:



equivClasses[listOfPairs_]:=listOfPairs//GatherBy[#, First]&//Map[Fold[Union], #, 1]&// Union


However, this function fails when the reverse of each pair doesn't necessarily appear, e.g., equivClasses[ex1]=1,2,3,2,3,.... We can manufacture such a new list easily, e.g., by



newList=(Sort/@ex1)~Join~(ReverseSort/@ex1)//Union


and then calling equivClasses as before.



Q1 Is the above function equivClasses reasonable? It feels a bit kludgy to me, in particular insofar as the code creates $n$-copies of each sublist of length $n$ before Union-ing them away.



Q2 The scope in which this problem has arisen is somewhat large and computationally expensive. The list of pairs that I can generate contains ~10^5 pairs of integers and takes ~10min if I only generate the pairs i,j with i < j. I can certainly do the Sort...~Join~ReverseSort business, this seems a bit inefficient insofar as it doubles the memory usage (although this step does run reasonably fast, about 0.005sec on my machine). How can I optimize this code?



Q3 Particularly problematic is the case when the list of pairs doesn't include all pairwise comparisons, e.g., 1,2,2,3 which should still get sorted into 1,2,3. What can I do in this case?










share|improve this question













I have a list of pairs, e.g.,



ex1=1,2,1,3,2,3, 4,5, 6,7,6,8, 7,8


that I would like to merge into the list



output=1,2,3,4,5,6,7,8


via the transitive property. More explicitly, if i,jis a pair in the original list, then i and j should both be in the same list. Furthermore, if i,j and j,k are pairs, then i, j, and k should all be in the same list. Another way to view this problem is that we begin with lists of binary equivalences and wish to construct all the equivalence classes.



In the case that the original list of pairs satisfies the property that if i,j is listed as a pair then j,i is also listed, e.g.,



ex2=1,2,2,1,1,3,3,1, 2,3,3,2, 4,5,5,4, 6,7,7,6,6,8,8,6,7,8,8,7


then the following function works:



equivClasses[listOfPairs_]:=listOfPairs//GatherBy[#, First]&//Map[Fold[Union], #, 1]&// Union


However, this function fails when the reverse of each pair doesn't necessarily appear, e.g., equivClasses[ex1]=1,2,3,2,3,.... We can manufacture such a new list easily, e.g., by



newList=(Sort/@ex1)~Join~(ReverseSort/@ex1)//Union


and then calling equivClasses as before.



Q1 Is the above function equivClasses reasonable? It feels a bit kludgy to me, in particular insofar as the code creates $n$-copies of each sublist of length $n$ before Union-ing them away.



Q2 The scope in which this problem has arisen is somewhat large and computationally expensive. The list of pairs that I can generate contains ~10^5 pairs of integers and takes ~10min if I only generate the pairs i,j with i < j. I can certainly do the Sort...~Join~ReverseSort business, this seems a bit inefficient insofar as it doubles the memory usage (although this step does run reasonably fast, about 0.005sec on my machine). How can I optimize this code?



Q3 Particularly problematic is the case when the list of pairs doesn't include all pairwise comparisons, e.g., 1,2,2,3 which should still get sorted into 1,2,3. What can I do in this case?







list-manipulation performance-tuning






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Oct 3 at 19:10









erfink

324111




324111







  • 1




    closely related: Using Gather to rearrange my data, Computing the equivalence classes of the symmetric transitive closure of a relation
    – kglr
    Oct 3 at 19:41












  • 1




    closely related: Using Gather to rearrange my data, Computing the equivalence classes of the symmetric transitive closure of a relation
    – kglr
    Oct 3 at 19:41







1




1




closely related: Using Gather to rearrange my data, Computing the equivalence classes of the symmetric transitive closure of a relation
– kglr
Oct 3 at 19:41




closely related: Using Gather to rearrange my data, Computing the equivalence classes of the symmetric transitive closure of a relation
– kglr
Oct 3 at 19:41










3 Answers
3






active

oldest

votes

















up vote
10
down vote



accepted










ConnectedComponents[Graph[ex1]] would be easier.






share|improve this answer




















  • Really a cool solution!
    – mgamer
    Oct 3 at 19:20










  • @mgamer Thank you. =D
    – Henrik Schumacher
    Oct 3 at 19:31










  • Hah! That's super slick. Especially since this is happening in a graph theoretic context (construction of a Fischer cover). Thank you!
    – erfink
    Oct 3 at 19:41










  • You're welcome!
    – Henrik Schumacher
    Oct 3 at 19:47

















up vote
9
down vote













ConnectedComponents[ex1] 



6, 7, 8, 1, 2, 3, 4, 5







share|improve this answer
















  • 2




    ... this more convenient form seems to be undocumented.
    – kglr
    Oct 3 at 19:47

















up vote
5
down vote













FixedPoint[Union @@@ Gather[#, IntersectingQ] &, ex1]



1, 2, 3, 4, 5, 6, 7, 8







share|improve this answer






















  • Seems to fail for 1,2,2,3,3,4 ?
    – erfink
    Oct 3 at 20:08






  • 1




    @erfink I made an update that solves that case as well, please let me know if there are cases where the new solution doesn't work.
    – C. E.
    Oct 3 at 20:13










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: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
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%2f183060%2fcreate-lists-of-equivalences-from-pairs%23new-answer', 'question_page');

);

Post as a guest






























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
10
down vote



accepted










ConnectedComponents[Graph[ex1]] would be easier.






share|improve this answer




















  • Really a cool solution!
    – mgamer
    Oct 3 at 19:20










  • @mgamer Thank you. =D
    – Henrik Schumacher
    Oct 3 at 19:31










  • Hah! That's super slick. Especially since this is happening in a graph theoretic context (construction of a Fischer cover). Thank you!
    – erfink
    Oct 3 at 19:41










  • You're welcome!
    – Henrik Schumacher
    Oct 3 at 19:47














up vote
10
down vote



accepted










ConnectedComponents[Graph[ex1]] would be easier.






share|improve this answer




















  • Really a cool solution!
    – mgamer
    Oct 3 at 19:20










  • @mgamer Thank you. =D
    – Henrik Schumacher
    Oct 3 at 19:31










  • Hah! That's super slick. Especially since this is happening in a graph theoretic context (construction of a Fischer cover). Thank you!
    – erfink
    Oct 3 at 19:41










  • You're welcome!
    – Henrik Schumacher
    Oct 3 at 19:47












up vote
10
down vote



accepted







up vote
10
down vote



accepted






ConnectedComponents[Graph[ex1]] would be easier.






share|improve this answer












ConnectedComponents[Graph[ex1]] would be easier.







share|improve this answer












share|improve this answer



share|improve this answer










answered Oct 3 at 19:13









Henrik Schumacher

41.1k258124




41.1k258124











  • Really a cool solution!
    – mgamer
    Oct 3 at 19:20










  • @mgamer Thank you. =D
    – Henrik Schumacher
    Oct 3 at 19:31










  • Hah! That's super slick. Especially since this is happening in a graph theoretic context (construction of a Fischer cover). Thank you!
    – erfink
    Oct 3 at 19:41










  • You're welcome!
    – Henrik Schumacher
    Oct 3 at 19:47
















  • Really a cool solution!
    – mgamer
    Oct 3 at 19:20










  • @mgamer Thank you. =D
    – Henrik Schumacher
    Oct 3 at 19:31










  • Hah! That's super slick. Especially since this is happening in a graph theoretic context (construction of a Fischer cover). Thank you!
    – erfink
    Oct 3 at 19:41










  • You're welcome!
    – Henrik Schumacher
    Oct 3 at 19:47















Really a cool solution!
– mgamer
Oct 3 at 19:20




Really a cool solution!
– mgamer
Oct 3 at 19:20












@mgamer Thank you. =D
– Henrik Schumacher
Oct 3 at 19:31




@mgamer Thank you. =D
– Henrik Schumacher
Oct 3 at 19:31












Hah! That's super slick. Especially since this is happening in a graph theoretic context (construction of a Fischer cover). Thank you!
– erfink
Oct 3 at 19:41




Hah! That's super slick. Especially since this is happening in a graph theoretic context (construction of a Fischer cover). Thank you!
– erfink
Oct 3 at 19:41












You're welcome!
– Henrik Schumacher
Oct 3 at 19:47




You're welcome!
– Henrik Schumacher
Oct 3 at 19:47










up vote
9
down vote













ConnectedComponents[ex1] 



6, 7, 8, 1, 2, 3, 4, 5







share|improve this answer
















  • 2




    ... this more convenient form seems to be undocumented.
    – kglr
    Oct 3 at 19:47














up vote
9
down vote













ConnectedComponents[ex1] 



6, 7, 8, 1, 2, 3, 4, 5







share|improve this answer
















  • 2




    ... this more convenient form seems to be undocumented.
    – kglr
    Oct 3 at 19:47












up vote
9
down vote










up vote
9
down vote









ConnectedComponents[ex1] 



6, 7, 8, 1, 2, 3, 4, 5







share|improve this answer












ConnectedComponents[ex1] 



6, 7, 8, 1, 2, 3, 4, 5








share|improve this answer












share|improve this answer



share|improve this answer










answered Oct 3 at 19:43









kglr

164k8188388




164k8188388







  • 2




    ... this more convenient form seems to be undocumented.
    – kglr
    Oct 3 at 19:47












  • 2




    ... this more convenient form seems to be undocumented.
    – kglr
    Oct 3 at 19:47







2




2




... this more convenient form seems to be undocumented.
– kglr
Oct 3 at 19:47




... this more convenient form seems to be undocumented.
– kglr
Oct 3 at 19:47










up vote
5
down vote













FixedPoint[Union @@@ Gather[#, IntersectingQ] &, ex1]



1, 2, 3, 4, 5, 6, 7, 8







share|improve this answer






















  • Seems to fail for 1,2,2,3,3,4 ?
    – erfink
    Oct 3 at 20:08






  • 1




    @erfink I made an update that solves that case as well, please let me know if there are cases where the new solution doesn't work.
    – C. E.
    Oct 3 at 20:13














up vote
5
down vote













FixedPoint[Union @@@ Gather[#, IntersectingQ] &, ex1]



1, 2, 3, 4, 5, 6, 7, 8







share|improve this answer






















  • Seems to fail for 1,2,2,3,3,4 ?
    – erfink
    Oct 3 at 20:08






  • 1




    @erfink I made an update that solves that case as well, please let me know if there are cases where the new solution doesn't work.
    – C. E.
    Oct 3 at 20:13












up vote
5
down vote










up vote
5
down vote









FixedPoint[Union @@@ Gather[#, IntersectingQ] &, ex1]



1, 2, 3, 4, 5, 6, 7, 8







share|improve this answer














FixedPoint[Union @@@ Gather[#, IntersectingQ] &, ex1]



1, 2, 3, 4, 5, 6, 7, 8








share|improve this answer














share|improve this answer



share|improve this answer








edited Oct 3 at 20:12

























answered Oct 3 at 19:55









C. E.

48k392194




48k392194











  • Seems to fail for 1,2,2,3,3,4 ?
    – erfink
    Oct 3 at 20:08






  • 1




    @erfink I made an update that solves that case as well, please let me know if there are cases where the new solution doesn't work.
    – C. E.
    Oct 3 at 20:13
















  • Seems to fail for 1,2,2,3,3,4 ?
    – erfink
    Oct 3 at 20:08






  • 1




    @erfink I made an update that solves that case as well, please let me know if there are cases where the new solution doesn't work.
    – C. E.
    Oct 3 at 20:13















Seems to fail for 1,2,2,3,3,4 ?
– erfink
Oct 3 at 20:08




Seems to fail for 1,2,2,3,3,4 ?
– erfink
Oct 3 at 20:08




1




1




@erfink I made an update that solves that case as well, please let me know if there are cases where the new solution doesn't work.
– C. E.
Oct 3 at 20:13




@erfink I made an update that solves that case as well, please let me know if there are cases where the new solution doesn't work.
– C. E.
Oct 3 at 20:13

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f183060%2fcreate-lists-of-equivalences-from-pairs%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Peggy Mitchell

Palaiologos

The Forum (Inglewood, California)