Как контролировать% RANDOM%? - PullRequest
0 голосов
/ 08 мая 2018

(Потому что кто-то спросил, у меня Windows 10, если кому-то интересно.

Недавно я работал над настольным PAI (частичным искусственным интеллектом), который сможет выполнять некоторые базовые задачи для меня, пока я не за компьютером.

Однако я хочу, чтобы он выбрал и сказал 1 из 9 различных возможных сообщений. Например, у меня есть 9 разных способов сказать «Как я могу вам помочь?», И я хочу, чтобы он выбрал и повторил один из этих 9 способов.

Для этого я хочу использовать переменную% RANDOM%. Проблема в том, что% RANDOM% генерирует случайное число в диапазоне от 0 до 32767, и я хочу, чтобы оно генерировало случайное число в диапазоне от 1 до 9.

Я видел, как несколько человек в Интернете говорили, что используют кусок кода:

 SET /a rand=(%RANDOM%*9/32768)+1 

Однако это не работает. Или, может быть, это для некоторых людей, но, конечно, не для меня. Всякий раз, когда я внедряю это в пакетный файл, он либо просто закрывает окно, потому что не знает, как выполнить код, либо просто выбирает одно и то же число снова и снова, несмотря ни на что.

Я также уже пробовал его с отложенным расширением и без него, и если я пытаюсь запустить код в обычной командной строке (CMD.EXE), он просто говорит «Отсутствует оператор».

Мне трудно, потому что я не очень разбираюсь в арифметике в партии. Любая помощь по устранению этого с благодарностью!

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Когда вы утверждаете, что при запуске скрипта вы постоянно получаете одно и то же значение, я подозреваю, что вы запускаете скрипт, дважды щелкнув его в проводнике Windows или на рабочем столе.

Источникэта проблема - случайное начальное значение , которое каждый сеанс cmd.exe устанавливает при запуске .Начальное число изменяется на 3 или 4 только один раз в секунду (10 раз в 3 секунды).

Каждый раз, когда вы запускаете свой скрипт двойным щелчком, вы запускаете новый сеанс cmd.exe.Все сеансы, которые запускаются в течение одной секунды, получат одинаковое случайное начальное число и, следовательно, одну и ту же последовательность.

Ваша проблема осложняется формулой, которую вы используете для генерации «случайного» числа от 1 до 9:SET /a "rand=(%RANDOM%*9/32768)+1" С этой формулой начальный результат будет меняться только один раз каждые ~ 18 минут.

Более простая формула set /a "rand=%random% %% 9 + 1" будет изменять начальное значение раз в секунду.

Вот демонстрацияо том, что я имею в виду.

test.bat

@echo off
set "t=%time%
set /a r=%random%, n1=r*9/32768+1, n2=r%%9+1
echo t=%t%, r=%r%, n1=%n1%, n2=%n2%

Вот что происходит, когда я использую цикл для запуска сценария 25 раз в разных сеансах cmd.exe:

C:\test>for /l %n in (1 1 25) do @cmd /c test.bat
t=14:22:05.00, r=29206, n1=9, n2=2
t=14:22:05.13, r=29206, n1=9, n2=2
t=14:22:05.24, r=29206, n1=9, n2=2
t=14:22:05.35, r=29206, n1=9, n2=2
t=14:22:05.47, r=29206, n1=9, n2=2
t=14:22:05.58, r=29206, n1=9, n2=2
t=14:22:05.71, r=29206, n1=9, n2=2
t=14:22:05.83, r=29206, n1=9, n2=2
t=14:22:05.96, r=29206, n1=9, n2=2
t=14:22:06.08, r=29209, n1=9, n2=5
t=14:22:06.19, r=29209, n1=9, n2=5
t=14:22:06.32, r=29209, n1=9, n2=5
t=14:22:06.44, r=29209, n1=9, n2=5
t=14:22:06.55, r=29209, n1=9, n2=5
t=14:22:06.66, r=29209, n1=9, n2=5
t=14:22:06.79, r=29209, n1=9, n2=5
t=14:22:06.90, r=29209, n1=9, n2=5
t=14:22:07.02, r=29212, n1=9, n2=8
t=14:22:07.15, r=29212, n1=9, n2=8
t=14:22:07.27, r=29212, n1=9, n2=8
t=14:22:07.38, r=29212, n1=9, n2=8
t=14:22:07.50, r=29212, n1=9, n2=8
t=14:22:07.63, r=29212, n1=9, n2=8
t=14:22:07.74, r=29212, n1=9, n2=8
t=14:22:07.86, r=29212, n1=9, n2=8

t - время, r - необработанное значение случайного начального числа, n1 - значение, вычисленное по исходной формуле, а n2 - значение с более простой формулой.Вы можете видеть, что исходный результат формулы никогда не изменяется, даже если начальное значение изменилось 3 раза.

Если я повторю эксперимент, но на этот раз выполню каждую команду в одном сеансе cmd.exe, то вы увидите, чтопоследовательность случайных чисел разумна.

C:\test>for /l %n in (1 1 25) do @test.bat
t=14:26:12.83, r=24169, n1=7, n2=5
t=14:26:12.83, r=7515, n1=3, n2=1
t=14:26:12.84, r=8502, n1=3, n2=7
t=14:26:12.84, r=11715, n1=4, n2=7
t=14:26:12.86, r=28979, n1=8, n2=9
t=14:26:12.86, r=5966, n1=2, n2=9
t=14:26:12.86, r=4269, n1=2, n2=4
t=14:26:12.87, r=27310, n1=8, n2=5
t=14:26:12.87, r=11966, n1=4, n2=6
t=14:26:12.89, r=16129, n1=5, n2=2
t=14:26:12.89, r=16597, n1=5, n2=2
t=14:26:12.89, r=2994, n1=1, n2=7
t=14:26:12.90, r=16762, n1=5, n2=5
t=14:26:12.90, r=1718, n1=1, n2=9
t=14:26:12.92, r=17976, n1=5, n2=4
t=14:26:12.92, r=20805, n1=6, n2=7
t=14:26:12.94, r=11730, n1=4, n2=4
t=14:26:12.94, r=20414, n1=6, n2=3
t=14:26:12.94, r=28978, n1=8, n2=8
t=14:26:12.95, r=11615, n1=4, n2=6
t=14:26:12.95, r=13486, n1=4, n2=5
t=14:26:12.97, r=21228, n1=6, n2=7
t=14:26:12.97, r=25754, n1=8, n2=6
t=14:26:12.97, r=3979, n1=2, n2=2
t=14:26:12.98, r=16189, n1=5, n2=8

На самом деле не существует хорошего чистого пакетного решения для случайной генерации чисел в разных сеансах cmd.exe.Но вы можете использовать гибридный сценарий, чтобы получить достойное решение.Ниже приведено демонстрационное JScript / пакетное решение, которое хорошо работает.Однако это происходит медленно, потому что: функция random должна инициализировать новый сеанс CSCRIPT при каждом вызове.

test2.bat

@if (@X)==(@Y) @end /* harmless hybrid line that begins a JScrpt comment
:::::::::::: batch portion ::::::::::::::
@echo off
call :random 1 9 rand
echo %rand%
exit /b

:random  min  max  rtnVar
for /f %%A in (
  'cscript //E:JScript //nologo "%~f0" "Math.floor(Math.random()*(%2-%1+1))+%1"'
) do set "%3=%%A"
exit /b


:: The following JScript code evaluates a JScript expression
:: and writes the result to stdout
************ JScript portion *********************/
WScript.StdOut.WriteLine(eval(WScript.Arguments.Unnamed(0)));

Вот результаты быстроговыполнение вышеуказанного в 25 различных сеансах cmd.exe - именно тот результат, который вам нужен.

C:\test>for /l %n in (1 1 25) do @cmd /c test2.bat
9
8
7
5
9
8
5
1
5
6
5
8
7
8
7
1
2
6
6
5
6
4
8
4
9
0 голосов
/ 08 мая 2018

Что произойдет, если вы используете set /a rnd=(%RANDOM%%%9)+1 вместо?

Пример:

@Echo Off

Set "msg[1]=G'day!"
Set "msg[2]=Hello!"
Set "msg[3]=Hey!"
Set "msg[4]=Hi!"
Set "msg[5]=Hiya!"
Set "msg[6]=Howdy?"
Set "msg[7]=Sup?"
Set "msg[8]=Whazzup?"
Set "msg[9]=Yo!"

Set /A rnd=(%RANDOM% %% 9) + 1

Call Echo %%msg[%rnd%]%%

Pause
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...