Výpočetní technika II - Algoritmizace v systému MATLAB Aktualizace: 26. prosince 2000


Navigační menu
  Vysvětlivky
  Obsah
  Kapitola 1: Matlab
       Kapitola 1.1: Úvod
       Kapitola 1.2: Režimy práce
  Kapitola 2: Skaláry, vektory, matice
       Kapitola 2.1: Operace
       Kapitola 2.2: Funkce
       Kapitola 2.3: Submatice
  Kapitola 3: Vytváření funkcí
  Kapitola 4: Větvení a rozhodování
  Kapitola 5: While cyklus
  Kapitola 6: For cyklus
  Kapitola 7: Objekty a 2-D grafika
  Kapitola 8: 3-D grafika
  Kapitola 9: Datové soubory
       Kapitola 9.1: Ukládání do souboru
       Kapitola 9.2: Načtení ze souboru
       Kapitola 9.3: Import dat z Excelu
  Kapitola 10: Symbolická matematika
  Kapitola 11: Řešení rovnice f(x)=0
  Kapitola 12: Soustavy lineárních rovnic
  Kapitola 13: Minimum funkce f(x)
  5. While cyklus  

 
  • Motto: Každý algoritmus lze popsat pomocí posloupnosti příkazů, větvení a cyklu s testováním před tělem cyklu. Dijkstra 1958.
  • Bez cyklu – každý příkaz se provede nejvýše jednou
    S cyklem – každý příkaz uvnitř cyklu se provede nejvýše N-krát
  • Důsledek pro programátora: Nechápu-li možnosti cyklu, pak doba potřebná k vytvoření programu je nejen vyšší než doba výpočtu, ale i vyšší než užitek z něj.
  • Cyklus má svůj začátek – while logická_podmínka
    Cyklus má svůj konec – end
    Cyklus má své tělo – libovolné příkazy mezi while a end
    Příkazem return – v těle větvení můžeme realizovat předčasný únik z funkce
    Existují i jiné příkazy pro předčasné ukončení cyklu, ale kazí programátorský styl
  • Obecná syntaxe:
 
       while logická_podmínka
        % tělo_cyklu
     end
 
 
  • Dijkstrův systém:
    V posloupnosti příkazů mohou být větvení (několik) nebo cykly.
    Uvnitř větvení může být posloupnost příkazů, cyklus nebo jiné větvení.
    Uvnitř cyklu může být posloupnost příkazů, větvení (jedno) nebo jiný cyklus.
  • Příklad cyklu ze života:
 
       zalez_do_postele;
     while unaven
        zdrimni_si;
     end
     vylez_z_postele;
 
 
  • Příklad cyklu uvnitř větvení:
 
       if unaven
        zalez_do_postele;
        while unaven
           zdrimni_si;
        end
     vylez_z_postele;
     end
 
 
  • Příklad větvení uvnitř cyklu:
 
       jdi_do_prace;
        while cas<16.00
           if nekdo_jde_kolem
              predstirej_praci;
           else
              zdrimni_si;
           end
        end
        jdi_domu;
 
 
  • Příklad cyklu uvnitř jiného cyklu:
 
       while zijes
        while unaven
           zdrimni_si;
        end
        servi_nekoho;
     end
 
 
  • Příklad cyklu s počítadlem nesežraných sušenek:
 
       jdi_na_navstevu;
     pocet_susenek=29;
     while pocet_susenek>0
        snez_susenku;
        pocet_susenek=pocet_susenek-1;
     end
     jdi_domu;
 
 
  • Zvolání: Kdo nepochopil algoritmus s cyklem, ten ho také nekrokoval.
    Poznámka 1: Cyklus umožňuje elegantně zobecnit řešení problému.
    Poznámka 2: Cyklus umožňuje realizovat hromadné zpracování dat.
    Poznámka 3: Elegance znamená co nejmenší počet příkazů, co nejmenší spotřebu paměti počítače nebo co nejkratší dobu výpočtu – vyberte si.
 

  Příklad 5A.1:  
  Sestavte funkci na výpočet největšího společného dělitele dvou přirozených čísel.
Instrukce: Starý řecký matematik Euklides vymyslel elegantní algoritmus, který pochopíte nejlépe jeho krokováním při různých hodnotách parametrů. Proč je algoritmus naivní?
 
  Řešení:  
 
function [nsd]=NaivniNSD(a,b)
% Naivni realizace nejvetsiho spolecneho delitele dle Euklida
% [nsd]=NaivniNSD(a,b);
% nsd ... nejvetsi spolecny delitel
% a ... prvni prirozene cislo
% b ... druhe prirozene cislo
while a~=b % pokud se jeste nerovnaji
   if a>b % mozna, ze a je vetsi nez b
      a=a-b; % zmensi a
   else
      b=b-a; % zmensi b
   end
end
nsd=a; % ted jsou hodnoty a, b stejne a rovne deliteli
 

  Příklad 5A.2:  
  Nastudujte funkce floor, abs a mod pomocí příkazu help a pak si uvědomte, proč následující funkce není naivní.  
  Řešení:  
 
function [nsd]=NSD(a,b)
% Efektivni realizace nejvetsiho spolecneho delitele dle Euklida
% [nsd]=NSD(a,b);
% nsd ... nejvetsi spolecny delitel
% a ... prvni prirozene cislo
% b ... druhe prirozene cislo
a=floor(abs(a)); % proc?
b=floor(abs(b)); % ze stejneho duvodu
while a>0 & b>0 % pokud jsou obe kladna
   if a>b % mozna, ze a je vetsi nez b
      a=mod(a,b); % rychle zmensi a nahrazenim zbytkem po deleni
   else
      b=mod(b,a); % rychle zmensi b nahrazenim zbytkem po deleni
   end
end
if a+b==0 % co kdyby byly obe hodnoty nulove
   nsd=1; % proc?
else
   nsd=a+b; % prave jedno z cisel ma hodnotu nula
end
 
 
  Příklad 5A.3:  
  Sestavte funkci pro řešení rovnice x = F(x) metodou prosté iterace, a pak ji použijte na řešení rovnice x = sin x + x v intervalu od 3 do 4.
Instrukce: Nejprve v klidu a bez cyklu vytvoříme konkrétní funkci
F(x) = sin x + x. Pak se budeme zabývat metodou prosté iterace jako obecným nástrojem pro řešení rovnice x = F(x).
 
  Řešení:  
 
function [y]=F(x)
% pokusna funkce pro prostou iteracni metodu
% x ... realne cislo
% y ... x+sin(x)
y=x+sin(x);
 
function [x]=ProstaIterace(a,b,x0,nmax,epsilon)
% Bezpecne reseni rovnice x=F(x) metodou proste iterace
% [x]=ProstaIterace(a,b,x0,nmax,epsilon);
% x ... nalezene reseni rovnice
% a ... dolni mez definicniho oboru F(x)
% b ... horni mez definicniho oboru F(x)
% x0 ... pocatecni odhad reseni a<=x<=b
% nmax ... maximalni pocet vycisleni funkce F(x)
% epsilon ... tolerance rozdilu mezi levou a pravou stranou rovnice
% dokud neni duvod k pochybam o metode
while nmax>0 & x0>=a & x0<=b
   % jeden krok proste iterace a jedno vycisleni funkce F
   x=F(x0);
   nmax=nmax-1; % mame o jeden zivot mene
   if abs(x-x0)<epsilon % budeme koncit?
      return; % hodnota x uz je dobra
   end
   x0=x; % "Co bylo, uz neni..." Byron
end
x=inf; % nenalezeno reseni
 
 
  Příklad 5A.4:  
  Nastudujte v helpu možnosti funkcí feval a eval. Potom sestavte funkci pro řešení libovolné rovnice x = F(x) metodou prosté iterace.
Instrukce: Funkci VyresCokoli se zadává jméno funkce jako řetězec v apostrofech. Pokuste se vyřešit rovnice x = sin x + x nebo x = cos x ve vhodných intervalech. Krokujte do hloubky s důrazem na provádění funkce feval.
 
  Řešení:  
 
function [x]=VyresCokoli(jmenoF,a,b,x0,nmax,epsilon)
% Obecne reseni rovnice x=F(x) metodou proste iterace
% [x]=VyresCokoli(jmenoF,a,b,x0,nmax,epsilon);
% x ... nalezene reseni rovnice
% jmenoF ... nazev funkce F(x) jako retezec znaku
% a ... dolni mez definicniho oboru F(x)
% b ... horni mez definicniho oboru F(x)
% x0 ... pocatecni odhad reseni a<=x<=b
% nmax ... maximalni pocet vycisleni funkce F(x)
% epsilon ... tolerance rozdilu mezi levou a pravou stranou rovnice
while nmax>0 & x0>=a & x0<=b % stejne
   % ukazka neprimeho volani funkce jmenem v bode x0
   x=feval(jmenoF,x0);
   nmax=nmax-1; % stejne
   if abs(x-x0)<epsilon % stejne
      return % stejne
   end
   x0=x; % stejne
end
x=inf; % stejne
 
 
  Příklad 5A.5:  
  Jistě znáte omšelou hitorku z 19. století, jak neposlušný žák Gauss dostal za trest spočítat součet všech čísel od 1 do 100 a on to měl hned hotové. Sestavte funkci pro výpočet součtu prvních n přirozených čísel.
Instrukce: Krokujte a místo proměnné k si představte počet čárek na tácku.
 
  Řešení:  
 
function [s]=ZaTrest(n)
% Soucet prvnich n prirozenych cisel
% [s]=ZaTrest(n);
% s ... hodnota souctu
% n ... pocet cisel
k=1; % prvni clen souctu
s=0; % soucet zacina od nuly
while k<=n % mame jeste pricitat?
   s=s+k; % pricteme 1,2,3,...
   k=k+1; % zvetsime na dalsi clen 2,3,4,...
end
 
 
  Příklady pro samostatné vypracování  
  Příklad 5B.1:  
  Pomocí funkce NSD sestavte funkci pro výpočet nejmenšího společného násobku dvou čísel.  
 
  Příklad 5B.2:  
  Pomocí funkce NSD sestavte funkci pro výpočet nejmenšího společného dělitele čísel uložených ve vektoru. Použijte funkci size.  
 
  Příklad 5B.3:  
  Pyramida je stavěna z kostek a bez dutin. Výška pyramidy je H. Základna pyramidy je čtverec o straně H. Sestavte funkci pro spotřebu kostek na její stavbu. Definujte pojem vytunelovaná pyramida alespoň třemi různými obecnými způsoby. Pro každou definici sestavte funkci pro spotřebu kostek na její stavbu.  
 
  Příklad 5B.4:  
  Blouznivý poutník ušel první den A kilometrů. Další dny ušel vždy polovinu trasy předchozího dne a ještě k tomu opačným směrem. Bez použití mocnin sestavte funkci, která z počtu dnů N a vzdálenosti A určí délku pochodu, vzdálenost mezi začátkem a cílem pochodu a účinnost poutníka v procentech.  
 
  Seznam použitých příkazů  
  while, return, floor, abs, mod, help, feval, eval  



© 2000 by Darina Bártová, Jaromír Kukal, Martin Pánek

Testováno v prohlížečích MSIE 5.x a NN 4.x při rozlišení 1024x768x256