赞
踩
有时需要用到整数1-n的随机排列,如决定出场顺序等。这里用java做一个简单的小界面,显示整数1-n的随机排列。
这里界面用javafx工具实现。
整数1-n的排列,共n!种,所以我们的目的相当于是从n!个样本点构成的总体中,随机等概率地抽取一个样本点。
当然,我们的实现算法不采取上述的n!的方式,需要采用计算量合理的算法。
一个可能出现的误区是:不断地产生1~n之间的随机整数;如果遇到与已经产生的整数出现重复,则舍弃掉这个整数,并继续产生,一直到产生n个不同的整数(>=1, <=n)。这个方法简单也直观,但从概率的角度看,这样产生的结果与上述的随机等概率抽样并不等价。
这里采用一种比较简单的方法:让计算机产生n个0~1均匀分布的随机数(一般我们使用的n较小,那么计算机产生的这n个随机并不重复),得到一个随机数序列。按顺序记录着n个随机数,即为每一个随机数贴上“标签”,标签上记录的是它在这个序列中的序号。
然后对这n个随机数排序。排序之后,随机数的位置自然发生了变换,我们按现在的位置顺序把它们的“标签”取出来,就得到一个1-n整数的随机排列。
输入n后,建立一个数组和一个哈希表。n轮产生随机数,在第i轮中,将产生的这个随机数添加到数组,同时将其作为键添加到哈希表中,键对应的值为轮次,即整数i。
对数组排序。这里我用的是二路归并排序的方法。
按顺序取出排好序后的数组中的数,之后查找它在哈希表中对应的值。这样得到的值序列,就是我们想要的一个整数随机排列。
- package random;
-
- import java.util.*;
- import javafx.application.Application;
- import javafx.scene.Scene;
- import javafx.scene.control.Button;
- import javafx.scene.control.TextField;
- import javafx.scene.control.TextArea;
- import javafx.scene.layout.BorderPane;
- import javafx.scene.layout.HBox;
- import javafx.scene.text.Text;
- import javafx.stage.Stage;
-
- public class RandomPermutation extends Application {
- private Text text = new Text("Enter the maximun integer:");
- private TextField tfInput = new TextField();
- private TextArea ta = new TextArea();
- private Button btRun = new Button("Run");
- private Button btClear = new Button("Clear");
- private boolean allow = true;
-
- @Override
- public void start(Stage primaryStage) {
- // UI
- ta.setEditable(false);
- ta.setWrapText(true);
-
- BorderPane pane = new BorderPane();
-
- HBox hBox = new HBox();
- hBox.getChildren().addAll(text, tfInput, btRun, btClear);
- pane.setBottom(hBox);
- pane.setCenter(ta);
-
- Scene scene = new Scene(pane, 700, 400);
- primaryStage.setTitle("Random");
- primaryStage.setScene(scene);
- primaryStage.show();
-
- btRun.setOnAction(e -> runAction());
- btClear.setOnAction(e -> clearAction());
- }
-
- public static void main(String[] args) {
- Application.launch(args);
- }
-
- // Clear
- public void clearAction() {
- allow = true;
- ta.clear();
- tfInput.clear();
- }
-
- // Run
- public void runAction() {
- if(allow) {
- Integer n = Integer.parseInt(tfInput.getText());
- if(n instanceof Integer) {
- // Hash map to store key(random_number)-value(integer)
- Map<Double, Integer> hashMap = new HashMap<>();
- // Array to store random_number
- double[] randomNumbers = new double[n];
- for(int i = 1; i <= n; i++) {
- double r = Math.random();
- hashMap.put(r, i);
- randomNumbers[i - 1] = r;
- }
- // Sort the array
- mergeSort(randomNumbers);
-
- // Get the value(integer) sequence
- for(int i = 1; i <=n; i++) {
- double randomNumber = randomNumbers[i - 1];
- Integer integer = hashMap.get(randomNumber);
- ta.appendText(integer.toString() + " ");
- if( i % 15 == 0) {
- ta.appendText("\n");
- }
- }
- }
-
- allow = false;
- }
- }
-
- // Merge sort method
- public static void mergeSort(double[] list) {
- if(list.length > 1) {
- double[] firstHalf = new double[list.length / 2];
- System.arraycopy(list, 0, firstHalf, 0, list.length / 2);
- mergeSort(firstHalf);
-
- int secondHalfLength = list.length - list.length / 2;
- double[] secondHalf = new double[secondHalfLength];
- System.arraycopy(list, list.length / 2, secondHalf, 0,
- secondHalfLength);
- mergeSort(secondHalf);
-
- merge(firstHalf, secondHalf, list);
- }
- }
-
- public static void merge(double[] list1, double[] list2, double[] temp) {
- int current1 = 0;
- int current2 = 0;
- int current3 = 0;
-
- while(current1 < list1.length && current2 < list2.length) {
- if(list1[current1] < list2[current2])
- temp[current3++] = list1[current1++];
- else
- temp[current3++] = list2[current2++];
- }
-
- while(current1 < list1.length)
- temp[current3++] = list1[current1++];
-
- while(current2 < list2.length)
- temp[current3++] = list2[current2++];
- }
-
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。