Программа получения позиций ладей, не атакующих друг друга(в программе для ферзей нужно убрать условие атаки по диагонали)одновременно даёт нам и перестановки n элементов.Небольшое изменение этой программы позволяет получить размещения из n элементов по m без повторений.Алгоритмы генерации размещений, которые я нашёл в сети,сначала получают сочетания, а уже потом размещения.Здесь же происходит всё наоборот -сначала генерируются размещения. То есть 2-ю программу на этой странице нельзя считать оптимальной для получения сочетаний,она приведена только для примера.Специальная программа для генерации перестановок не приводится,т.к. их можно получить в данной программе при m=n.Компиляция программ(например в Qbasice 4.5),конечно позволит значительно ускорить их работу. Однако скорость счёта всё равно остаётся низкой.Если m задано, то на порядки быстрей работает программа с m вложенными циклами(см.ниже).
CLS DEFINT A-Z INPUT "Имя файла.Если не надо записывать в файл - n или N"; filename$ OPEN filename$ FOR OUTPUT AS #1 INPUT " n= "; n INPUT "m="; m l = m A# = n r = n 10 l = l - 1 IF l = 0 THEN 0 r = r - 1 A# = A #* r GOTO 10 0 PRINT "число размещений"; PRINT A# INPUT "показать 1-9,нет-0"; x IF x = 0 THEN END DIM y(n + 1) 1 k = k + 1 IF k = m + 1 THEN 2 8 y(k) = y(k) + 1 IF y(k) = n + 1 AND k = 1 THEN END IF y(k) = n + 1 THEN y(k) = 0: k = k - 1: GOTO 8 END IF FOR j = 1 TO k - 1 IF y(j) = y(k) THEN 8 NEXT GOTO 1 2 i# = i# + 1 PRINT i#; ":"; FOR j = 1 TO m PRINT y(j); NEXT PRINT " " IF filename$ = "N" OR filename$ = "n" THEN 8 PRINT #1, i#; ":"; FOR j = 1 TO m PRINT #1, y(j); NEXT PRINT #1, GOTO 8
Чтобы получить сочетания ,нужно однозначно упорядочить размещения,например по возрастанию или убыванию,как в следующей программе.
CLS DEFINT A-Z INPUT "Имя файла. Если не надо записывать в файл n или N"; filename$ OPEN filename$ FOR OUTPUT AS #1 CLS 0 INPUT " N="; n INPUT " M="; m C# = n: Z# = 1 FOR I = 1 TO m - 1 C# = C# * (n - I) Z# = Z# * (I + 1) NEXT SOCH# = C# / Z# PRINT "Число сочетаний "; SOCH# INPUT "показать 1..9,нет-0"; x IF x = 0 THEN END DIM y(n + 1) 1 k = k + 1 IF k = m + 1 THEN 2 8 y(k) = y(k) + 1 IF y(k) = n + 1 AND k = 1 THEN END IF y(k) = n + 1 THEN y(k) = 0: k = k - 1: GOTO 8 END IF FOR j = 1 TO k - 1 IF y(j) = y(k) THEN 8 NEXT GOTO 1 2 :
FOR j = 2 TO m IF y(j) < y(j - 1) THEN 8 NEXT I# = I# + 1 PRINT I#; ":"; FOR j = 1 TO m PRINT y(j); NEXT PRINT " " IF filename$ = "N" OR filename$ = "n" THEN 8 PRINT #1, I#; ":"; FOR j = 1 TO m PRINT #1, y(j); NEXT PRINT #1, " " GOTO 8 Впрочем, практического значения эти алгоритмы не имеют.Уже при n=12 даже компилированная программа считает слишлом медленно.Когда m задано,на порядки быстрее работает программа с m вложенными циклами.Вот как она выглядит для сочетаний.
CLS M = 5 INPUT "n="; N C# = N: Z# = 1 FOR i = 1 TO M - 1 C# = C# * (N - i) Z# = Z# * (i + 1) NEXT SOCH# = C# / Z# PRINT " Cm-n="; SOCH# SLEEP FOR n1% = 1 TO N - 4 FOR n2% = n1% + 1 TO N - 3 FOR n3% = n2% + 1 TO N - 2 FOR n4% = n3% + 1 TO N - 1 FOR n5% = n4% + 1 TO N i# = i# + 1 PRINT i#; ":"; n1%; n2%; n3%; n4%; n5% 1 NEXT n5% NEXT n4% NEXT n3% NEXT n2% NEXT n1% END
Такой фрагмент использован в программе 5 ферзей,находящей позиции доминирования ферзей на досках 8*8;9*9;10*10 и 11*11.Генерация размещений используется в программе игры “Быки и коровы”.
|