Question

PHP Permutation

Asked by: Yuengling

This code is extremely slow, is there a way to make it faster?
When trying to permutate 20 numbers, it takes quite a long time.

I'd also like to  select a certain number out of 20
For example,  I may want only 7 out of 20 and find all possible permutation with the
length of 7 numbers instead of seeing all possibility of 20.

<?
      $numbers =Array();
      $length =20;

      function permutate($n)
      {
            global $numbers;
            global $length;

              if ($n==1) {
                /* print current permutation */
                for ($i=0; $i< $length; $i++)
                          print ($numbers[$i]);
                  print ("<BR>\n");
              }
                else {
                   for ($i=0; $i< $n; $i++) {
                    $tmp = $numbers[$i];
                    $numbers[$i] = $numbers[$n - 1];
                    $numbers[$n - 1] = $tmp;

                    permutate($n-1);

                    $tmp = $numbers[$i];
                    $numbers[$i] = $numbers[$n - 1];
                    $numbers[$n - 1] = $tmp;
            }
        }
}
  for ($i=0; $i< $length; $i++){
     $numbers[$i] = $i;
   }
  permutate($length);      
?>

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2003-09-27 at 23:12:09ID20750879
Tags

php

,

permutation

Topic

PHP Scripting Language

Participating Experts
4
Points
340
Comments
31

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. r-permutation
    I need an algorithm that will generate, in lexicographic order, permutations of 'k' letters from 'n' objects. e.g. 6 letters from an alphabet of 26 abcdef abcdeg abcdeh . abcdez abcdfe . abcdze etc. Does anyone have access to a source?
  2. Permutation Algorithm
    Given a string "ABC" (a sequence of three items, all different from one another, initially sorted low-to-high) the following list includes all possible permutations of that string: ABC ACB BAC BCA CAB CBA What I need is an *algorithm* that will generate each and e...
  3. Permutations and Combinations
    Experts, I need your specialized assistance for writing a script to do permutations and combinations or words, in similar way such as: http://www.wcrl.ars.usda.gov/cec/java/showcomb.htm But with a differential, the user writes the sequence of letter that want to permute or...
  4. php Permutation
    re-posting since I am not getting much response on the other thread- http://oldlook.experts-exchange.com/Web/Web_Languages/PHP/Q_20750879.html This is the permutation code i came up with, however not very efficent. <? $numbers =Array(); $length =20; ...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: VGRPosted on 2003-09-28 at 09:33:38ID: 9445745

to speed it up, yes, get 7 out of 20. Just add a parameter (&$nbsofar) that is incrtemented each time a perutation is finished ; your recursive function will then stop and traceback if the threashold of 7 (for instance) is reached.

 

by: YuenglingPosted on 2003-09-28 at 10:02:49ID: 9445852

Yes i had considered that, That will mean I have to complete all 20 first before I find the first 7 and also
that will also give me duplicates.

For example   start with a smaller number for simplicity sake 10 numbers and I want to find 7 out of 10

01234569870
01234567908

as you can see , both are unique combination, however the first 7 number are the same.

I am trying to get all posible permutations  for 7 out of 20 numbers available, and yet have 7 unique combinations for each  
 ( 20! )  possible combinations

Isnt there a much faster way to do this?

 

by: shmertPosted on 2003-09-28 at 14:32:58ID: 9447146

There are 2 main speed factors which may be slowing you down.  One, recursion might not be the best bet.  Recursion is usually not as efficient as looping, although it can reduce the amount of code you write.  The most optimal form of recursion (I forget the term for this) is where the recursive call is the last line in the function, so the interpreter can discard the state of the current function when it enters the next function.  This isn't the type of recursion you're using, however.  When you have a loop recursing down 20 levels several thousand times, things are bound to get slow...

Also, there is some (minor) overhead involved in method calls in PHP.  Changing from recursive calls to several nested loops should help trim some time off your function also.  Which is a shame, because your recursive method is nice and elegant, and doesn't use much code.

 

by: inq123Posted on 2003-10-03 at 14:24:24ID: 9488114

Hi Yuengling,

May I ask why the permutate function has this interesting implementation?  Is it important to preserve the order of the long numbers your script prints?  And also why the long numbers have double digits in them?  Is that important?  It does not make sense to have double digits in them because in your permutate function, these double digits would never be separated, and would not truly be permuated.

I think it'd be quite hard to design a flexible permutate function using purely loop.  This is one classic case where recursion should be used.

Cheers!

 

by: inq123Posted on 2003-10-03 at 14:49:05ID: 9488253

Yuengling,

I made this version.  It doesn't obey the order of permutation as your printout has, but it offers true permuation (it doesn't have the problem I mentioned above of your script that has non-permuted double digits) and easier to read.  In addition, it's over 6 times faster than your script.  Here is my script:

<?
  $numbers =Array();
  $length =20;
  $count = 0;
  $time = time();
  permutate($length);

  function permutate($n)
  {
    global $numbers, $length, $count, $time;
    for($i = 0; $i < 10; $i++)
    {
      $numbers[$n - 1] = $i;
      if($n == 1)
      {
/*         for($j = 0; $j < $length; $j++)
          print $numbers[$j];
        print "<BR>\n"; */
        if($count++ == 5000000)
        {
          print "total time used: " . (time() - $time) . "<br>\n";
          exit;
        }
      }
      else
      {
        permutate($n - 1);
      }
    }
  }
?>

Now here's a modified version of your script where I added equivalent statements to enable speed comparison (notice that I had to use 500,000 in your script so that the script does not exceed 30-sec max set on my server, but my script finishes in 25 sec. for 5,000,000 number generations):

<?
     $numbers =Array();
     $length =20;
  $count = 0;
  $time = time();

     function permutate($n)
     {
          global $numbers;
          global $length;
          global $count, $time;
            if ($n==1) {
              /* print current permutation */
/*               for ($i=0; $i< $length; $i++)
                      print ($numbers[$i]);
               print ("<BR>\n"); */
        if($count++ == 500000)
        {
          print "total time used: " . (time() - $time) . "<br>\n";
          exit;
        }
            }
                else {
                 for ($i=0; $i< $n; $i++) {
                 $tmp = $numbers[$i];
                 $numbers[$i] = $numbers[$n - 1];
                 $numbers[$n - 1] = $tmp;

                 permutate($n-1);

                 $tmp = $numbers[$i];
                 $numbers[$i] = $numbers[$n - 1];
                 $numbers[$n - 1] = $tmp;
          }
       }
}
  for ($i=0; $i< $length; $i++){
     $numbers[$i] = $i;
   }
  permutate($length);    
?>

Mine ran 25 sec for 5 million numbers, and yours ran 16 sec for 0.5 million numbers, a 6.4 X difference.

 

by: inq123Posted on 2003-10-03 at 14:53:05ID: 9488273

I think it's hard to be even faster as I used as simple as possible (unless someone did it using loop and still allow passing in the length of the number, which is not an easy task).  But please

BTW, I do think this algorithm, although not difficult, somehow deserves a bit more points (just so I could become top 15 in PHP this year earlier). :-)

 

by: inq123Posted on 2003-10-03 at 15:47:59ID: 9488514

Just realized two important things:
1. if all you care about is to permutate first 7 digits completely, DO NOT use your old version!  That one would be thousands times slower to permutate all 7 digits than my version even if string length is 10 digits long.
2. you should never use my solution to do anything like cracking passwords etc.  Thank you.

 

by: KaritzPosted on 2003-10-04 at 03:48:32ID: 9490429

Here is a function that can work for you. I have not tested its speed put it should be higher than that of a recursive one.

function permutation($n) {
  $result = 1;
  if (!isset($k)) {
    $k = $n;
  }
  while($k--) {
    $result *= $n--;
  }
  return $result;
}

 

by: VGRPosted on 2003-10-04 at 03:55:37ID: 9490447

@inq123 : I've a proposition : we merge our loginnames and add our points :D

I'm sure the Mods, Admins, EE staff people will be happy ;-)

 

by: inq123Posted on 2003-10-04 at 05:46:00ID: 9490703

I'd be happy too, you have a lot more points than I do! :-)

BTW, Karitz, your permutation function's doing the permutation calculation P(n, k), while the OP asked for a function to display all the numbers that's permutated, meaning traverse through all the P(n, k) numbers (and potentially display each one).

 

by: inq123Posted on 2003-10-04 at 05:51:17ID: 9490712

BTW, sorry for always post immediately after I posted -- I always forget something before I press the "submit" button.

I asked OP whether the order of those numbers were important, but now I thought about it and think they can't be.  If they're important, then you're pretty much stuck at the one implementation OP presented, and there's not much room to improve there.  So it can't be important.

But one thing important that I semi-mentioned is that: OP's version can't be used for length longer than 10 unless modified, otherwise those double digit numbers will defeat the permutation.

Last thing: VGR, I thought Mods, etc. won't be happy to see our loginnames merged, that means there's only one volunteer to clean up and contribute! (although this one login might do more than before).

 

by: VGRPosted on 2003-10-04 at 10:44:11ID: 9491768

more than before... and be up 24 hours a day, and it's one member less, but a more active one.

An idea to elaborate :D

 

by: inq123Posted on 2003-10-04 at 10:49:26ID: 9491788

LOL...

BTW, sorry for slightly cluttering the thread.

 

by: shmertPosted on 2003-10-06 at 21:11:18ID: 9503132

By the way here are some fun factorial facts:
7! = 5040
20! = 2.4329e+18

So, calculating all combinations for 20 possible keys isn't really reasonable.  If you could find some algorithm to compute only the factorials which yeild a unique 7-digit number, I believe that would require (20! * 2) / ((1 + 20 - 7)!) combinations (guessing here).  And that gives you
2 * 20! / 14! = 55,814,400

This is starting to sound like a result set that might be too large to do very much with (?)

 

by: shmertPosted on 2003-10-06 at 21:15:41ID: 9503148

That said, here's a non-recursive algorithm for generating unique permutations of an array of values.  This should be faster than a recursive, but I haven't done time tests yet... (also, this doesn't do a substring of the resulting unique values, like first 7 chars of a 20-char permutation).

<?php

$length = 5; // length of the desired output string
$options = 5; // range of a single character in the output string

$lastComboIndex = $length-1;

$combo = array();
for ($i=0; $i<$length; $i++) {
        $combo[$i] = $i;
}

$trackingArray = array_fill(0, $lastComboIndex , 0);
echo join('-',$combo) . "<br />\n";
$matches = 1;
$dupCount = 0;
while (true) {
        for ($i=0; $i<=$lastComboIndex; $i++) {
                if ($trackingArray[$i] <= $i) {
                        $tmp = $combo[0];
                        $combo[0] = $combo[$i+1];
                        $combo[$i+1] = $tmp;
                        $trackingArray[$i]++;
                        while ($i-- > 0) $trackingArray[$i] = 0;
                        echo join('-',$combo) . "<br />\n";
                        $matches++;
                        break;
                }
                if ($i==$lastComboIndex - 1) {
                        echo "matches: $matches <br />\n";
                        die("DONE!");
                }
        }
}

?>

 

by: inq123Posted on 2003-10-07 at 06:00:15ID: 9505322

shmert, your function's buggy.  You need to check on it.  Here's the output of length=4:

0-1-2-3
1-0-2-3
2-0-1-3
0-2-1-3
1-2-0-3
2-1-0-3
3-1-0-2
1-3-0-2
0-3-1-2
3-0-1-2
1-0-3-2
0-1-3-2
2-1-3-0
1-2-3-0
3-2-1-0
2-3-1-0
1-3-2-0
3-1-2-0
0-1-2-3
1-0-2-3
2-0-1-3
0-2-1-3
1-2-0-3
2-1-0-3
matches: 24
DONE!

It's easy to see your function's wrong because there's no instance where 1 is in last digit.  please note that the only reason your matches is always right is that there're duplicates in your output.  See 2-1-0-3.  

 

by: inq123Posted on 2003-10-07 at 08:01:52ID: 9506289

BTW, I forgot to point out to you shmert that the original question was that take a length of 20 digits, permutate them and take only the first 7 digits.  That is different than permutate only 7 digits.  The function you provided is permutation in true sense (if bugs in your function are fixed), so was the original poster's solution.  But with the original question, really the first 7 digits of 20 numbers would be permutated in the sense that each digit will change from 0-9 (10^7 permutation, not 7!), and while your function and OP's solution both can do that too, they would do that (namely, permutate the first 7 digits from 0-9) millions of times of slower than my solution if length increases to 20.

But of course if OP modifies the question posed, the analysis would be different.

 

by: VGRPosted on 2003-10-07 at 10:31:12ID: 9507462

"shmert, your function's buggy.  " :D  no kidding ? Is that possible ? The Guru made a bug ? :D

 

by: YuenglingPosted on 2003-10-08 at 07:08:07ID: 9513416

inq123,
   I had the opportunity to test and use your code because it was faster, however the code are not of true permutation since there are duplicates, repeating of numbers in each string, so I added a second function that would filter out the duplicates.  The result are stored into the database so that I would only have to run the script once and the result will always be the same so retrieving it from the database would be much faster than doing the permutation everytime.

   I previously was going to go with the code i had made, but it seems to freeze up the apache server once it got to 8 digits permutation, frustrated by the crashing of the apache server (I'm running the script on my personal computer), I switch over to your code thinking that I would not encounter this crashing, but then I noticed that it does the same thing when it reach 8 digits permutation on your code.

   Now, thinking that its must not be the script thats doing it, it must be the configuration problem in either php or apache. I then proceeded to increase the size of memory allowed for a script to 256 mb and increased the length of time executed to 4 hours in php configuration file. I also then went and configure the apache file to allow 4 hours before timeouts, and increased the size of process allowed to 1000.  (The computer is 2.4 ghz with 1gb ram)  And restarted the apache server. I shut down all other programs to allow only just the script to run. I still encounter this same crashing down of the apache server when it encounters 8 digits to permutate and getting only the length of 5 or 6 characters.

Anyone know why it does this ? I've increased the number of points to 320, that also includes the 20 points in the other posting.

If it matters, the database table structure have 9 field, and each field are just a character of length 2 and are as the following

table
----------------
perm, take, a1, a2, a3, a4, a5, a6, a7

i've limits the length of string from 3 up to 7 characters.


The code are as following.....including the filtering out of duplicates.
---------------------------------------------------------------------------------------
<?
      include ('courses_db.php');

       $numbers =Array();
       $perm =Array();
       $length =0;
      $num =0;
      $get =0;
      main();

/*-------------------------------------------------------------------------*/

      function permutate($n)
      {
            global $numbers, $perm, $length, $num, $get;

            for($i = 0; $i < $num; $i++){
                  $numbers[$n - 1] = $i;
                  if($n == 1){
                      for($j = 0; $j < $length; $j++){
                            $perm[$get][$j] =$numbers[$j];
                           }
                               $get++;
                         }
                         else{
                            permutate($n - 1);
                         }
                 }
       }

/*-------------------------------------------------------------------------*/
      function filter()
      {
            global $perm;
            $unique =Array();
            $filter =Array();
            $index =0;

            $size =count($perm);
            for($i =0; $i < $size; $i++){
                  $unique =$perm[$i];
                  $count =count($unique);
                  $fail =TRUE;
                  for($n =0; ($n < $count && $fail); $n++){
                        $x =$unique[$n];
                        for($j =0; ($j < $count && $fail); $j++){
                              if($x ==$unique[$j] & $j != $n){
                                    $fail =FALSE;
                              }
                        }
                  }
                  if($fail ==TRUE){
                        $filter[$index] =$unique;
                        $index++;
                  }
            }
            $perm =$filter;
      }

/*-------------------------------------------------------------------------*/
      function debug()
      {
            global $perm;
            $take =$perm;
            $x =count($take);

            for($i =0; $i < $x; $i++){
                  $cell =count($take[$i]);
                  for($n =0; $n < $cell; $n++){
                        echo $take[$i][$n];
                  }
                  echo "<BR>\n";
            }
      }
/*-------------------------------------------------------------------------*/
      function permToDB()
      {
            global $perm, $length, $num;
            global $table_perm;

            $array =$perm;
            $size =count($array);


            for($i =0; $i < $size; $i++){
                  $set ="perm, take,";
                  $insert ="\"$num\",\"$length\",";
                  $cell =count($array[$i]);

                  for($n =0; $n < $cell; $n++){
                        $set    .="a".($n + 1);
                        $insert .="\"".$array[$i][$n]."\"";

                        if (($n + 1) != $cell){
                              $set         .=",";
                              $insert .=",";
                        }
                  }
                  $query ="INSERT INTO $table_perm ($set) VALUES ($insert)";
                  mysql_query($query) or die("<BR><BR>".mysql_error(). " - ". $query);
            }
      }

/*-------------------------------------------------------------------------*/
      function main()
      {
            global $length, $num, $get;

            for($length =3; $length <= 7; $length++){
                  for($num =$length; $num < 10; $num++){
                        echo "length: $length....finding up to $num numbers<BR>";
                        $get =0;
                        permutate($length);
                        filter();
                        //permToDB();
                        debug();
                        //echo "<BR><BR>";
                  }
            }
      }

?>



 

by: shmertPosted on 2003-10-08 at 15:52:56ID: 9517113

Argh, buggy, yes.  But inq, I think it's closer to the solution than yours, which simply iterates through sequentially.  Here's a new (hopefully bug-free) version adapted from a perl script I found:

<?php
// borrowed from the Perl Cookbook
// http://iis1.cps.unizar.es/Oreilly/perl/cookbook/ch04_20.htm#ch04-38739
function getPermutations($OPTIONS, $sublength, $startIndex=0) {
        $length = count($OPTIONS);
        $out = array();
        $max = factorial($length);
        echo "options = $sublength / $length, factorial = $max <br />\n";
        $pattern = $OPTIONS;
        for ($x=$startIndex; $x<$max; $x++) {
                $N = $x;
                for ($i=1; $i<= $length;) {
                        //array_unshift($pattern, $N % $i);
                        $pattern[($length-$i)] = $N % $i;
                        $N = $N/$i;
                        $i++;
                }
                //echo join('-', $pattern) . ': ';
                $perm = '';
                $options = $OPTIONS;
                foreach($pattern AS $offset) {
                        list($char) = array_splice($options, $offset, 1);
                        $perm .= $char;
                }
                //echo $perm . "<br />\n";
                $out[] = substr($perm, 0, $sublength);
        }
        return array_unique($out);
}

function factorial($s){
        if($s) $r = $s * factorial($s - 1);
        else $r = 1;
        return $r;
}

$OPTIONS = array(1,2,3,4,5);
$array = getPermutations($OPTIONS, 3);
$count = count($array);
echo "there are $count unique permutations <br />\n";
foreach($array AS $item) echo $item . "<br />\n";

?>

 

by: shmertPosted on 2003-10-08 at 15:55:52ID: 9517127

Note: there's an optional argument to specify a startIndex in the function.  That is because if you try to do all 20 at once, the machine will choke.  Factorials get large very very quickly.  I think 50! is greater than the number of atoms in the universe.  You will need a more robust CPU for that one ;)

I think if you take the first 7 characters from all permutations of 20 characters, you will end up with 20!/13! options, or 390,700,800.  That's rather a lot.  If you do multiple passes with the startIndex set differently each time, this may end up working for you.

I must admit I'm rather curious what you intend to do with this very large array of permutations.  It would be pretty simple to convert the function I posted above to get the Nth permutation, instead of returning the entire list.  Would that be useful?

 

by: inq123Posted on 2003-10-08 at 15:56:04ID: 9517131

Yuengling, please see this post of mine above:

================
BTW, I forgot to point out to you shmert that the original question was that take a length of 20 digits, permutate them and take only the first 7 digits.  That is different than permutate only 7 digits.  The function you provided is permutation in true sense (if bugs in your function are fixed), so was the original poster's solution.  But with the original question, really the first 7 digits of 20 numbers would be permutated in the sense that each digit will change from 0-9 (10^7 permutation, not 7!), and while your function and OP's solution both can do that too, they would do that (namely, permutate the first 7 digits from 0-9) millions of times of slower than my solution if length increases to 20.

But of course if OP modifies the question posed, the analysis would be different.
================

So as you see this is why my version have the duplicate numbers you mentioned.  In fact, in your version where you permutate 20 numbers concatenated together, you'll have duplicate numbers in the first 7 digits that you want if you wait long enough (print out more than 10! numbers and you'll find those).  True permutation with 10-based integers and printed out the way your script did would only work on length of maximum of 10 digits.  That's why I made my version, and that's why mine could be thousands times faster if we imitate true permutation of 20 numbers but only take the first 7 digits.  That was your original question.

 

by: inq123Posted on 2003-10-08 at 16:16:15ID: 9517210

> But inq, I think it's closer to the solution than yours, which simply iterates through sequentially.

shmert, you seems to be always on the run and hardly had time to read and understand others' posts.  Please see here (old post plus a little expansion):

++++++++++++++++++++++++++++++++++++++

================
BTW, I forgot to point out to you shmert that the original question was that take a length of 20 digits, permutate them and take only the first 7 digits.  That is different than permutate only 7 digits.  The function you provided is permutation in true sense (if bugs in your function are fixed), so was the original poster's solution.  But with the original question, really the first 7 digits of 20 numbers would be permutated in the sense that each digit will change from 0-9 (10^7 permutation, not 7!), and while your function and OP's solution both can do that too, they would do that (namely, permutate the first 7 digits from 0-9) millions of times of slower than my solution if length increases to 20.

But of course if OP modifies the question posed, the analysis would be different.
================

So as you see this is why my version have the duplicate numbers you mentioned.  In fact, in your version where you permutate 20 numbers concatenated together, you'll have duplicate numbers in the first 7 digits that you want if you wait long enough (print out more than 10! numbers and you'll find those).  True permutation with 10-based integers and printed out the way your script did would only work on length of maximum of 10 digits.  That's why I made my version, and that's why mine could be thousands times faster if we imitate true permutation of 20 numbers but only take the first 7 digits.  That was your original question.

+++++++++++++++++++++++++++++++++++++++++++++++

The OP actually modified the behavior expected of the program (namely OP originally said 20 numbers, permutate, take first 7 digits, now OP meant true permutation of only 7 digits, those are two very different things, neither OP or you seemed to have realized that).  But I do agree, and anticipated, that if OP modifies the question, then it would be different, and I said long time ago your version, if fixed, is true permutation.

 

by: inq123Posted on 2003-10-08 at 16:25:24ID: 9517238

> I think if you take the first 7 characters from all permutations of 20 characters, you will end up with 20!/13! options, or 390,700,800.  That's rather a lot.  If you do multiple passes with the startIndex set differently each time, this may end up working for you.

That's right.  I just want to add that in OP's original version those 20 characters have only 10 variations, thus the old version ended up with 10^7, less than you would expect.

Besides, I don't see why the server would choke because of that at all.  Notice the OP's old version did not store anything in memory and thus however many numbers would not have mattered.  The stack initiation and destroy would allow them reused.  I see no problem there.  There must be some other problem.

 

by: inq123Posted on 2003-10-08 at 21:15:45ID: 9518245

Yuengling,

I just had some time and thought about it -- if what you need is true permutation, then your version of recursive is the way to go.  I tried to produce a different one and ended up with almost exactly the same version as yours!  For faster version of true permutation, you probably have to use shmert's provided non-recursive versions, if the 2nd version fixed bug.

As to your server's problem, for both my version and your initial version, there was no storage of anything and should not have used up memory.  Did you use top to monitor memory usage?  That should help diagnosis.

Good luck!

 

by: shmertPosted on 2003-10-09 at 07:43:12ID: 9520993

inq, I actually did read your post, and it didn't seem like your iterative algorithm addressed the initial question, which explicitly stated he was looking for "permutations"...  That said, it's confusing how things will behave once you get past 9, into double-digits.

My code is not the most efficient way to go if you are only getting the first unique 7 characters from a 20-character permutation.  It relies on array_unique() for that, which is going to bomb, since as inq pointed out you want this to run without taking up memory.

The correct way to do this would be to find all combinations for 7 digits out of 20 (resulting in 77,520 combinations, I think), then run my algorithm on each of those possible combinations (7! each), which will give you 390,700,800 final unique combinations.

 

by: YuenglingPosted on 2003-10-10 at 12:18:28ID: 9529821

I'm creating a program for a local college, I've gathered all possible courses offered by that college and stored it into MySQL database.

What I was trying to do, is to create a web application that would allow a student to choose several courses they may wishes to take say they may be interested in 8 classes, but want to take only 5 courses, and all of them have to be after 12(noon) only.

What I had done was to get all courses that the student had wanted to take and stored it in an array.

This is where permutaion comes in, to get the permutation of indexs in an array  

for example,

courses [1] ="Math 8am - 9am"
courses [2] ="Math 1pm - 3pm"
courses [3] ="Chemistry 3pm - 4pm"
courses [4] ="Chemistry 11am - 1pm"
courses [5] ="Database 5pm - 6pm"
courses [6] ="Gym 6pm - 7pm"
courses [7] ="Science 2pm - 3pm"
courses [8] ="Science 4pm - 5pm"


Now, the possible courses may be

courses[2], courses[3], courses[5], courses[8],
and so forth without any courses having a conflict in time.

Now, a permutation of 20 would be ridiculous and i doubt a student would pick that many so i would not even go that far. However I will go up to permutation of 10 numbers, of which a student may select 3 to 7 courses.
That would be ( [3 to10]! / (10 - [3 to 7] )!

But trying to get the permutation working and store all possibility into the database has been an hassle, apache freezing up on me, trying to install each permutation individually so that it would not overwhelm apache server, but to no avail. Apache just decide to shut down and become a cry baby.

If you have a much better idea then it would be greatly appreciated.





 

by: YuenglingPosted on 2003-10-10 at 12:50:36ID: 9529992

the permutation will be use to find indexes in an array.

 

by: YuenglingPosted on 2003-10-15 at 12:47:49ID: 9557396

AH, worked all week on making the permutation work,  I can see that it will be futile.  I only have a 30 second window on my web hosting space to run the script and permutation will just eat up all of it.

I've decided to go with combination algorithm, achieving only just the unqiue number where order does not matter.

I will award points by the end of the week if anybody is willing to come up with a combination code, otherwise I'll just split the points between schmert and inq.  I thank you for your time and effort.

 

by: shmertPosted on 2003-10-15 at 12:57:35ID: 9557447

all right.  I don't have any new ideas for this :-/  good luck!

 

by: YuenglingPosted on 2003-10-16 at 02:33:12ID: 9560548

Fantastic work you guys, I thank you shmert and inq123 for your time and effort

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...