이 장에서는 먼저 Java 랜덤 숫자를 생성하는 몇 가지 방법을 설명하고 예를 통해 보여줍니다.
개요 :
여기서 랜덤 숫자를 생성하기가 어렵다고 말씀해 주시겠습니까? Java 캡슐화 된 무작위를 사용하는 것이 아닌가? 물론 일반적으로 괜찮습니다.이 기사에서 설명 할 알고리즘은이 랜덤 라이브러리 기능을 기반으로합니다.
이 기사는 주로 샘플링 동작에 중점을두고 샘플링 자체에는 중복 데이터가없는 암시 적 규칙이 있습니다. 좋아,이 지침으로. 먼저 자신의 아이디어 중 일부를 사용하여 반복적 인 생성없이 임의의 숫자를 생성 할 수 있습니다.
알고리즘 시도 :
일부 좋은 알고리즘이 나타나며 종종 일부는 좋지 않은 알고리즘이 동반됩니다. 그러나 그다지 효과적이지 않은 알고리즘의 경우 일반적으로 이해하고 구현하기 쉬운 하나의 공통 기능이 있습니다. 다음은 단계별 접근 방식을 통한 간단한 설명입니다.
첫 번째 시도 : 순진한 랜덤 알고리즘
이 알고리즘은 이해하기 쉽고 무작위입니다! 임의의 숫자가 생성되어 세트에 추가 될 때마다.
개인 void simplerandom (int start, int end, int count) {system.out.println ( "자연 랜덤 알고리즘 :"); StringBuffer buffer = new StringBuffer (); for (int i = 0; i <count; i ++) {int random = numberutils.randominteger (start, end); buffer.append (i == 0? ( "[" + random) : ( "," + random)); } buffer.append ( "]"); System.out.println (버퍼); } 두 번째 시도 : 실존 랜덤 알고리즘을 확인하십시오
우리는 위의 방법에 문제가 있다는 것을 알고 있습니다. 즉, 중복 데이터가있을 수 있습니다. 따라서 무작위 숫자를 생성 할 때 숫자가 이미 존재하는지 확인하고 존재하면 재생됩니다.
private void Checkrandom (int start, int end, int count) {system.out.println ( "실존 랜덤 알고리즘 확인 :"); StringBuffer buffer = new StringBuffer (); List <integer> save = new ArrayList <> (); for (int i = 0; i <count; i ++) {int random = numberutils.randominteger (start, end); if (종료 (저장, 랜덤)) {i-; 계속하다; } save.add (random); buffer.append (i == 0? ( "[" + random) : ( "," + random)); } buffer.append ( "]"); System.out.println (버퍼); } 세 번째 시도 : 요소 제거 랜덤 알고리즘
위의 알고리즘은 데이터 복제 문제를 해결했습니다. 그러나 매우 나쁜 문제 중 하나는 샘플 랜덤 숫자를 생성하는 데 오랜 시간이 걸릴 수 있다는 것입니다 (이것은 얼굴에 따라 다릅니다 ...).
그러나 여기에는 새로운 아이디어가 있습니다. 즉, 세트에서 숫자를 무작위로 사용하고 선택할 때 제거하는 것입니다. 그렇다면이 숫자가 무작위로 무작위로 도달하지 않겠습니까? 이것은 임의 숫자의 반복 문제를 매우 잘 해결합니다. 코드는 다음과 같습니다.
개인 void removerandom (int start, int end, int count) {System.out.println ( "요소 제거 랜덤 알고리즘 :"); StringBuffer buffer = new StringBuffer (); 목록 <integer> 숫자 = initList (시작, 끝); for (int i = 0; i <count; i ++) {int random = numberutils.randominteger (count -i); buffer.append (i == 0? 숫자. } buffer.append ( "]"); System.out.println (버퍼); } 네 번째 시도 : 상태 전송 랜덤 알고리즘
이전의 많은 블로그에서 일부는 알고리즘의 상태 전송 프로세스입니다. 상태 전송은 또한 내가 가장 좋아하는 알고리즘 중 하나입니다. 아래 그림 -1은 랜덤 숫자의 값 범위를 표시하고 순서의 주황색 숫자는 결과의 랜덤 시퀀스입니다. 하단 시퀀스에는 상태의 전이를 나타내는 일부 점선 화살표가 있습니다.
그림 1 상태 전환에 기반한 임의 번호 생성 알고리즘 샘플링
구현 코드 :
private void statusRandom (int start, int end, int count) {system.out.println ( "상태 전송 임의 알고리즘 :"); StringBuffer buffer = new StringBuffer (); int [] status = new int [end + 1]; for (int i = 0; i <count; i ++) {int random = numberutils.randominteger (start, end); System.err.println (랜덤); if (status [random] == 0) {buffer.append (i == 0? ( "[" + random)) : ( "," + random)); 상태 [random] = random == end? 시작 : (random + 1); // 시작하기 전에 숫자를 갖는 것은 불가능합니다.} else {// 상태 전송 index = random; do {index = status [index]; } while (status [index]! = 0); buffer.append (i == 0? ( "[" + index) : ( "," + index)); 상태 [index] = index == 종료? 시작 : (색인 + 1); // start}} buffer.append ( "]"); System.out.println (버퍼); } 다섯 번째 시도 : 재귀 플로이드 랜덤 알고리즘
Floyd 알고리즘은 궁극적으로 상태 이전 프로세스입니다. 알고리즘에는 결정된 임의 번호를 저장하려면 목록 또는 배열이 필요합니다. 이름에서 알 수 있듯이 여기에서 재귀 솔루션을 사용하겠습니다. 재귀 과정에서, 우리는 I-th 랜덤 숫자의 상태를 I-1 랜덤 숫자로 옮깁니다. 코드는 다음과 같습니다.
개인 목록 <Integer> SimpleFloyd (list <integer> list, int count, int start, int end) {if (count == 0) {return list; } list = simplefloyd (list, count -1, start, end -1); int random = numberutils.randominteger (시작, 끝); if (list.contains (random)) {list.add (end); } else {list.add (random); } 반환 목록; } 여섯 번째 시도 : 플로이드 랜덤 알고리즘을 반복합니다
이 아이디어는 위의 재귀 플로이드 랜덤 알고리즘과 유사하지만 여기서는 최적화 할 변수를 추가합니다. 더 이상 재발 할 필요가 없습니다. 코드는 다음과 같습니다.
개인 목록 <Integer> iterationfloyd (int start, int end, int count) {system.out.println ( "반복 플로이드 랜덤 알고리즘 :"); 목록 <integer> list = new ArrayList <> (); for (int i = end -count+1; i <end; i ++) {int random = numberutils.randominteger (start, i); if (list.contains (random)) {list.add (i); } else {list.add (random); }} 리턴 목록; } 테스트 결과 :
그림 2 무작위 번호 생성 알고리즘 테스트 결과
위의 테스트 결과에서 순진한 임의 알고리즘에는 중복 데이터가있을뿐만 아니라 가장 시간이 많이 걸린다는 것을 분명히 알 수 있습니다. 따라서 샘플링 된 랜덤 숫자를 생성 할 때이 알고리즘을 사용하지 마십시오. 후자의 알고리즘 중에서 상태 전송 임의 알고리즘이 최고이며 반복 플로이드 랜덤 알고리즘이 두 번째입니다. 이것은 개인적인 취향에 따라 만들 수 있습니다.