使用Arraylist产生不重复的随机数
在Java中主要有两种方法来获取随机数,分别是通过Math.random方法和Random类获得随机数,不过Math.random方法其实也是通过生成一个Random类实例,然后再生成随机数的,也就是说,实际上两种方法都是使用Random类来生成随机数的。随机数的生成的与产生随机数的种子有关:
1)种子不同,就会产生不同的随机数
2)种子相同,即使是使用不同的Random实例,产生的随机数均是相同的
3)举例说明:
Random rand1=new Random();//使用默认的种子,也就是System.nanoTime()的返回值,这个值是距离某个时间点的纳秒值,可以保证产生不同的随机数,一般都是用这个 Random rand2=new Random(100); Random rand3=new Random(100); rand1.nextInt(); rand1.nextInt();//与上个值不同 rand2.rand1.nextInt(); rand23rand1.nextInt();//与rand2的值是相同的
4)但是,当使用以下形式式却可能会产生相同的随机数:
1 Random ww=new Random(); 2 for (int i = 0; i <100 ; i++) { 3 System.out.println(ww.nextInt(100)); 4 }
使用以下形式也可能会产生相同的随机数:
for (int i = 0; i <100 ; i++) { Random ww=new Random(); System.out.println(ww.nextInt(100)); }
随机就利用Arraylist产生不重复的随机数,代码如下:
1 import java.util.*; 2 3 /** 4 * Created by hfz on 2016/3/16. 5 */ 6 public class Chromosome implements Cloneable { 7 private double chromosomeFitness=0; 8 private double selectProbability=0; 9 private double cumulateProbability=0; 10 private short[] pathUsedRouterId; 11 private byte[][] weight; 12 private short totalRouterAmount;//通过读文件,得到的路由节点的总个数,这个是除了要求的源节点A、目的节点B以及必须经过的节点之外的所有节点 13 private short pathUsedRouterAmount;//最优路径中,除了要求的源节点A、目的节点B以及必须经过的节点之外 14 // 我们估算路径中要经过多少节点(从A到B不一定要经过所有的节点),是totalRouterAmount的一个子集 15 public Chromosome(short totalRouterAmount,short pathUsedRouterAmount,byte[][]weight){ 16 this.totalRouterAmount=totalRouterAmount; 17 this.pathUsedRouterAmount=pathUsedRouterAmount; 18 this.weight=weight; 19 pathUsedRouterId=new short[pathUsedRouterAmount]; 20 } 21 public void generateInitChromosome(ArrayList<Short> demandedRouter){ 22 ArrayList<Short> allRouterId=new ArrayList<>(totalRouterAmount);//通过读文件,得到的路由节点的总个数; 23 ArrayList<Short> arrayListPathRouter=new ArrayList<>(); 24 for (short i=0;i< totalRouterAmount;++i){ 25 if (!(demandedRouter.contains(i))) { 26 allRouterId.add(Short.valueOf(i)); 27 } 28 } 29 /* 30 //删除节点A、B。 31 allRouterId.remove((Object)demandedRouter[0]);//删除A,强制转换为Object的话,才会删除对应的值,否则是索引下的值 32 allRouterId.remove((Object)demandedRouter[1]);//删除B 33 for (short i=2;i<demandedRouter.length;++i) { 34 allRouterId.remove((Object)demandedRouter[i]); 35 } 36 */ 37 //Random random=new Random(1000);//固定种子的话,多次运行程序demandedRouter和pathUsedRouterId结果相同的 38 //java中随机数的产生取决于种子,种子不同,产生的随机数也不同,但是如果种子相同,即使实例不同也产生相同的随机数。 39 Random random=new Random(); 40 int index; 41 //生成不重复的随机数 42 for (short i=0;i<pathUsedRouterAmount;++i){ 43 index=random.nextInt(allRouterId.size());//[0,allRouterId.size()) 44 pathUsedRouterId[i]=(Short.valueOf(allRouterId.get(index))); 45 arrayListPathRouter.add(i);//将路径中的节点索引 46 // 存到列表中,留待使用必须经过的点随机替换pathUsedRouterId中的点 47 allRouterId.set(index,allRouterId.get(allRouterId.size()-1)); 48 allRouterId.remove(allRouterId.size()-1);//最后一个索引的值 49 } 50 //用必须要经过的点随机替换pathUsedRouterId中的点,要生成不重复的随机数 51 //arrayListPathRouter=Arrays.asList(pathUsedRouterId); 52 for (short i=2;i<demandedRouter.size();++i) { 53 index = random.nextInt(arrayListPathRouter.size()); 54 pathUsedRouterId[arrayListPathRouter.get(index)] = (Short.valueOf(demandedRouter.get(i))); 55 //不是pathUsedRouterId[index] = (Short.valueOf(demandedRouter.get(i))); 56 //两次的index可能相同,但是即使相同,其实在arrayListPathRouter.get(index)中对应的索引值其实是不同的 57 arrayListPathRouter.set(index, arrayListPathRouter.get(arrayListPathRouter.size() - 1)); 58 arrayListPathRouter.remove(arrayListPathRouter.size() - 1); 59 } 60 61 System.out.println(demandedRouter); 62 System.out.println(Arrays.toString(pathUsedRouterId)); 63 } 64 public static void main(String[] args){ 65 66 byte[][] test={{1,2},{3,4}}; 67 Short[] tt={0,1,2,3,4,8,9,12}; 68 //List tt1=Arrays.asList(tt); 69 Chromosome c1=new Chromosome((short)25,(short)17,test); 70 c1.generateInitChromosome(new ArrayList<Short>(Arrays.asList(tt))); 71 } 72 }
参考:
http://blog.csdn.net/p106786860/article/details/9465055
https://www.zhihu.com/question/30091884