aggregation of related elements in a list
- To: mathgroup at smc.vnet.net
- Subject: [mg61542] aggregation of related elements in a list
- From: leigh pascoe <leigh at cephb.fr>
- Date: Sat, 22 Oct 2005 00:35:27 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Dear Mathgroup, I would like to construct a function to transform a list of integers into a list of lists of related members. Suppose we have the finite list {x1,x2,x3,..........xN} and a test function ( relatedQ[x_,y_,n_] ) that decides whether two elements are related. The actual test may vary, but returns True or False for any two elements as a function of n (n is an independent variable not the number of elements in the list}. I would like to process this list to aggregate those members that are related either directly to each other or to a common element. For example if x1 is unrelated to any other element in the list, x2 is related to x5 but not x7 and x5 is related to x7 etc. would produce the list of lists {{x1},{x2,x5,x7),.......} To take a specific example, assume we have the list list={1,2,6,7,8,9,11,16} and that application of the relatedQ, test to all possible pairs yields the list of related pairs prlist={{1,2},{1,6},{2,6},{2,7},{6,7},{6,11},{7,8},{7,11},{11,16}} Using the list and the list of related pairs we can deduce the desired list of lists as {{1,2,6,7,8,11,16},{9}} If 6 were not in the original list we would get instead {{1,2},{7,8,11,16},{9}} I have tried to develop a Mathematica function or procedure to produce this list, but am having trouble achieving it. Can anyone help? The algorithm I have been trying to implement is: - form a list of all related pairs and singletons in the original list by comparing all pairs to prlist - then compare the first element in the resulting list with each of the others in that list and form the Union of all those where (Intersection !={}) - delete all pairs retained for the Union. - repeat the process for the next element in the list and so on. The following ugly code seems to work on some lists, but with others gives me an error message, presumably an objection to a dynamic redefinition of the list inside a Do statement. In[87]:= chains[n_]:=Block[{lst,tmp,tmp2,lst2}, lst={1,2,6,7,8,9,11,16}; tmp=Flatten[ Part[Reap[ Do[{If[Intersection[{{Part[lst,i],Part[lst,j]}}, Edges[gr1[n]]]\[NotEqual]{}, Sow[{Part[lst,i],Part[lst,j]}]],Sow},{i,1,Length[lst]-1},{j, i+1,Length[lst]}]],2],1]; tmp2=Part[ Reap[Do[If[Intersection[{lst[[i]]},Flatten[tmp]]\[Equal]{}, Sow[lst[[i]]]],{i,1,Length[lst]}]],2]; lst2=Union[tmp,tmp2]; Do [ { If [ Intersection[lst2[[i]],lst2[[j]]]\[NotEqual]{}, {lst2[[i]]=Union[lst2[[i]],lst2[[j]]],lst2=Delete[lst2,j]} ] }, {i,1,Length[lst2]-1}, {j,i+1,Length[lst2]} ]; lst2 ] chains[4] I have been doing much Intersecting, Unions, Deletions, nested loops and Sowing, but have so far been unable to Reap the result that I want! There should be a simple recursive function that will do what I want, but I can't find it. Thanks for any help LP
- Follow-Ups:
- Re: aggregation of related elements in a list
- From: Daniel Lichtblau <danl@wolfram.com>
- Re: aggregation of related elements in a list