隨機序列生成算法---生成前N個整數的一組隨機序列


問題描述:

給定輸入N,生成從1開始的:1,2,3,4,......N 一組隨機序列,序列中的數不能重復出現。

比如:N=5,合法的隨機序列為{4,3,1,5,2} 、{3,1,4,2,5}……非法的序列有{5,4,1,2,1}

來源:《數據結構與算法分析-MAW著  第二章習題2.8》

 

思路1:

對於數據a[N]而言,當隨機生成第i個數a[i]時,確保a[i]在 a[0]至a[i-1]中沒有出現過,就把該數放入a[i],繼續生成下一個數a[i+1]

算法復雜度為O(N^2logN)---每生成一個a[i],需要掃描a[0]...a[i-1]。

public static int[] algorithm1(int N) {  
            int []a = new int[N];  
            for (int i = 0; i < a.length; ++i) {    
                while (true) {  
                    a[i] = randInt(1, N); //生成[1,N]之間的一個隨機數         
            int j = 0;
for (; j < i; ++j) { if (a[i] == a[j]) { break;//如果這個隨機數已經在前面出現過了,break,下一輪繼續生成另一個隨機數,直至a[i]與前面所有的數不同 } } //end for if(j == i)   break;//本次生成的a[i]在前面沒有出現過, break while, i++,下一輪生成a[i+1] }//end while } return a; }

 

思路2:

先以1,2,3,.....N 初始化數組a[N],然后隨機選擇一個數組下標,交換這兩個下標處的值。

算法復雜度為O(N)

public static int[] algorithm3(int N){
          int[] a = new int[N];
          for(int i = 1; i <= N; i++)
              a[i-1] = i;
          for(int i = 1; i < N; i++)
              swapReference(a, i, randInt(0, i));
          return a;
      }
      
      private static void swapReference(int[] a, int i, int j){
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
      }

 

JAVA中采用java.util.Random類的nextInt(int n)方法可生成一個[0,n)的隨機數。---包括0不包括n

要生成范圍[i,j]內的一個隨機數,方法如下:

①nextInt(j-i+1)----生成[0, j-i+1)之間的隨機數

②nextInt(j-i+1)+i  生成 [i, j+1)之間的隨機數,即為[i,j]內的一個隨機數了。

 

性能比較:當N=1w時,algorithm1用時42ms,algorithm3用時2ms

當N=10w時,algorithm1用時2806ms,algorithm3用時12ms

整個程序代碼如下:

import java.util.Random;

public class C2_2_8 {
    
    private static Random rand = new Random(47);
    //生成一個[i,j]之間的隨機數
    public static int randInt(int i, int j){
        return rand.nextInt(j-i+1) + i;
    }
    
      public static int[] algorithm1(int N) {  
            int []a = new int[N];  
            for (int i = 0; i < a.length; ++i) {    
                while (true) {  
                    a[i] = randInt(1, N); //生成[1,N]之間的一個隨機數         
                    for (int j = 0; j < i; ++j) {    
                        if (a[i] == a[j]) {  
                            break;//如果這個隨機數已經在前面出現過了,break,下一輪繼續生成另一個隨機數,直至a[i]與前面所有的數不同  
                        }  
                    } //end for
                    
                    
                    break;//本次生成的a[i]在前面沒有出現過, break while, i++,下一輪生成a[i+1]
                }//end while 
            }
            return a;  
        }  
    
      
      public static int[] algorithm3(int N){
          int[] a = new int[N];
          for(int i = 1; i <= N; i++)
              a[i-1] = i;
          for(int i = 1; i < N; i++)
              swapReference(a, i, randInt(0, i));
          return a;
      }

      //生成一個即有正數又有負數的隨機數組
      public static int[] randomArr(int N){
          int [] a = new int[N];
          for(int i = 1; i <= N/2; i++)
              a[i-1] = i;
          for(int j = N; j > N/2; j--)
              a[j-1] = -j;
          for(int i = 1; i < N; i++)
              swapReference(a, i, randInt(0, i));
          return a;
      }
private static void swapReference(int[] a, int i, int j){ int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } public static void main(String[] args) { long start3 = System.currentTimeMillis(); algorithm3(100000); System.out.println(System.currentTimeMillis() - start3); long start = System.currentTimeMillis(); algorithm1(100000); long time = System.currentTimeMillis() - start; System.out.println(time); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM