Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.
Nástěnka
❗22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
❗04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
❗23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.
Nejste přihlášen(a). Přihlásit
Stránky: 1
Na wiki jsou hned tři algoritmy, proklikneš se k nim odtud: http://en.wikipedia.org/wiki/Strongly_c … _component
Offline
Můžeme třeba trochu modifikovat Tarjanův algoritmus. Jeden vrchol si zvolíme za počátek, označme ho v. V poli tam si pro každý vrchol w budeme pamatovat, jestli se z v umíme dostat do w a v poli zpet, jesti se umíme dostat z w do v. Základem je rekurzivní procedura
over(w)
tam[w]:=true;
pro všechny w' do kterych vede hrana z w
pokud tam[w']=false
over(w')
pokud zpet[w']=true pak zpet[w]:=true;
end;
Na začátku nastavíme zpet[v] na true, pak stačí spustit proceduru over s parametrem v a na konci ověřit, že tam[w] i zpet[w] je pro všechny w rovno true.
Proč to funguje? Algoritmus je modifikací procházení do hloubky, proto bude správně nastaveno pole tam. Že bude správně nastaveno i pole zpet se ukáže indukcí vzhlem ke vzdálenosti od vrcholu v.
Offline
↑ Kondr:
díky za odpoved. Resim tyz problem a obecne tápu v zapisu kodu stylem programovani v prologu. Coz ma nejspise byt vystupem prave tohoto ukolu. Nas vyucujici to nazyva pseudokodem. Napriklad takto:
Euclid(a, b)
1 if b = 0
2 then return a
3 else if a > b
4 then return Euclid(b, a − b)
5 else return Euclid(a, b − a)
pricemz tento "pseudokod" reprezentuje nalezeni NSD (nejmensi spolecny delitel). Můžu te požádat ješte o podrobnější analýzu? Případně další odkaz pokud znáš? Děkuju!
Offline
Prolog a pseudokód jsou nebe a dudy :) Pseudokód je cokoli, co vypadá jako programovací jazyk a může to obsahovat kusy jazyka přirozeného. To ten můj zápis splňuje a pokud máte nějaké konvence pro psaní pseudokódu, nebude těžké to těm konvencím přizpůsobit.
Offline
to: Kromanon
predpokladam ze delas UTI 12 projekt na VSB banske, takze co kdyby jsme dali hlavy dokupy, nasel jsem k tomu celkem dost informaci i ten samostny algoritmus, tak kdyby ses ozval na icq 209083224, budu rád, dikes Tom
Offline
↑ Kromanon: Do každého vrcholu se vleze jen jednou, udělá se v něm konstantní počet operací a prohlédne se každá hrana, která z něho vede. Každá hrana se zkoumá nejvýš dvakrát (z jednoho a druhého konce), takže celková složitost O(V+E), standardní značení V=počet vrcholů, E=počet hran.
Offline
Ale 0(V+E) neni polynomialni slozitost myslim teda :)
Offline
↑ kalkulacka:Já myslím že jo. Nepíše se polynomiální vzhledem k čemu, ale vzhledem k V to je určitě v O(V^2) (to je polynom druhého stupně) a vzhledem k E nejde složitost určit (i když má graf jedinou hranu, stejně je potřeba inicializovat pole tam i zpet).
Offline
Složitost je závislost doby běhu programu na "velikosti vstupu". Pokud je vstup jedno číslo, bere se za velikost vstupu počet jeho cifer, pokud je to více čísel, jejich počet, atd. Někdy může být vstupů více, pak se složitost bere vůči více parametrům. Třeba vynásobit čísla o M a N cifrách klasickým způsobem -- každou cifrou vždy vynásobíme všechny ostatní, počítáme u toho přesahy, přičítáme je dál... pro každou dvojici cifer tedy uděláme cca 4 operace, celkem 4MN operací. Nás ale zajímá pouze jak rychle to roste. Pokud nám složitos něčeho vyjde jako 7MN^3+15M+N^2+3Nlog(N), bereme pouze ty nejvýznamnější členy a navíc u nich nepočítáme koeficienty a píšeme je jako parametr funkce O -- v tomto případě O(MN^3). Přece jen sečtení dvou čísel znamená na různých procesorech/v různých programovacích jazycích různý počet instrukcí, proto ty koeficienty nejsou důležité. Polynomiální složitost je jakákoliv O(f), kde f vznikne konečným počtem sčítání a násobení parametrů -- tedy třeba O(N^3+M) je polynomiální, ale O(2^N) ne.
U grafů se složitost počítá vzhledem k V a E -- počtu vrcholů a hran. Protože E<V^2, platí pro i>1 O(V^i+E)=O(V^i), takže člen E u složitějších algoritmů často můžeme zanedbat.
Offline
↑ Kromanon:Ne. Jestli je souvislý silně, zjistíme tím algoritmem. Graf s jednou hranou nikdy silně souvislý není.
Offline
↑ Kondr:
Dobře. Mám - li Tarjanuv algoritmus:
index = 0 // DFS node number counter
S = empty // An empty stack of nodes
forall v in V do
if (v.index is undefined) // Start a DFS at each node
tarjan(v) // we haven't visited yet
procedure tarjan(v)
v.index = index // Set the depth index for v
v.lowlink = index
index = index + 1
S.push(v) // Push v on the stack
forall (v, v') in E do // Consider successors of v
if (v'.index is undefined) // Was successor v' visited?
tarjan(v') // Recurse
v.lowlink = min(v.lowlink, v'.lowlink)
elif (v' is in S) // Was successor v' in stack S?
v.lowlink = min(v.lowlink, v'.index)
if (v.lowlink == v.index) // Is v the root of an SCC?
print "SCC:"
repeat
v' = S.pop
print v'
until (v' == v)
kam tedy vrazit tu modifikaci:
over(w)
tam[w]:=true;
pro všechny w' do kterych vede hrana z w
pokud tam[w']=false
over(w')
pokud zpet[w']=true pak zpet[w]:=true;
end;
aby to mepozbylo vyznamu co se tyce overeni te silne souvislosti?
Offline
Tarjanuv algoritmus je pro náš problém kanón na komára, ale jeho logika je taková, že procházíme graf do hloubky a pro každý uzel ověřujeme, že se z něj umíme dostat zpět do kořene komponenty. Protože my ale nechceme najít všechny komponenty, ale pouze ověřit, že je komponenta jen jedna, nepotřebujeme index a lowlink ale jenom tam a zpet. Proto je procedura over výrazně kratší než tarjan.
Offline
Kondr napsal(a):
Můžeme třeba trochu modifikovat Tarjanův algoritmus. Jeden vrchol si zvolíme za počátek, označme ho v. V poli tam si pro každý vrchol w budeme pamatovat, jestli se z v umíme dostat do w a v poli zpet, jesti se umíme dostat z w do v. Základem je rekurzivní procedura
over(w)
tam[w]:=true;
pro všechny w' do kterych vede hrana z w
pokud tam[w']=false
over(w')
pokud zpet[w']=true pak zpet[w]:=true;
end;
Na začátku nastavíme zpet[v] na true, pak stačí spustit proceduru over s parametrem v a na konci ověřit, že tam[w] i zpet[w] je pro všechny w rovno true.
Proč to funguje? Algoritmus je modifikací procházení do hloubky, proto bude správně nastaveno pole tam. Že bude správně nastaveno i pole zpet se ukáže indukcí vzhlem ke vzdálenosti od vrcholu v.
mohl bys si napsat celkovy ten algoritmus? prosel jsem si algoritmus, ktery to prohledava do hloubky, ale jak to prepsat na tarjanuv a tak aby to nebylo stejne??? mohl bys nam pomoct stim celkovym algoritmem....pls
Offline
Ahoj, ráda bych se taky na něco zeptala ohledně té složitosti. Není mi to totiž nějak vůbec jasné...
Nějak totiž asi nechápu rozdíl mezi tou složitostí, co se označuje O(n) a tou, co se označuje Theta(n).
Měla jsem za to, že O je složitost maximální, tzn, že když řeknu, že nějaký algoritmus má složitost v O(n^2), znamená to, možná trošku zjednodušeně, že algoritmus nikdy neprovede víc, než n^2 instrukcí. Nicméně klidně se může stát, že skončí třeba už po n instrukcích.
A pokud má algoritmus složitost v Theta(n^2), znamená to, že složitost toho algoritmu víceméně odpovídá n^2, takže taky neprovede víc, než n^2 instrukcí, ale nemělo by se ani stát, že skončí už po n. Protože by měl vždy skončit kolem někde kolem těch n^2.
Chápu to špatně?
A tak, jak je napsáno to zadání, bych to chápala tak, že se jedná právě o tu Theta složitost, takže ten hledaný algoritmus by měl být polynomiální, takže by měl mít složitost blízkou n^k. A pokud má tady ten vámi zmiňovaný algoritmus složitost O(V+E), tak má podle mě časovou složitost lineární a tak bych se obávala, jestli to skutečně není v rozporu se zadáním.
Pokud by se zadávajícímu jednalo o tu složitost O, pak by to bylo jistě v pořádku protože složitost O(lineární) jistě patří do O(polynomiální). Ale pokud by se mu jednalo o tu složitost Theta, pak podle mě složitost Theta(lineární) jistě nepatří do Theta(polynomiální).
Jste si jisti, že se to nedá chápat tak, jak jsem uvedla?
Offline
↑ cinique:No vždycky tam je "až na konstantu. Tzn. algoritmus se složitostí O(n^2) může skončit po 2n^2 krocích, po 11343984n^2 krocích, ale nemůže skončit po n^3 krocích.
Stejně tak v Theta(N) může skončit po 2n^2 nebo 0.5n^2 krocích, nemůže skončit po 23n krocích ani 0.00001n^3 krocích.
Podrobněji na wiki: http://en.wikipedia.org/wiki/Big_O_notation
Složitost Theta(V+E) je lineární a proto je polynomiální. Nicméně když se řekne "najděte algoritmus se složitostí ....", zpravidla se myslí O, ne Theta.
Offline
Stránky: 1