powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / алгоритм
6 сообщений из 31, страница 2 из 2
алгоритм
    #38689918
balalexv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Sharahov,

Ну, в такой терминологии я кое-как из кода понял, мне же больше хочется понять физический смысл того, что хранится в переменных :).
...
Рейтинг: 0 / 0
алгоритм
    #38689920
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В ZeroIndex[i] для каждого AllCycles[i] записывается номеp младшего нулевого бита после первой серии единичных битов.
Это первое место, которое может оказаться не занято, после добавления соответствующего подсписка в текущий набор.
...
Рейтинг: 0 / 0
алгоритм
    #38689921
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
balalexvAleksandr Sharahov,

Ну, в такой терминологии я кое-как из кода понял, мне же больше хочется понять физический смысл того, что хранится в переменных :).

Смысл простой.
В начале набора может стоять только подсписок, в котором есть 1.
Перебираем их в цикле.
При этом каждый раз определяем первую свободную дырку.
Для очередной дырки перебираем все подсписки, кот. начинаются с такого элемента.
Если подсписок допустим, идем дальше.
Повторяем до победного конца.
...
Рейтинг: 0 / 0
алгоритм
    #38689931
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

Все-таки в 16272074 - самый правильный код.

Упрощенная процедура Generate() из 16272101 работает неверно и дает много грязи,
т.к. не проверяет допустимость очередного подсписка - это я ужинал, кровь от мозга оттекла наверно.

Жалко нельзя тут без помощи модератора удалить сообщение.
Если заглянет кто сюда, удалите 16272101 .
...
Рейтинг: 0 / 0
алгоритм
    #38690163
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
balalexv,

Немного погонял на разных данных.
Выяснилось, что не совсем верно использовать MaxZeroIndex для определения условия окончания рекурсии,
т.к. может оказаться, что все подмассивы, содержащие последний элемент, имеют дырку.
Правильнее будет каким-либо способом проверять, что все элементы вошли в текущий набор.
Исправленная версия под спойлером.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
//Cгенерировать все перестановки, которые состоят только из разрешенных циклов,
//например, перестановки длиной 5 из циклов {1},{2},{1,2},{1,4},{3,4,5},{3,4},{5},{1,2,3},{4,6},{3,5},{4},{1,5}.

unit AllowedPermForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TCycle= integer;

const
  CycleBitCount=8*SizeOf(TCycle);
  AllCycles: array[0..11] of TCycle=
   ($01, $02, $03, $09, $1C, $0C, $10, $07, $18, $14, $08, $11);
   //{1},{2},{1,2},{1,4},{3,4,5},{3,4},{5},{1,2,3},{4,6},{3,5},{4},{1,5}

var
  LastBitNo: integer;
  ZeroIndex: array of integer;
  UsedIndex: array[0..CycleBitCount-1] of integer;
  CycleIndex: array[0..CycleBitCount-1] of array of integer;

{
Выдача из Init:
LastBitNo = 4
ZeroIndex = 1  2  2  1  5  4  5  3  5  3  4  1
CycleIndex[0] = 0  2  3  7  11
CycleIndex[1] = 1
CycleIndex[2] = 4  5  9
CycleIndex[3] = 8  10
CycleIndex[4] = 6

Выдача из Print:
00000001  00000002  0000001C
00000001  00000002  0000000C  00000010
00000001  00000002  00000014  00000008
00000003  0000001C
00000003  0000000C  00000010
00000003  00000014  00000008
00000009  00000002  00000014
00000007  00000018
00000007  00000008  00000010
00000011  00000002  0000000C
}

procedure Print(Count: integer);
var
  i: integer;
  s: string;
begin;
  for i:=0 to Count-1 do s:=s + IntToHex(AllCycles[UsedIndex[i]], 8) + '  ';
  Form1.Memo1.Lines.Add(s);
  end;

function Init: boolean;
var
  i, j, k: integer;
  c, AllBits: TCycle;
//  s: string;
begin;
  AllBits:=0;
  SetLength(ZeroIndex, Length(AllCycles));
  for i:=Low(CycleIndex) to High(CycleIndex) do CycleIndex[i]:=nil;
  for i:=Low(AllCycles) to High(AllCycles) do begin;
    c:=AllCycles[i];
    AllBits:=AllBits or c;
    if c<>0 then begin;
      j:=0;
      while c and 1=0 do begin;
        c:=c shr 1;
        inc(j);
        end;
      k:=Length(CycleIndex[j]);
      SetLength(CycleIndex[j], k+1);
      CycleIndex[j, k]:=i;
      while c and 1=1 do begin;
        c:=c shr 1;
        inc(j);
        end;
      ZeroIndex[i]:=j;
      end;
    end;
  Result:=(AllBits and (AllBits+1)=0);
  LastBitNo:=-1;
  while AllBits<>0 do begin;
    AllBits:=AllBits shr 1;
    inc(LastBitNo);
    end;
{
  Form1.Memo1.Lines.Add(Format('LastBitNo = %d',[LastBitNo]));
  s:='ZeroIndex = '; for i:=0 to Length(ZeroIndex)-1 do s:=s + IntToStr(ZeroIndex[i]) + '  ';
  Form1.Memo1.Lines.Add(s);
  for j:=0 to LastBitNo do begin;
    s:=Format('CycleIndex[%d] = ',[j]);
    for i:=0 to Length(CycleIndex[j])-1 do s:=s + IntToStr(CycleIndex[j,i]) + '  ';
    Form1.Memo1.Lines.Add(s);
    end;
}
  end;

procedure Generate(Count, BitNo: integer; Mask: TCycle);
var
  i, Index, NewBitNo: integer;
  c, t, NewMask: TCycle;
begin;
  for i:=0 to Length(CycleIndex[BitNo])-1 do begin;
    Index:=CycleIndex[BitNo, i];
    c:=AllCycles[Index];
    if Mask and c=0 then begin;
      NewMask:=Mask or c;
      UsedIndex[Count]:=Index;
      NewBitNo:=ZeroIndex[Index];
      t:=1; t:=t shl NewBitNo;
      while t and NewMask<>0 do begin;
        t:=t+t; inc(NewBitNo);
        end;
      if NewBitNo>LastBitNo then Print(Count+1)
      else Generate(Count+1, NewBitNo, NewMask);
      end;
    end;
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin;
  Memo1.Lines.Add('Начало работы');
  if Init then Generate(0,0,0);
  Memo1.Lines.Add('Конец работы');
  end;

end.

...
Рейтинг: 0 / 0
алгоритм
    #38690175
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обращаю внимание на то, что комментарии к данным могут не совсем соответствовать самим данным.
Это из-за того, я при экспериментах не всегда правил комментарии.
В частности, вижу, что в комментарии стоит цикл {4,6} вместо {4,5}.
...
Рейтинг: 0 / 0
6 сообщений из 31, страница 2 из 2
Форумы / Программирование [игнор отключен] [закрыт для гостей] / алгоритм
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]