- Информация о материале
- Автор: Arsen Gonian
- Категория: Uncategorised
- Просмотров: 42
Исследуем формулу Эйлера как генератор простых чисел.
Cn=n*n+n+41
Напишем код на Python и Forth для проверки количества простых чисел при n = от 0 до 100, 1000, 10000, 50000 и 65000.
Рассмотрим также C=27941 как замену 41, и сделаем вывод что многочлен с таким свободным членом генерирует больше простых чисел.
Код для подсчета количества простых чисел, генерируемое формулой Cn=n*n+n+41 (Cn=n*n+n+27941) на ЯП Forth.
S" lib\include\float2.f" INCLUDED
S" lib\include\facil.f" INCLUDED
: TIME TIME&DATE 2DROP 24 * + 60 * + 60 * + ;
: IS_PRIME ( N -> D )
DUP 4 < IF DROP 1 EXIT THEN
DUP 2 MOD 0= IF DROP 2 EXIT THEN
DUP 0 D>F FSQRT F>D DROP 2 + 3 DO
DUP I MOD 0= IF DROP I 0 LEAVE THEN
2 +LOOP IF 1 ELSE THEN
;
: TST 20 0 DO I DUP . IS_PRIME . CR LOOP ;
: EULER ( N K -> )
0 SWAP ROT 0 DO
DUP I DUP 1+ * +
IS_PRIME 1 = IF SWAP 1+ SWAP THEN
LOOP DROP
;
: MAIN
TIME
65000 41 EULER . \ код для проверки
TIME SWAP - CR ." ZANYALO " . ." sec" ;
MAIN
Первый параметр n, второй - C=41 или C=27941.
100 41 EULER .
86 Ok
100 27941 EULER .
77 Ok
1000 41 EULER .
581 Ok
1000 27941 EULER .
599 Ok
10000 41 EULER .
4149 Ok
10000 27941 EULER .
4466 Ok
45000 41 EULER .
15571 Ok
45000 27941 EULER .
17075 Ok
Код для работы с беззнаковыми числами на Forth.
S" lib\include\float2.f" INCLUDED
S" lib\include\facil.f" INCLUDED
: TIME TIME&DATE 2DROP 24 * + 60 * + 60 * + ;
: IS_PRIME ( N -> D )
DUP 4 U< IF DROP 1 EXIT THEN
DUP 2 UMOD 0= IF DROP 2 EXIT THEN
DUP 0 D>F FSQRT F>D DROP 2 + 3 DO
DUP I UMOD 0= IF DROP I 0 LEAVE THEN
2 +LOOP IF 1 ELSE THEN
;
: TST 20 0 DO I DUP . IS_PRIME . CR LOOP ;
: EULER ( N K -> )
0 SWAP ROT 0 DO
DUP I DUP 1+ * +
IS_PRIME 1 = IF SWAP 1+ SWAP THEN
LOOP DROP
;
: MAIN
TIME
50000 27941 EULER . \ код для проверки
TIME SWAP - CR ." ZANYALO " . ." sec" ;
MAIN
Без измерения времени выполнения:
50000 41 EULER .
17071 Ok
50000 27941 EULER .
18776 Ok
65000 41 EULER .
21631 Ok
65000 27941 EULER .
23793 Ok
С измерением времени выполнения:
MAIN \ 50000 27941 EULER
18776
ZANYALO 1 sec Ok
MAIN \ 50000 41 EULER
17071
ZANYALO 0 sec Ok
MAIN \ 65000 27941 EULER
23793
ZANYALO 2 sec Ok
MAIN \ 65000 41 EULER
21631
ZANYALO 2 sec Ok
Только при n=100, формула Эйлера с C=41 генерирует больше простых чисел, чем с C=27941. При n = 1000, 10000, 50000 и 65000 - C=27941 "побеждает", генерирует больше простых чисел.
Forth работает только с 32 битными числами (примерно +/- 2 миллиарда). Квадратный корень из 2**31 грубо 46000 плюс значения остальных членов суммы, то есть можем спокойно прогнать n до 45000. При работе с беззнаковыми числами - квадратный корень из 2**32=65536, а это значит, что можем увеличить диапазон до 65000.
Код на Python проще и понятнее (приведен ниже, сравните сами), но выполняется примерно в 15 раз дольше. Также минусом Forth является отсутствие библиотек для работы с длинными числами.
Код для подсчета количества простых чисел, генерируемое формулой Cn=n*n+n+41 (Cn=n*n+n+27941) на ЯП Python.
import time
def is_prime(n):
if n%2 == 0:
return 2
for i in range(3,int(n**0.5)+1,2):
if n%i == 0:
return i
return 1
def Euler(m,k):
start_time = time.time()
c=0
for i in range(m):
n=i*(i+1)+k
if is_prime(n)==1:
c+=1
end_time = time.time()
elapsed_time = end_time - start_time
print(f"Время выполнения: {elapsed_time:.2f} секунд")
return c
Euler(100,41)
Время выполнения: 0.00 секунд
86
Euler(100,27941)
Время выполнения: 0.00 секунд
77
Euler(1000,41)
Время выполнения: 0.01 секунд
581
Euler(1000,27941)
Время выполнения: 0.03 секунд
599
Euler(10000,41)
Время выполнения: 0.72 секунд
4149
Euler(10000,27941)
Время выполнения: 0.78 секунд
4466
Euler(45000, 41)
Время выполнения: 15.91 секунд
15571
Euler(45000, 27941)
Время выполнения: 16.98 секунд
17075
Euler(50000, 41)
Время выполнения: 19.69 секунд
17071
Euler(50000, 27941)
Время выполнения: 21.69 секунд
18776
Euler(65000, 41)
Время выполнения: 35.07 секунд
21631
Euler(65000, 27941)
Время выполнения: 38.62 секунд
23793
Euler(100000,41)
Время выполнения: 85.23 секунд
31985
Euler(100000,27941)
Время выполнения: 93.43 секунд
35150
Двенадцать новых чисел для формулы Эйлера:
Для 55661 процент простых чисел 19214 / 50000 * 100% = 38.428%
Для 72491 процент простых чисел 19120 / 50000 * 100% = 38.24%
115721 19860 / 50000 * 100 % = 39,72%
136517 19392 / 50000 * 100 % = 38,784%
247757 21203 / 50000 * 100 % = 42,406%
239621 19812 / 50000 * 100 % = 39,624%
206807 19248 / 50000 * 100 % = 38,496%
333491 19576 / 50000 * 100 % = 39,152%
361637 19596 / 50000 * 100 % = 39,192%
383681 19193 / 50000 * 100 % = 38,386%
487451 19035 / 50000 * 100 % = 38,07%
460631 18727 / 50000 * 100 % = 37,454%
Euler(10000, 55661)
Время выполнения: 0.80 секунд
4544
Euler(50000, 55661)
Время выполнения: 22.43 секунд
19214
Euler(10000, 72491)
Время выполнения: 0.80 секунд
4533
Euler(50000, 72491)
Время выполнения: 22.15 секунд
19120
По сравнению с 41 и 27941, которые дают результаты:
17071 / 50000 * 100% = 34,142%
18776 / 50000 * 100% = 37,552%
Euler(10000, 115721)
Время выполнения: 0.85 секунд
4690
Euler(50000, 115721)
Время выполнения: 23.50 секунд
19860
Euler(10000, 136517)
Время выполнения: 0.83 секунд
4609
Euler(50000, 136517)
Время выполнения: 23.15 секунд
19392
Euler(10000, 247757)
Время выполнения: 0.91 секунд
5027
Euler(50000, 247757)
Время выполнения: 25.15 секунд
21203
Euler(10000, 239621)
Время выполнения: 0.86 секунд
4724
Euler(50000, 239621)
Время выполнения: 23.55 секунд
19812
Euler(10000, 206807)
Время выполнения: 0.83 секунд
4601
Euler(50000, 206807)
Время выполнения: 22.77 секунд
19248
Euler(10000, 333491)
Время выполнения: 0.85 секунд
4668
Euler(50000, 333491)
Время выполнения: 23.26 секунд
19576
Euler(10000, 361637)
Время выполнения: 0.85 секунд
4634
Euler(50000, 361637)
Время выполнения: 23.33 секунд
19596
Euler(10000, 383681)
Время выполнения: 0.84 секунд
4612
Euler(50000, 383681)
Время выполнения: 22.72 секунд
19193
Euler(10000, 487451)
Время выполнения: 0.84 секунд
4537
Euler(50000, 487451)
Время выполнения: 22.47 секунд
19035
Euler(10000, 460631)
Время выполнения: 0.81 секунд
4439
Euler(50000, 460631)
Время выполнения: 22.30 секунд
18727
Плюс еще 26 свободных членов для формулы Эйлера для генерации простых чисел:
10000 595937 EULER .
4978 Ok
50000 595937 EULER .
21081 Ok
10000 579431 EULER .
4589 Ok
50000 579431 EULER .
19288 Ok
10000 601037 EULER .
4604 Ok
50000 601037 EULER .
19341 Ok
10000 701147 EULER .
4712 Ok
50000 701147 EULER .
20013 Ok
10000 771581 EULER .
4669 Ok
50000 771581 EULER .
19520 Ok
10000 765197 EULER .
4666 Ok
50000 765197 EULER .
19787 Ok
10000 722231 EULER .
4609 Ok
50000 722231 EULER .
19539 Ok
10000 878357 EULER .
4510 Ok
50000 878357 EULER .
19133 Ok
10000 1544987 EULER .
4809 Ok
50000 1544987 EULER .
20431 Ok
10000 1974881 EULER .
4643 Ok
50000 1974881 EULER .
19932 Ok
10000 1272851 EULER .
4570 Ok
50000 1272851 EULER .
19428 Ok
10000 1840997 EULER .
4563 Ok
50000 1840997 EULER .
19388 Ok
10000 1000817 EULER .
4556 Ok
50000 1000817 EULER .
19467 Ok
10000 1257911 EULER .
4519 Ok
50000 1257911 EULER .
19169 Ok
10000 1850747 EULER .
4511 Ok
50000 1850747 EULER .
19344 Ok
10000 1426697 EULER .
4495 Ok
50000 1426697 EULER .
19234 Ok
10000 1087211 EULER .
4462 Ok
50000 1087211 EULER .
18909 Ok
10000 2640161 EULER .
4798 Ok
50000 2640161 EULER .
20568 Ok
10000 2367767 EULER .
4767 Ok
50000 2367767 EULER .
20428 Ok
10000 2603297 EULER .
4595 Ok
50000 2603297 EULER .
19605 Ok
10000 2719391 EULER .
4580 Ok
50000 2719391 EULER .
19713 Ok
10000 2094341 EULER .
4564 Ok
50000 2094341 EULER .
19397 Ok
10000 2655671 EULER .
4488 Ok
50000 2655671 EULER .
19153 Ok
10000 2039747 EULER .
4440 Ok
50000 2039747 EULER .
19027 Ok
10000 2567177 EULER .
4435 Ok
50000 2567177 EULER .
19276 Ok
10000 2960381 EULER .
4387 Ok
50000 2960381 EULER .
18881 Ok
- Информация о материале
- Автор: Arsen Gonian
- Категория: Uncategorised
- Просмотров: 536
- Информация о материале
- Автор: Arsen Gonian
- Категория: Uncategorised
- Просмотров: 3278
Игры на JS
JavaScript (JS) — один из самых популярных языков программирования для создания веб-приложений, включая игры. Вот несколько примеров игр, которые можно создать на JavaScript:
Бросок Мяча под углом к горизонту
Бросок мяча под углом к горизонту — это классическая задача из области кинематики, которая описывает движение тела, брошенного с определенной скоростью под некоторым углом к горизонту. Рассмотрим основные моменты и формулы, связанные с этим движением.
Игра Камень, ножницы, бумага
Камень-ножницы-бумага: классическая детская игра, в которой участники одновременно выбирают один из трех символов - камень, ножницы или бумагу. Победитель определяется по правилам: камень побеждает ножницы, ножницы побеждают бумагу, бумага побеждает камень.
Игра Кено
Кено: лотерейная игра, в которой игрок выбирает набор чисел из общего диапазона. Затем производится случайное извлечение чисел, и игрок получают выигрыш в зависимости от совпадения чисел на своей карте с выигрышными номерами.
Игра Кости
Кости: игра, в которой бросается кубик (кубики) с числами. В зависимости от выпавшего значения, игроки могут делать ставки на различные исходы (результаты) бросков.
Игра Монетка (орел или решка)
Монетка - это игра, в которой бросают монету и делают ставки на то, какой стороной она упадет - орел или решка. Просто нажмите на картинку Орла или Решки, затем на кнопку "Выбрать".
Игра Слот-машина
Нажмите кнопку "Испытать судьбу", чтобы получить символы в случайном порядке. Игрок выигрывает, если выпадает три одинаковые фигуры
Игра Виселица
Знакомая всем с детства игра. Просто угадывайте буквы, чтобы разгадать слово. В данном исполнении игра стала похожа на "Поле чудес".
Игра Угадайка
Знакомая с детства игра. Просто введите число от 1 до 100. Решите математическую задачу: за какое максимальное количество ходов гарантированно можно угадать число.
Игра Питон
Игра "Питон" ("Змейка") - это цифровое воплощение простоты и увлекательности. В ней игрок управляет змеей, которая ползет по пиксельному миру в поисках яблок и других фруктов и овощей. С каждым съеденным фруктом змея удлиняется, а игра ускоряется. Это испытание ловкости, стратегии и терпения, где каждое движение может привести к новому рекорду или неожиданному концу. Змея скользит между препятствиями, создавая узоры на экране, напоминающие танец в бесконечном лабиринте. Эта игра - отражение эры ретро-игр, где простые концепции превращаются в часы захватывающего геймплея.
Библиотеки и движки для создания игр на JS:
- Phaser.js: Популярный игровой фреймворк для 2D-игр. Предлагает множество инструментов для создания игр, начиная от управления анимацией и физикой, заканчивая аудио поддержкой и управлением пользователем.
- Three.js: Используется для создания 3D-графики в браузере, включая сложные игры с трёхмерными мирами.
- Babylon.js: Еще один мощный фреймворк для разработки 3D-игр и приложений в браузере.
- p5.js: Библиотека, подходящая для создания интерактивных графических приложений, включая игры.
- Информация о материале
- Автор: Arsen Gonian
- Категория: Uncategorised
- Просмотров: 195
AI / ИИ на Форте.
Работа с элементарной ИИ на Форте не является сложной задачей. Продемонстрируем это.
Возьмем простой пример со следующими исходными данными (обучающая выборка):
x1=0 x2=0 y_true=0
x1=0 x2=1 y_true=0
x1=1 x2=0 y_true=0
x1=1 x2=1 y_true=1
Можете заметить, что вводам x1 и x2 сопоставляется их логическое "И".
Подключим библиотеку для работы с вещественными числами.
S" lib/include/float2.f" INCLUDED
Нам понадобятся переменные w1, w2 - веса; b - смещение (сразу инициализируем все три нулями); x1, x2 - входные значения; learning_rate - шаг обучения, для определенности взят за "0.1"; y_true - соответствующее истинное значение из тестовой выборки.
FVARIABLE w1
FVARIABLE w2
FVARIABLE b
0E w1 F!
0E w2 F!
0E b F!
FVARIABLE x1 FVARIABLE x2
FVARIABLE learning_rate
0.1E learning_rate F!
FVARIABLE y_true
Напишем слово моделирующее поведение персептрона (назовем его "P"), которое просто вычисляет выход по формуле:
y_pred = x1*w1+x2*w2+b
затем сравниваем это значение с нулем, если меньше оставляем 0, иначе 1.
Таким образом мы совместили функцию активации с расчетом линейной комбинации для персептрона с двумя входами.
\ x1 w1 x2 w2 b P - формат вызова слова
: P ( F: x1 w1 x2 w2 b -> F: y_pred ) FSWAP FROT F* F+ FSWAP FROT F* F+ F0< IF 0E ELSE 1E THEN ;
Проверим работу слова на случайных данных:
1E 2E 3E 5E 1000E P F.
1.0000000 Ok
1*2+3*5+1000 = 1017, что явно больше нуля, следовательно, результат работы 1. Персептрон работает корректно.
Самое важное слово производящее тренировку персептрона назван - "T" (от слова Train). Входом служат исходные параметры x1, x2 и соответствующее им истинное значение, а вместо выхода - изменение переменных w1, w2 и b, что обозначено в комментарии стековой нотации буквой "V:" (от слова "VARIABLE").
: T ( F: x1 x2 y_true -> V: w1 w2 b ) \ x1 x2 y_true T - формат вызова слова
y_true F! \ x1 x2 y_true -> x1 x2
FOVER x1 F! FDUP x2 F! \ x1 x2 -> x1 x2 x1=x1 x2=x2
w1 F@ FSWAP w2 F@ b F@ \ x1 x2 -> x1 w1 x2 w2 b
P \ x1 w1 x2 w2 b -> y_pred
y_true F@ FSWAP F- \ y_pred -> y_true-y_pred=error
learning_rate F@ F* \ error -> error*learning_rate
FDUP x1 F@ F* w1 F@ F+ w1 F! \ error*learning_rate -> error*learning_rate w1=error*learning_rate*x1+w1
FDUP x2 F@ F* w2 F@ F+ w2 F! \ error*learning_rate -> error*learning_rate w2=error*learning_rate*x2+w2
b F@ F+ b F! \ error*learning_rate -> b=error*learning_rate+b
." Обновленные веса: w1 = " w1 F@ F. ." w2 = " w2 F@ F. ." b = " b F@ F. CR
;
Первая строка - описание слова.
Вторая - сохранение значения "y_true" в одноименной переменной.
Третья, аналогично предыдущей, сохранение значений x1, x2.
Четвертая - получаем значения переменных w1, w2 и b, одновременно выстраиваем их в том порядке, которая соответствует стековой нотации слова "P".
Пятая вызываем "P" (работа которой описана выше).
В шестой считаем ошибку по формуле error = y_true-y_pred.
В седьмой умножаем на шаг обучения, чтобы в
в девятой, десятой и одиннадцатой корректируются значения переменных w1, w2 и b по формулам:
w1=error*learning_rate*x1
w2=error*learning_rate*x2
b=error*learning_rate
Двенадцатая - вывод значения обновленных весов (контрольная информация о работе слова).
Можно протестировать это слово на следующих данных:
0E 0E 0E T
0E 1E 0E T
1E 0E 0E T
1E 1E 1E T
Окончательно можем написать слово "epochs", которая проведет обучение на тестовой выборке.
: epochs ( N -> )
0 DO
." Эпоха " I . CR
0E 0E 0E T
0E 1E 0E T
1E 0E 0E T
1E 1E 1E T
CR
LOOP ;
Она просто прогоняет N раз (количество эпох) обучение на тестовых данных с выводом результатов о проделанной работе.
Запустим его с параметром 10.
10 epochs
Эпоха 0
Обновленные веса: w1 = 0.1000000 w2 = 0.1000000 b = -0.1000000
Обновленные веса: w1 = 0.1000000 w2 = 0.0000000 b = -0.2000000
Обновленные веса: w1 = 0.1000000 w2 = 0.0000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.1000000
Эпоха 1
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.1000000
Обновленные веса: w1 = 0.2000000 w2 = 0.0000000 b = -0.2000000
Обновленные веса: w1 = 0.1000000 w2 = 0.0000000 b = -0.3000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Эпоха 2
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Эпоха 3
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Эпоха 4
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Эпоха 5
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Эпоха 6
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Эпоха 7
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Эпоха 8
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Эпоха 9
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Обновленные веса: w1 = 0.2000000 w2 = 0.1000000 b = -0.2000000
Ok
Обратим внимание, что, начиная с Эпохи 2, веса w1 и w2, а также b не меняются (если предварительно не тестировать работу слова "T", то с Эпохи 3).
Проверим "натренированность" весов и смещения, для чего напишем последнее слово "PREDICT", которая будет предсказывать выход "y".
: PREDICT ( x1 x2 -> y. )
w1 F@ FSWAP w2 F@ b F@ P F.
;
Работа которого заключается в том, чтобы подготовить параметры для слова "P". Проверим качество тренировки:
0E 0E PREDICT
0.0000000 Ok
0E 1E PREDICT
0.0000000 Ok
1E 0E PREDICT
0.0000000 Ok
1E 1E PREDICT
1.0000000 Ok
Можно слегка изменить код, так чтобы вводить целые числа и получать целочисленный выход (чтобы облегчить ввод и сделать простым и наглядным вывод).
В слове "T" добавляем три строки преобразующие "x1 x2 y_true" из целочисленного в вещественный формат
: T ( x1 x2 y_true -> V: w1 w2 b ) \ x1 x2 y_true T - формат вызова слова
ROT S>D D>F
SWAP S>D D>F
S>D D>F
y_true F! \ x1 x2 y_true -> x1 x2
FOVER x1 F! FDUP x2 F! \ x1 x2 -> x1 x2 x1=x1 x2=x2
w1 F@ FSWAP w2 F@ b F@ \ x1 x2 -> x1 w1 x2 w2 b
P \ x1 w1 x2 w2 b -> y_pred
y_true F@ FSWAP F- \ y_pred -> y_true-y_pred=error
learning_rate F@ F* \ error -> error*learning_rate
FDUP x1 F@ F* w1 F@ F+ w1 F! \ error*learning_rate -> error*learning_rate w1=error*learning_rate*x1+w1
FDUP x2 F@ F* w2 F@ F+ w2 F! \ error*learning_rate -> error*learning_rate w2=error*learning_rate*x2+w2
b F@ F+ b F! \ error*learning_rate -> b=error*learning_rate+b
." Обновленные веса: w1 = " w1 F@ F. ." w2 = " w2 F@ F. ." b = " b F@ F. CR
;
Также изменится "epochs" которое вызывает уже исправленное "T".
: epochs ( N -> )
0 DO
." Эпоха " I . CR
0 0 0 T
0 1 0 T
1 0 0 T
1 1 1 T
CR
LOOP ;
И наконец, в "PREDICT" преобразуем вход "x1 x2" в вещественный, а результат "y." из вещественного (точка в конце обозначает тот факт, что он печатается на экран, а не остается на стеке).
: PREDICT ( x1 x2 -> y. )
SWAP S>D D>F
S>D D>F
w1 F@ FSWAP w2 F@ b F@ P F>D D>S .
;
результат тренировки будет выглядеть так:
0 0 PREDICT
0 Ok
0 1 PREDICT
0 Ok
1 0 PREDICT
0 Ok
1 1 PREDICT
1 Ok
Логическое "ИЛИ"
Возьмем другую серию данных. Теперь вводам сопоставим их логическое "ИЛИ".
x1=0 x2=0 y_true=0
x1=0 x2=1 y_true=1
x1=1 x2=0 y_true=1
x1=1 x2=1 y_true=1
в коде предыдущего примера изменится только слово:
: epochs ( N -> )
0 DO
." Эпоха " I . CR
0E 0E 0E T
0E 1E 1E T
1E 0E 1E T
1E 1E 1E T
CR
LOOP ;
После обучения, слово PREDICT выдаст следующие результаты:
0E 0E PREDICT
0.0000000 Ok
0E 1E PREDICT
1.0000000 Ok
1E 0E PREDICT
1.0000000 Ok
1E 1E PREDICT
1.0000000 Ok
Проверьте это самостоятельно. Заметим, что с Эпохи 2 коэффициенты перестают меняться.
Операция "Исключающее ИЛИ"
Теперь исходные данные будут выглядеть так:
x1=0 x2=0 y_true=0
x1=0 x2=1 y_true=1
x1=1 x2=0 y_true=1
x1=1 x2=1 y_true=0
Аналогично изменится только слово "epochs":
: epochs ( N -> )
0 DO
." Эпоха " I . CR
0E 0E 0E T
0E 1E 1E T
1E 0E 1E T
1E 1E 0E T
CR
LOOP ;
После обучения (тоже 10 эпох), получим:
0E 0E PREDICT
1.0000000 Ok
0E 1E PREDICT
1.0000000 Ok
1E 0E PREDICT
0.0000000 Ok
1E 1E PREDICT
0.0000000 Ok
Что не является правильным результатом. Даже после Эпохи 9 коэффициенты меняются. Можете по экспериментировать самостоятельно с гораздо большим количеством эпох. Результат аналогичный даже после 1000 эпох ("1000 epochs"). Задача "Исключающее ИЛИ" не разрешима на персептроне, необходимо более сложные модели для такой простой операции.
Чтобы получить корректные результаты для каждого примера вводите код заново в новое окно консоли, или инициализируйте переменные заново:
0E w1 F!
0E w2 F!
0E b F!
Пример 1 - логическое "И" (окончательный код, можно "копи пастить")
S" lib/include/float2.f" INCLUDED
FVARIABLE w1
FVARIABLE w2
FVARIABLE b
0E w1 F!
0E w2 F!
0E b F!
FVARIABLE x1 FVARIABLE x2
FVARIABLE learning_rate
0.1E learning_rate F!
FVARIABLE y_true
: P ( F: x1 w1 x2 w2 b -> F: y_pred ) FSWAP FROT F* F+ FSWAP FROT F* F+ F0< IF 0E ELSE 1E THEN ;
: T ( F: x1 x2 y_true -> V: w1 w2 b ) \ x1 x2 y_true T - формат вызова слова
y_true F! \ x1 x2 y_true -> x1 x2
FOVER x1 F! FDUP x2 F! \ x1 x2 -> x1 x2 x1=x1 x2=x2
w1 F@ FSWAP w2 F@ b F@ \ x1 x2 -> x1 w1 x2 w2 b
P \ x1 w1 x2 w2 b -> y_pred
y_true F@ FSWAP F- \ y_pred -> y_true-y_pred=error
learning_rate F@ F* \ error -> error*learning_rate
FDUP x1 F@ F* w1 F@ F+ w1 F! \ error*learning_rate -> error*learning_rate w1=error*learning_rate*x1+w1
FDUP x2 F@ F* w2 F@ F+ w2 F! \ error*learning_rate -> error*learning_rate w2=error*learning_rate*x2+w2
b F@ F+ b F! \ error*learning_rate -> b=error*learning_rate+b
." Обновленные веса: w1 = " w1 F@ F. ." w2 = " w2 F@ F. ." b = " b F@ F. CR
;
: epochs ( N -> )
0 DO
." Эпоха " I . CR
0E 0E 0E T
0E 1E 0E T
1E 0E 0E T
1E 1E 1E T
CR
LOOP ;
10 epochs
: PREDICT ( x1 x2 -> y. )
w1 F@ FSWAP w2 F@ b F@ P F.
;
0E 0E PREDICT
0E 1E PREDICT
1E 0E PREDICT
1E 1E PREDICT
Пример 2 - логическое "ИЛИ"
S" lib/include/float2.f" INCLUDED
FVARIABLE w1
FVARIABLE w2
FVARIABLE b
0E w1 F!
0E w2 F!
0E b F!
FVARIABLE x1 FVARIABLE x2
FVARIABLE learning_rate
0.1E learning_rate F!
FVARIABLE y_true
: P ( F: x1 w1 x2 w2 b -> F: y_pred ) FSWAP FROT F* F+ FSWAP FROT F* F+ F0< IF 0E ELSE 1E THEN ;
: T ( F: x1 x2 y_true -> V: w1 w2 b ) \ x1 x2 y_true T - формат вызова слова
y_true F! \ x1 x2 y_true -> x1 x2
FOVER x1 F! FDUP x2 F! \ x1 x2 -> x1 x2 x1=x1 x2=x2
w1 F@ FSWAP w2 F@ b F@ \ x1 x2 -> x1 w1 x2 w2 b
P \ x1 w1 x2 w2 b -> y_pred
y_true F@ FSWAP F- \ y_pred -> y_true-y_pred=error
learning_rate F@ F* \ error -> error*learning_rate
FDUP x1 F@ F* w1 F@ F+ w1 F! \ error*learning_rate -> error*learning_rate w1=error*learning_rate*x1+w1
FDUP x2 F@ F* w2 F@ F+ w2 F! \ error*learning_rate -> error*learning_rate w2=error*learning_rate*x2+w2
b F@ F+ b F! \ error*learning_rate -> b=error*learning_rate+b
." Обновленные веса: w1 = " w1 F@ F. ." w2 = " w2 F@ F. ." b = " b F@ F. CR
;
: epochs ( N -> )
0 DO
." Эпоха " I . CR
0E 0E 0E T
0E 1E 1E T
1E 0E 1E T
1E 1E 1E T
CR
LOOP ;
10 epochs
: PREDICT ( x1 x2 -> y. )
w1 F@ FSWAP w2 F@ b F@ P F.
;
0E 0E PREDICT
0E 1E PREDICT
1E 0E PREDICT
1E 1E PREDICT
Пример 3 - "Исключающее ИЛИ"
S" lib/include/float2.f" INCLUDED
FVARIABLE w1
FVARIABLE w2
FVARIABLE b
0E w1 F!
0E w2 F!
0E b F!
FVARIABLE x1 FVARIABLE x2
FVARIABLE learning_rate
0.1E learning_rate F!
FVARIABLE y_true
: P ( F: x1 w1 x2 w2 b -> F: y_pred ) FSWAP FROT F* F+ FSWAP FROT F* F+ F0< IF 0E ELSE 1E THEN ;
: T ( F: x1 x2 y_true -> V: w1 w2 b ) \ x1 x2 y_true T - формат вызова слова
y_true F! \ x1 x2 y_true -> x1 x2
FOVER x1 F! FDUP x2 F! \ x1 x2 -> x1 x2 x1=x1 x2=x2
w1 F@ FSWAP w2 F@ b F@ \ x1 x2 -> x1 w1 x2 w2 b
P \ x1 w1 x2 w2 b -> y_pred
y_true F@ FSWAP F- \ y_pred -> y_true-y_pred=error
learning_rate F@ F* \ error -> error*learning_rate
FDUP x1 F@ F* w1 F@ F+ w1 F! \ error*learning_rate -> error*learning_rate w1=error*learning_rate*x1+w1
FDUP x2 F@ F* w2 F@ F+ w2 F! \ error*learning_rate -> error*learning_rate w2=error*learning_rate*x2+w2
b F@ F+ b F! \ error*learning_rate -> b=error*learning_rate+b
." Обновленные веса: w1 = " w1 F@ F. ." w2 = " w2 F@ F. ." b = " b F@ F. CR
;
: epochs ( N -> )
0 DO
." Эпоха " I . CR
0E 0E 0E T
0E 1E 1E T
1E 0E 1E T
1E 1E 0E T
CR
LOOP ;
10 epochs
: PREDICT ( x1 x2 -> y. )
w1 F@ FSWAP w2 F@ b F@ P F.
;
0E 0E PREDICT
0E 1E PREDICT
1E 0E PREDICT
1E 1E PREDICT
Как и было сказано ранее отличие всех трех примеров только в коде слова "epochs".
- Информация о материале
- Автор: Arsen Gonian
- Категория: Uncategorised
- Просмотров: 1113
Шахматы
Шахматы — это настольная стратегическая игра, которая играется на квадратной доске размером 8x8 клеток. В игре участвуют два игрока, каждый из которых управляет армией из 16 фигур: 1 король, 1 ферзь, 2 ладьи, 2 слона, 2 коня и 8 пешек. Основная цель игры — поставить мат королю противника, то есть создать такую позицию, при которой король соперника не может избежать взятия.
Основные правила и фигуры:
-
Фигуры и их ходы:
- Король: Ходит на одну клетку в любом направлении.
- Ферзь: Ходит на любое количество клеток по горизонтали, вертикали или диагонали.
- Ладья: Ходит на любое количество клеток по горизонтали или вертикали.
- Слон: Ходит на любое количество клеток по диагонали.
- Конь: Ходит буквой "Г" — две клетки в одном направлении и одна в перпендикулярном. Конь — единственная фигура, которая может перепрыгивать через другие фигуры.
- Пешка: Ходит на одну клетку вперед, но бьет на одну клетку по диагонали. На первом ходе может сделать два шага вперед. Если пешка достигает последнего ряда (8-го или 1-го), она может быть превращена в любую другую фигуру (чаще всего в ферзя).
-
Цель игры:
- Шах: Это ситуация, когда король находится под угрозой взятия. Игрок должен устранить угрозу, иначе он проиграет.
- Шах и мат: Это ситуация, при которой король находится под шахом и не может избежать взятия в следующий ход. Это завершает игру, и игрок, поставивший мат, побеждает.
- Пат: Это ситуация, при которой игрок, чей ход, не может сделать ни одного допустимого хода, но при этом его король не находится под шахом. Пат приводит к ничьей.
-
Дополнительные правила:
- Рокировка: Специальный ход, при котором король и ладья перемещаются одновременно. Король перемещается на две клетки в сторону ладьи, а ладья ставится на клетку, через которую король перепрыгнул. Рокировка возможна только при выполнении определенных условий (например, король и ладья еще не ходили, между ними нет других фигур, король не находится под шахом и не проходит через клетки, находящиеся под угрозой).
- Взятие на проходе: Это специальный ход пешкой, который возможен, если пешка противника сделала два шага вперед с исходной позиции, а ваша пешка могла бы взять её, если бы она сделала один шаг. Взятие на проходе должно быть выполнено сразу же после такого хода.
Стратегия и тактика:
Шахматы требуют как стратегического планирования на протяжении всей игры, так и тактических расчетов для выигрыша отдельных фигур и позиций. Хорошие шахматисты должны уметь предсказывать ходы противника, рассчитывать возможные последствия своих действий на несколько шагов вперед и понимать общую позиционную игру.
История и культура:
Шахматы имеют долгую историю, восходящую к Индии VI века, где игра, известная как "чатуранга", была предшественником современных шахмат. Со временем шахматы распространились по всему миру, приобретая популярность в различных культурах.
Сегодня шахматы играют важную роль в культуре и спорте, с миллионами игроков по всему миру и множеством международных турниров, включая престижный матч за звание чемпиона мира. В последние годы интерес к шахматам возрос благодаря доступности онлайн-игр и популярным сериалам, таким как "Ход королевы" (The Queen's Gambit).
8 ферзей
Размещение 8 ферзей на шахматной доске размером 8 на 8 возможно 92 способами. Разумеется при условии, что ни одни из них не угрожает остальным.
Перейдя по ссылке вы увидите все эти варианты на отдельной странице.
Разместить 5 ферзей на шахматной доске размером 5 на 5 возможно 10 способами
Разместить 6 ферзей на шахматной доске размером 6 на 6 возможно 4 способами
Разместить 7 ферзей на шахматной доске размером 7 на 7 возможно 40 способами
Размещение 2, 3, 4 Ферзей на полях соответствующих размеров при аналогичном условии невозможно (тривиальный случай одного ферзя на поле 1 x 1 не рассматриваем).
Разместить 9 ферзей на шахматной доске размером 9 на 9 возможно 352 способами
Разместить 10 ферзей на шахматной доске размером 10 на 10 возможно 726 способами