ОК, я взял наживку ...
Если я правильно понимаю код (а если нет, то вы можете игнорировать весь этот ответ), он выбирает (в примере) случайные 5 элементов (без элементов дважды) из массива [1,2,3,4,5,6,7,8,9]
.
После небольшого расчесывания я назвал эту проблему одной из случайной перестановки массива и выбора первых 5 элементов. Вот небольшая функция, которую я написал, чтобы сделать случайную перестановку с использованием шаффла Кнута
FUNCTION random_perm(n) RESULT(perm)
! return a random permutation of the integers 1..n, uses Knuth's shuffle
INTEGER, INTENT(in) :: n
INTEGER, DIMENSION(n) :: perm
INTEGER, DIMENSION(n) :: randi
REAL, DIMENSION(n) :: randr
INTEGER :: tmp, ix, jx
CALL random_SEED()
CALL random_NUMBER(randr)
randi = 1+INT(n*randr)
perm = [(ix,ix=1,n)]
DO ix = 1, n-1
jx = randi(ix)
tmp = perm(ix)
perm(ix) = perm(jx)
perm(jx) = tmp
END DO
END FUNCTION random_perm
ОП может использовать такую функцию:
n129 = random_perm(9)
lotto5 = n129(1:5)
На данный момент lotto5
не отсортировано. Если это важно, один из способов «сортировки» результата будет состоять в том, чтобы заменить предыдущие две строки на
n129 = random_perm(9)
ix = 1
DO jx = 1, 9
IF (ANY(n129(1:5)==jx)) THEN
lotto5(ix) = jx
ix = ix+1
END IF
END DO
Из ограниченного количества испытаний:
- Я достаточно уверен, что это работает правильно.
- Это медленнее, чем код OP, примерно на 2-4%.
Если OP беспокоит только скорость, то OP может позаботиться о том, чтобы «включить» функцию вручную, чтобы увидеть, имеет ли она какое-то значение. Я этого не делал и не буду. Я думаю, что полезно иметь генератор случайных перестановок в отдельной функции. OP намекает на то, что эта функция (или, скорее, представление OP в опубликованном коде) является частью гораздо большего кода, поэтому полезна ли предоставленная мной функция в этом контексте, я не знаю.
Наконец, чтобы ответить на более широкий вопрос OP, что я написал лучше оригинала?
Нет, медленнее.
Возможно, да. Если целью OP является получение первых m
элементов случайной перестановки целых чисел 1,2,...,n
, то функция для возврата случайной перестановки является полезным компонентом для более крупных программ. Но OP может обоснованно утверждать, что его (?) Код является лучшей (потому что более быстрой) реализацией этой функции, но просто по-другому.
Что возвращает нас к началу, что означает лучше ?