Solving Recursion Problems with MMA - R.Gaylord

  • Thread starter Thread starter Nile3
  • Start date Start date
  • Tags Tags
    Recursion
Click For Summary

Discussion Overview

The discussion revolves around the implementation of a recursive function in Mathematica (MMA) for generating k-element subsets from a given set. Participants explore the mechanics of the function, its recursive nature, and seek advice on understanding and creating similar functions.

Discussion Character

  • Exploratory
  • Technical explanation
  • Homework-related

Main Points Raised

  • One participant shares a specific example of a recursive function for generating subsets and expresses difficulty in understanding its construction.
  • Another participant suggests using a more compact trace method to analyze the function's behavior, highlighting the dual recursion involved in the implementation.
  • Clarifications are provided regarding the base cases of the recursion and the logic behind the recursive calls, emphasizing the importance of understanding how elements are combined.
  • A participant expresses a desire to learn more about creating such functions independently and asks for resources on recursive functions.
  • Recommendations for books on LISP and Scheme programming languages are provided, noting their focus on recursion as a key concept.

Areas of Agreement / Disagreement

Participants generally agree on the complexity of the recursive function and the need for further study, but there is no consensus on how to independently create such functions without additional resources.

Contextual Notes

Participants mention the challenges of understanding recursion and the potential for different methods of tracing function calls, indicating that the discussion may involve varying levels of familiarity with recursion concepts.

Who May Find This Useful

This discussion may be useful for individuals learning about recursion in programming, particularly in the context of Mathematica, as well as those seeking resources for deeper understanding of recursive functions.

Nile3
Messages
42
Reaction score
0
Hello, I'm going through Introduction to programming with MMA by R.Gaylord and there is an exemple in chapter 7 about recursively creating k-elements subsets of a given set.

subsets[Range[5], 2] should give {{1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2,5}, {3,4}, {3, 5}, {4, 5}}

The problem is, I can't figure out how he created this function. He explains only the tip of the iceberg. I tried the common ways of analyzing using trace but the resulting output is way too big. Any tips on why this function works and how you would go about creating it from just knowing what you have to do would be appreciated.


Code:
subsets[lis_, 0] := {{}}
subsets[{}, k_] := {}
subsets[lis_, k_] := Module[{res = subsets[Rest[lis], k - 1]},
  Join[
   Map[(Join[{First[lis]}, #] &), res],
   subsets[Rest[lis], k]
   ]
  ]


Code:
In[9]:= subsets[Range[5], 2]

Out[9]= {{1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}, {3, 
  4}, {3, 5}, {4, 5}}
 
Physics news on Phys.org
I don't know what trace method you used, but this is more compact.
Trace[subsets[Range[5], 2], subsets[_, _]]
That only shows each call to subsets and might be more explanatory.

His function is a little tricky because it is using a sort of double recursion. On one hand it is nibbling away at the list of items still available to construct a subset and on the other it is nibbling away at the number of elements still needed to construct the subset.

As always with recursion, first comes the base case to stop the recursion. Since he has double recursion going on he has two base cases.

First
subsets[lis_, 0] := {{}}
means if I have nibbled down to where no more elements are needed to make a subset then I return the empty list to terminate the process of appending more and more elements to make up the n subset.
And
subsets[{}, k_] := {}
means if I am trying to nibble off more elements to make a subset but I have exhausted my supply then again I have to stop the process, but in a different way that we need to understand in a moment.

Now the recursion itself
subsets[lis_, k_] := Module[{res = subsets[Rest[lis], k - 1]},
Join[
Map[(Join[{First[lis]}, #] &), res],
subsets[Rest[lis], k]
]
]
The res=subsets[] will produce all the n-1 element subsets from the tail of the available list.

The Map[(Join[{First[lis]}, #] &), res] will combine the first element of the list with every possible n-1 subset from the tail.

And finally there are the n element subsets from the tail of the list.

Now if you use the Trace method I showed above you may be able to see how each of those recursion steps are either nibbling away at the rest of list or are nibbling away with n-1.

You can use a slight change to use Trace to look at the results from subsets calls
subsets[lis_, k_] := Module[{res = subsets[Rest[lis], k - 1], v},
Join[Map[(Join[{First[lis]}, #] &), res], v = subsets[Rest[lis], k]]];
Trace[subsets[Range[5], 2], _ = _]

That introduces a variable v to be used for assignments and tells Trace to only show assignments. So res= and v= will be shown in the trace. You can compare and contrast that with the previous version using Trace to gain some insight.

Sometimes I will position the cursor and insert a newline into the middle of a Trace output. That creates a copy of it and puts it into a new cell. Then I will insert more newlines, trying to organize the results vertically so I can better walk through the results and try to gain an understanding.

Study this for a while and try to decide if this is enough or if you need more?
 
Great answer, thank you very much. I still don't know how to invent this type of functions on my own but I'll keep studying.

Do you know of a good website to get many examples of recursive functions?
 
See if you can borrow from a library or buy inexpensive old copies of books on LISP and Scheme programming languages. I'd advise at least trying to get a peek at any book before buying it over the net, unless the price means it really doesn't matter. Both LISP and Scheme texts will spend a lot of time introducing you to to recursion.

Winston's LISP text might be good, but it looks like it drank the "object oriented" Koolaid in later editions.
http://www.bestwebbuys.com/books/search.jsp?isrc=b-home-search&N=0&Ntt=winston+lisp&Ntk=All

Abelson's Structure and Interpretation might be good.
http://www.bestwebbuys.com/Structur...ter-Programs-ISBN-9780070004221?isrc=b-search
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 3 ·
Replies
3
Views
5K
  • · Replies 6 ·
Replies
6
Views
4K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
Replies
8
Views
2K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 10 ·
Replies
10
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 7 ·
Replies
7
Views
3K