Tuesday, December 28, 2010

Generating Distinct Random Numbers @ Runtime - OPTIMIZED Solution!

This is the optimized solution for generating distinct random numbers at runtime.
"getDistinctRandomNumbers" function has the complexity of O(n^2), and "checkForDuplicateNumber" function has complexity of 0(log n), which makes the overall complexity of the algorithm to be O(n^2 log n).

If you would observe the function "checkForDuplicateNumber", its clear that we have used the "Divide and Conquer" strategy to optimize the solution. By this we have reduced 1 while loop, and added recursive calls to the function, optimizing the number of calls at each step.

".sort( )" call in action script, implicitly uses the optimized way to sort the array.

This is obviously better than the previous solution, having complexity of O(n^3).


public function getDistinctRandomNumbers(range, numCount):Array
{
      // NumCount is the count of random numbers to be generated
      // Range is the upper limit of the generated random numbers,  starting from 0.
      var newArray = new Array();
      var randNum2:int;
      var randNum1 = Math.floor(Math.random() * range);

      newArray.push(randNum1);

      for(var k:int = 0; k < numCount - 1; k++)
      {
           randNum2 = Math.floor(Math.random() * range);
           var len = newArray.length;

           var sortArr = newArray.sort();
           var halfLen = Math.ceil(len / 2);
           var flag = checkForDuplicateNumber(0, halfLen, len, sortArr, randNum2);
           while(flag)
           {
                 randNum2 = Math.floor(Math.random() * range);
                 flag = checkForDuplicateNumber(0, halfLen, len, sortArr, randNum2);
           }

           newArray.push(randNum2);
       }

       return newArray;
}

public function checkForDuplicateNumber(minVal, halfLen, len, sortedArr, randNum2):Boolean
{
     if(halfLen == len == 1)
     {
         if(sortedArr[halfLen - 1] == randNum2)
         {
             return true;
         }
         return false;
     }

     if(sortedArr[halfLen - 1] == randNum2)
     {
       return true;
     }

     else if(randNum2 < sortedArr[halfLen - 1])
     {
          checkForDuplicateNumber(minVal, Math.ceil((halfLen + minVal) / 2), halfLen, sortedArr, randNum2);
          return false;
     }

     else if(randNum2 > sortedArr[halfLen - 1])
     {
          checkForDuplicateNumber(halfLen, Math.ceil((len + halfLen) / 2), len, sortedArr, randNum2);
          return false;
     }

     return false;
}

No comments:

Post a Comment