Vypoctova zlozitost

Programovacie jazyky, rady, poradňa...
PAuLi3
Darca
Darca
Používateľov profilový obrázok
Príspevky: 4737
Registrovaný: 28 dec 2006, 18:33
Bydlisko: Komjatice,Nitra
Kontaktovať používateľa:

Vypoctova zlozitost

Príspevok od používateľa PAuLi3 »

Zdar, nevedel by mi niekto pomoct s tymto programom, treba mi zistit casovu a pamatovu zlozitost a neviem ako nato
a druha vec, ci by nebol niekto ochotny mi tento program nejak vysvetlit

Kód: Vybrať všetko

type
TSudoku = class
Pole: array [0..8, 0..8] of integer;
    Opakuje: array [0..8, 0..8] of Boolean;
    Stlpec: array [0..8] of set of 1..9;
    Riadok: array [0..8] of set of 1..9;
    Malystvorec: array [0..2, 0..2] of set of 1..9;
    constructor Create( Memo1:TMemo );
    procedure Vyplnsudoku;
    procedure Backtracking;
    function Moze(r,s, k: integer): Boolean;
end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
var
  Sudoku: TSudoku;
begin
 Sudoku := TSudoku.Create( Memo1 );
 Sudoku.Backtracking;
end;

constructor TSudoku.Create( Memo1:TMemo );
var
  sudokutext: TextFile;
  r,s: integer;
begin
 AssignFile(sudokutext, 'sudoku.txt');
 Reset(sudokutext);
 for r := 0 to 8 do
  for s := 0 to 8 do
  begin
   Read(sudokutext, Pole[r,s]);
   Opakuje[r,s] := Pole[r,s] <> 0;
   if Opakuje[r,s] then
   begin
    Stlpec[s] := Stlpec[s] + [Pole[r,s]];
    Riadok[r] := Riadok[r] + [Pole[r,s]];
    Malystvorec[r div 3, s div 3] := Malystvorec[r div 3, s div 3] + [Pole[r,s]];
   end;
  end;
  CloseFile(sudokutext);
  Vyplnsudoku;
end;

procedure TSudoku.Vyplnsudoku;
var
r,s: integer;
begin
 Form1.Memo1.Clear;
 for r := 0 to 8 do begin
 for s := 0 to 8 do
 Form1.Memo1.Text := Form1.Memo1.Text + '   ' + intToStr( Pole[r,s] );
 Form1.Memo1.Text := Form1.Memo1.Text + #13#10;
end;
 Form1.Memo1.Lines.Add( '   ' );
end;


function TSudoku.Moze(r,s, k: integer): Boolean;
begin
  Result := not (k in Riadok[r]) and
            not (k in Stlpec[s]) and
            not (k in Malystvorec[r div 3, s div 3]);
end;

procedure TSudoku.Backtracking;
var
  r,s,k: integer;
begin
 r := 0;
 s := 0;
 while (r < 9) and (Pole[r,s] <> 0) do
 begin
  inc(s);
   if s = 9 then
   begin
    inc(r);
    s := 0;
   end;
 end;
 if r = 9 then
 begin
  Vyplnsudoku;
  end
  else
    for k := 1 to 9 do
    if Moze(r,s, k) then
    begin
     Pole[r,s] := k;
     Stlpec[s] := Stlpec[s] + [k];
     Riadok[r] := Riadok[r] + [k];
     Malystvorec[r div 3, s div 3] := Malystvorec[r div 3, s div 3] + [k];
     Backtracking;
     Pole[r,s] := 0;
     Stlpec[s] := Stlpec[s] - [k];
     Riadok[r] := Riadok[r] - [k];
     Malystvorec[r div 3, s div 3] := Malystvorec[r div 3, s div 3] - [k];
    end;
 end;
end.
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: Vypoctova zlozitost

Príspevok od používateľa audiotrack »

si robíš srandu, že? Vysvetliť ti ho vysvetlím, ale nechci po mne aby som ti rátal zložitosti v backtrackingoch. Na to fakt nemám čas a keď vidím že je to úloha ktorú si zkopíroval a ani jej nerozumieš tak na to nemám ani chuť

no a čo to robí? Rieši sudoku. Ak nechápeš konkrétnej časti, tak sa spýtaj konkrétnejšie. Mne sa tam zdá všetko príliš triviálne aby som šiel riadok po riadku
PAuLi3
Darca
Darca
Používateľov profilový obrázok
Príspevky: 4737
Registrovaný: 28 dec 2006, 18:33
Bydlisko: Komjatice,Nitra
Kontaktovať používateľa:

Re: Vypoctova zlozitost

Príspevok od používateľa PAuLi3 »

sorry ale som noob v tomto, potreboval by som hlavne hlavnu proceduru backtracking vysvetlit
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: Vypoctova zlozitost

Príspevok od používateľa audiotrack »

procedure TSudoku.Backtracking;
var
r,s,k: integer;
begin
r := 0;
s := 0;
while (r < 9) and (Pole[r,s] <> 0) do
begin
inc(s);
if s = 9 then
begin
inc(r);
s := 0;
end;
end;

if r = 9 then
begin
Vyplnsudoku;
end

else
for k := 1 to 9 do
if Moze(r,s, k) then
begin
Pole[r,s] := k;
Stlpec[s] := Stlpec[s] + [k];
Riadok[r] := Riadok[r] + [k];
Malystvorec[r div 3, s div 3] := Malystvorec[r div 3, s div 3] + [k];

Backtracking;
Pole[r,s] := 0;
Stlpec[s] := Stlpec[s] - [k];
Riadok[r] := Riadok[r] - [k];
Malystvorec[r div 3, s div 3] := Malystvorec[r div 3, s div 3] - [k];

end;
end;
end.

budem to rozdelovať podľa farieb aby bolo jasné kde sa čo robí. Ospravedlňujem sa že sa tým pokazí tabulátorovanie, ale bude to aj tak prehľadnejšie. Nemohol som použiť code lebo by nebolo vidno farby

v prvej časti prechádza celou plochou, všetkých 9x9 štvorčekov (lebo je 9 riadkov a 9 stlpcov). Ak nájde hodnotu rôznu od 0 (teda je tam číslo), tak ide ďalej. Keď príde na koniec riadku (s=9) tak nastaví stlpec znova na nulu a riadok zvýši o jedna aby sa posunul o riadok nižšie
v druhej časti overí či sme prišli až na koniec, teda deviaty riadok a deviaty stlpec. Ak áno, znamená to že sme prešli všetky hodnoty (a všetky sú rôzne od nuly, lebo nám to zabezpečuje ten cyklus) takže máme sudoku vyplnené a zavoláme procedúru vypln ktorá ju vypíše.
v ďalšej časti (teda v časti že nemáme všetko vyplnené) skúsi postupne dosadiť hodnotu od 1 po 9 pre príslušné políčko. Túto hodnotu doplní (ako keby vieme že tam bude, lebo teoretickú možnosť že tam môže byť nám zaručí procedúra moze ktorá to overuje), zaráta ju do stlpca, riadku, do malého štvorca a zavolá znova sám seba, teda procedúru backtracking
v poslednej časti po sebe upratuje. To čo pred backtrackingom vyplnil a teraz sme zistili že to bolo zle, lebo procedúra dobehla a nemali sme všetky hodnoty vyplnené musíme zmazať (teda znova odráta zo stlpca, riadku, malého štvorca). Rekurzívne volanie dobehne, a konkrétna rekurzívna vetva sa skúša pre inú hodnotu v poradí 1-9 cyklu tejto farby

nedá sa to dobre vysvetliť písomne, lebo by si musel vedieť rekurziu, backtracking a pár info okolo toho a rozumieť tomu. Nie je to žiadna triviálna záležitosť pokiaľ nemáš prax a dobré algoritmické myslenie
Napísať odpoveď