함께 연결된 두 범위 사이의 난수 출력

함께 연결된 두 범위 사이의 난수 출력

이 문제범위 사이에서 난수를 생성하는 것에 관한 것입니다. 이는 괜찮지만 제 경우에는 적합하지 않습니다.

제 생각에는 SQL 용어로 설명하겠습니다. 왜냐하면 제 생각에는 코드 결과로 SQL 스크립트를 작성하는 것 bash입니다 .bash

두 개의 MySQL 테이블이 있습니다. 하나는 사람이고 다른 하나는 장소입니다. 각 레코드에는 1~139(장소) 및 1~1519(사람) 범위의 고유한 정수 ID가 있습니다. 이는 외래 키를 통해 서로 관련되어 있습니다. 즉, 한 곳에는 많은 사람이 있을 수 있지만 한 사람에게는 한 곳만 있을 수 있습니다.

# 1-139  # 1-1519
place1 → person1
       → person2
       → person3
       ... and so on

지금 내가 가지고 있는 데이터는 한곳에 있어요모두사람들은 다른 장소와는 다른 방식으로 연결되어 있습니다.

장소가 139개이고 사람이 1519명이니까 1개 장소가 있고 사람이 1519명이에요.

내 목표는 무작위로 사람들을 장소에 배정하고 각 장소에 최소한 한 명씩 배치하는 것입니다.

지금까지 내 코드는 다음과 같습니다.

$ c=1519
$ while [[ $c -ne 0 ]]; do 
    x=$((shuf -i 1-139 -n 1))
    [[ $x -gt 139 ]] && continue
    echo $x
    (( c-- ))
  done

이 코드는 1~139 사이의 1519개의 난수를 생성하므로 이제 각 사람을 임의의 위치에 연결할 수 있습니다.

내 질문은 다음과 같습니다

  • 이를 달성하는 더 효율적인 방법이 있습니까?
  • 모든 장소에 최소한 한 사람이 있는지 어떻게 제어할 수 있나요?

나는 에서 이 작업을 수행하는 것을 선호 bash하지만 이를 포함하지 않는 다른 솔루션에도 열려 있습니다.

답변1

일반적인 도구(적어도 Linux 배포판에서는)를 사용하여 이 작업을 수행하려는 경우 가장 효율적인 방법은 아마도 다음과 같이 질문하는 것입니다 shuf.

shuf -i 1-139 -n 1519 -r

그러면 1에서 139 사이에서 무작위로 선택된 1519개의 숫자가 생성됩니다.

모든 장소에 사람이 있는지 확인하려면 먼저 139개의 숫자를 반복하지 않고 섞으세요.

shuf -i 1-139
shuf -i 1-139 -n 1380 -r

"첫 번째 139" 효과를 줄이려면(처음 139명이 모두 다른 위치에 있게 됨) 덱을 다시 섞습니다.

(shuf -i 1-139; shuf -i 1-139 -n 1380 -r) | shuf

답변2

테이블에 people 이 저장되어 person있고 각 사람이 place_id1에서 139 사이의 정수를 가지고 있다고 가정합니다. SQL을 사용하여 person테이블을 직접 업데이트합니다.

UPDATE person SET place_id = FLOOR(RAND()*139 + 1);

이렇게 하면 테이블의 모든 항목이 업데이트되어 place_id키가 무작위로 지정됩니다. 하지만 완전히 테스트되지 않았습니다.

업데이트 후 다음을 사용하여 각 위치가 표시되는지 테스트할 수 있습니다.

SELECT COUNT(DISTINCT place_id) = 139 FROM person;

1모든 위치가 표시되면 이 값이 반환되고, 그렇지 않으면 반환되어야 합니다 0.

답변3

우리가 이 값을 원하면최대한 고르게 펴서(1519가 139의 10배의 덜 정확한 배수라는 점을 고려하면) 단지 공백을 피하는 대신 충분히 큰 반복 시퀀스 1, ..., 139, 1, ..., 139, 1, ... 및 그런 다음 처음 1519개 멤버를 섞습니다.

while seq 139; do :; done | head -n 1519 | shuf

사람을 위치에 매핑해야 하는 경우 간단히 출력 행에 번호를 매길 수 있습니다.

while seq 139; do :; done | head -n 1519 | shuf | nl

이는 모두 표준 쉘이므로 Bash 확장이 필요하지 않습니다.

관련 정보