Тексты программ на Паскале


  { Программа решения задачи об n ферзях перебором с возвратом }
  program BacktrackQueens;
  var
      n : integer; { размер доски }
  queen : array[1..100] of integer; { массив положений ферзей }

  { Процедура печати решения }
  procedure WriteSolution;
  var
     i : integer;
  begin
     for i := 1  to n  do
         Write(queen[i],' ');
     WriteLn
  end;

  { Функция проверки совместимости m-го ферзя с предыдущими }
  function Check(m : integer) : boolean;
  var
      i : integer;
  begin
    for i := 1  to m-1  do
      if (queen[i] = queen[m]) { совпадают горизонтали }
       Or (i+queen[i] = m+queen[m]) { нисходящие диагонали }
       Or (i-queen[i] = m-queen[m]) { восходящие диагонали }
        then begin
         Check := False; Exit;
      end;
    Check := True;
  end;

  { Процедура, осуществляющая перебор }
  procedure Backtrack(m : integer);
  var
      i : integer;
  begin
     if m > n  then { найдено решение }
         WriteSolution
     else
        for i := 1  to n  do begin
           queen[m] := i;
           if Check(m) { m-ый ферзь не бьёт предыдущих }  then
                   Backtrack(m+1);
        end;
  end;

  begin
     Write('Размер доски? '); Read(n);
     Backtrack(1)
  end.



  { Программа решения задачи об n ферзях перебором
     с распостранением ограничений и просмотром вперёд }
  program PropagateQueens;
  var
      n : integer; { размер доски }
      queen : array[1..160] of integer; { массив положений ферзей }
      space : array[1..160,1..160] of integer;{пространство перебора}
      step : array[1..160] of integer; { порядок выбора ферзей }
      cases : array[1..160] of integer; { количество вариантов }

  { Процедура печати решения }
  procedure WriteSolution;
  var
      i : integer;
  begin
     for i := 1  to n  do
         Write(queen[i],' ');
     WriteLn
  end;

  { Процедура сокращения пространства перебора }
  procedure Prune(qm,queen,m : integer);
  var i, nq : integer;
    procedure ExcludeField(queen : integer);
    begin
       if (queen >= 1) and (queen <= n)  then
          if space[nq,queen] := 0  then begin
              Dec(cases[nq]); space[nq,queen] := m;
          end;
    end;
  begin
      for i := m+1  to n  do begin
          nq := step[i];
          ExcludeField(queen); { на той же горизонтали }
          ExcludeField(queen+nq-qm); { на той же диагонали }
          ExcludeField(queen-nq+qm);
      end;
  end;

  { Процедура восстановления пространства перебора }
  procedure Restore(qm,queen,m : integer);
  var i, nq : integer;
    procedure IncludeField(queen : integer);
    begin
       if (queen >= 1) and (queen <= n)  then
          if space[nq,queen] = m  then begin
              Inc(cases[nq]); space[nq,queen] = 0;
          end;
    end;
  begin
     for i := m+1  to n  do begin
         nq := step[i];
         IncludeField(queen); { на той же горизонтали }
         IncludeField(queen+nq-qm); { на той же диагонали }
         IncludeField(queen-nq+qm);
     end;
  end;

  var minq, l : integer;
  procedure Propagate(m : integer);
  var i, qm : integer;
  begin
     if m > n  then
         WriteSolution
     else begin
        { Выбирается ферзь с наименьшим количеством вариантов }
        minq := n+1;
        for i := m  to n  do
              if cases[step[i]] <= minq  then begin
                  l := i; qm := step[l]; minq := cases[qm];
              end;
        step[l] := step[m]; step[m] := qm;
        for i := 1  to n  do
             if space[qm,i] = 0  then begin
                queen[qm] := i;
                Prune(qm,i,m);
                Propagate(m+1);
                Restore(qm,i,m);
             end;
     end;
  end;

  var i, j : integer;
  begin
  Write('Размер доски? '); Read(n);
  for i := 1  to n  do begin
     for j := 1  to n  do
         space[i,j] := 0;
     step[i] := i; cases[i] := n;
  end;
  Propagate(1)
  end.

Следующая часть, Содержание