Thursday, July 7, 2011

Fast! iterative algorithm for generating permutations from sets' single elements

I like it. I like this one. Last algorithm for this problem (here) was O(n^3). Now it's O(n). It may mean two things: first one was very shitty, or that the second one is really good. Probably both are true.

I came back home, without a laptop. With one hand holding the Algorithms book (I really recommend that one) and with notebook and a pen in the other. I choose notebook and pen. It did the trick.

I know I masturbate on that issue, but it's fun. After some furious paper programming I got here:


I asked myself 3 questions at the beginning:
  1. How many times "1" will be first?
  2. How many times "4" will be in the result?
  3. How many times "5" will be in the result?"

I wanted to answer that questions without the use of any offset indexes kept in memory in other array. Keep it simple: what do I know about my input data?
So my answers were like that:
  1. If I take all the sizes of following tables and multiply them, I'll get 12.
  2. Always, cause it's a single element array, so 36 (total possible permutations.
  3. The same as answer number one. 6 times in cycle of 3, 18.

The main conclusion was that I can fill the results array column by column instead of row by row. All permutations will be fully calculated at once, at the very end. No gathering the permutation by permutation and then pushing it to the results. No no no, that needs indexes and traveling across the array many times. This idea dropped the complexity from O(n^3) to O(n).

Cycles, subcycles, offsets. The most important thing was to calculate a proper index in the result table and stick the current argument element exactly there (IBID). No more talk, code is below and benchmark is on the gist comment.

4 comments:

  1. Kuba you definitely need to go out more...XD

    ReplyDelete
  2. 1/8
    ...
    a tak serio to genialne :)

    ReplyDelete
  3. Hi , Algorithm looks good . but is that working version ? and do you have a java equivalent of this ?

    Need little more clarity in the section of -
    '# prepare the results table' of code.

    It looks like 'repeatCounter' value is always getting as 1. Can you please update the working version if possible. Thanks.

    ReplyDelete
  4. Hey raveendra! This version is working, I just copy pasted it and works good. But don't do it this way if you don't have to :) check out this: http://jakubgodawa.blogspot.com/2011/07/how-to-re-implement-cartesian-product.html

    Cheers!

    ReplyDelete