You are on page 1of 16

ალგორითმები - ცნებები და განსაზღვრებები.

ალგორითმის სირთულე.
ასიმპტოტური ნოტაცია.
ალგორითმის განსაზღვრება
ალგორითმს უწოდებენ ზუსტად განსაზღვრული წესებისა და
ინსტრუქციების ერთობლიობას, რომელთა თანმიმდევრულ
შესრულებას მივყავართ კონკრეტული ამოცანის
ამოხსნამდე.

ალგორითმის თვისებები:
• დისკრეტულობა: შედგება ცალკეული ბიჯებისაგან.
• სიცხადე: შეიცავს მხოლოდ პროცესორისათვის საჭირო
ბრძანებებს.
• განსაზღვრულობა: ყოველთვის ერთი და იგივე შედეგი
გამოაქვს ერთი და იგივე შემავალი მონაცემისათვის
• სასრულობა: მთავრდება ბიჯების სასრულ რაოდენობაში.
• ზოგადობა: შეიძლება მისი მრავალჯერადი გამოყენება
სხვადასხვა შემავალი მონაცემისათვის.
• კორექტულობა: იძლევა სწორ პასუხს ნებისმიერ დასაშვები
შემავალი მონაცემისათვის.
ალგორითმის სირთულე
ალგორითმის სირთულის ანალიზი აუცილებელია
მოცემული ამოცანის ამოხსნისათვის ოპტიმალური
ალგორითმის საპოვნელად. ალგორითმის
სირთულის კრიტერიუმად იყენებენ ელემენტარული
ოპერაციების რაოდენობას, რომელიც საჭიროა
მოცემული ალგორითმის საშუალებით ამოცანის
ამოხსნისათვის. სირთულის ფუნქცია წარმოადგენს
დამოკიდებულებას შემოსატან მონაცემებსა და
ელემენტარული ოპერაციების რაოდენობას შორის.
ალგორითმის სირთულე სხვადასხვაგვარად არის
დამოკიდებული შემოსატან მონაცემებზე. ზოგი
ალგორითმი დამოკიდებულია შესატანი
მონაცემების მოცულობაზე, ზოგი - მონაცემების
მნიშვნელობაზე, ზოგჯერ კი ალგორითმზე შესატანი
მონაცემების თანმიმდევრობა ახდენს გავლენას.
ასიმპტოტური ანალიზი
პრაქტიკაში ყველაზე მეტად გავრცელებულია
ალგორითმების ასიმპტოტური ანალიზი. მისი მიზანია დროისა
და მეხსიერების ხარჯვის შეფასება შესატანი მონაცემების
მოცულობის მიხედვით. ამისათვის გამოიყენება ე.წ.
ასიმპტოტური ფუნქციები, რომელთა კლასიფიკაციისათვის
შემოღებულია სპეციალური აღნიშვნები.

 Q, O, W, o, w
 განისაზღვრებიან როგორც ფუნქციები
მთელი დადებითი რიცხვებისათვის.
 პრაქტიკულად წარმოადგენენ
ფუნქციათა კრებულს, რომლებიც
ახდენენ ორი ფუნქციის ზრდის ტემპის
შედარებას;
 მაგალითად: ფუნქცია f(n) = Q(n2) აღწერს, თუ
როგორ იზრდება f(n) n2-თან შედარებით.
-ნოტაცია

g(n) ფუნქციისათვის (g(n))


განისაზღვრება, როგორც

(g(n)) = { f(n) :
 დადებითი მუდმივები
c1, c2, და n0, ისეთი რომ n
 n0,

0  c1g(n)  f(n)  c2g(n) }

f(n) და g(n) არაუარყოფითებია დიდი n-ისათვის.


მაგალითი

(g(n)) = { f(n) :  დადებითი მუდმივები c1, c2,


და n0, ისეთი რომ n  n0, 0  c1g(n)  f(n) 
c2g(n) }
• 10n2 - 3n = Q(n2)
• რომელი c1 და c2 მუდმივები გამოდგება?
• შევარჩიოთ c1 ოდნავ ნაკლები წამყვანი
წევრის კოეფიციენტზე, ხოლო c2 კი პირიქით -
ოდნავ მეტი.
• ზრდის ტემპის შესადარებლად საჭიროა
წამყვან წევრებზე დაკვირვება.
O-ნოტაცია
g(n) ფუნქციისათვის O(g(n)),
განისაზღვრება, როგორც:

O(g(n)) = {f(n) :
 დადებითი მუდმივა c
და n0, ისეთი, რომ n 
n0,
გვაქვს 0  f(n)  cg(n) }

g(n) არის f(n)-ის ასიმპტოტური ზედა საზღვარი


f(n) = (g(n))  f(n) = O(g(n)).
(g(n))  O(g(n)).
მაგალითი

O(g(n)) = {f(n) :  დადებითი მუდმივა c და


n0, ისეთი რომ n  n0, გვაქვს 0  f(n) 
cg(n) }

ნებისმიერი წრფივი an + b ფუნქცია


არის O(n2)-ში.

o(g(n)) = {f(n):  c > 0,  n0 > 0, ისეთი რომ


 n  n0, გვაქვს 0  f(n) < cg(n)}.
 -ნოტაცია
g(n) ფუნქციისათვის
(g(n)) განისაზღვრება,
როგორც:
(g(n)) = {f(n) :
 დადებითი მუდმივა c და n0,
ისეთი, რომ n  n0,
გვაქვს 0  cg(n)  f(n)}

g(n) არის f(n)-ის ასიმპტოტური ქვედა საზღვარი


f(n) = (g(n))  f(n) = (g(n)).
(g(n))  (g(n)).
მაგალითი

(g(n)) = {f(n) :  დადებითი მუდმივა c და


n0, ისეთი რომ n  n0, გვაქვს 0  cg(n) 
f(n)}

n = (lg n).
Q, O, W ფუნქციების ურთიერთკავშირი

თეორემა:
თეორემა: ნებისმიერი ორიg(n)
ნებისმიერიორი და f(n)
g(n)და f(n)
ფუნქციისათვის,
ფუნქციისათვის,
f(n)==(g(n)),
f(n) (g(n)),მაშინ
მაშინდა
დამხოლოდ
მხოლოდმაშინმაშინ,,როცა
როცა
f(n)
f(n)==O(g(n)) f(n)==(g(n)).
დაf(n)
O(g(n))და (g(n)).
ე.ი., (g(n)) = O(g(n)) Ç W(g(n))
მუშაობის (შესრულების) დრო
• “მუშაობის დროა O(f(n))” Þ უარეს შემთხვევაში O(f(n))
• O(f(n)) შემოსაზღვრულია უარესი შემთხვევის მუშაობის დროით 
O(f(n)) შემოსაზღვრულია თითოეული შემოსატანი მონაცემისათვის
• Q(f(n)) შემოსაზღვრულია უარესი შემთხვევის მუშაობის დროით 
Q(f(n)) შემოსაზღვრულია თითოეული შემოსატანი მონაცემისათვის.
• “მუშაობის დროა W(f(n))” Þ საუკეთესო შემთხვევა W(f(n))

მაგალითები:
• Insertion sort უარეს შემთხვევაში ალაგებს Q(n2) დროში, ე.ი.
სორტირება მუშაობს O(n2)-ში.
• სორტირების ნებისმიერი მეთოდი თითოეულ ელემენტს ერთხელ
მაინც იხილავს, ე.ი. სორტირების დრო ყოველთვის არის W(n).
• სორტირება შერწყმით (merge sort), ალაგებს მასივს Q(n lg n)
დროში უარეს შემთხვევაში.
o- და w - ნოტაცია

მოცემული g(n) ფუნქციისათვის:


o(g(n)) = {f(n):  c > 0,  n0 > 0, ისეთი რომ
 n  n0, გვაქვს 0  f(n) <
cg(n)}.

მოცემული g(n) ფუნქციისათვის:


w(g(n)) = {f(n):  c > 0,  n
0 > 0, ისეთი რომ

 n  n0, გვაქვს 0  cg(n) <


f(n)}.
თვისებები
• ტრანზიტულობა
f(n) = (g(n)) & g(n) = (h(n))  f(n) = (h(n))
f(n) = O(g(n)) & g(n) = O(h(n))  f(n) = O(h(n))
f(n) = (g(n)) & g(n) = (h(n))  f(n) = (h(n))
f(n) = o (g(n)) & g(n) = o (h(n))  f(n) = o (h(n))
f(n) = w(g(n)) & g(n) = w(h(n))  f(n) = w(h(n))
• რეფლექსურობა
f(n) = (f(n))
f(n) = O(f(n))
f(n) = (f(n))
• ურთიერთდამოკიდებულება
f(n) = O(g(n)) მაშინ და მხოლოდ მაშინ, როცა g(n) = (f(n))
f(n) = o(g(n)) მაშინ და მხოლოდ მაშინ, როცა g(n) = w(f(n))
• მონოტონურობა
f(n) არის მონოტონურად ზრდადი თუ m  n  f(m)  f(n).
მონოტონურად კლებადი თუ m  n  f(m)  f(n).
მკაცრად ზრდადი თუ m < n  f(m) < f(n).
მკაცრად კლებადი თუ m > n  f(m) > f(n).
მუშაობის სიჩქარე
სირთულე კომენტარი მაგალითი
O(1) დამოკიდებული არ არის ამოცანის ზომაზე. ძებნა ჰეშ-ცხრილში
O(log log n) დროის ძალიან ნელი ზრდა ელემენტის ძებნა ინტერპოლაციით

O(log n) ლოგარითმული ზრდა ორობითი ძებნა დალაგებულ მასივში


წრფივი დრო - ამოცანის ზომის ორჯერ
O(n) გაზრდა გამოიწვევს მუშაობის დროის წრფივი ძებნა n-ელემენტიან მასივში.
ორჯერ გაზრდასაც.
ლოგარითმულად წრფივი ზრდა. ამოცანის
n-ელემენტიანი მასივის მასივის
ზომის ორჯერ გაზრდა გამოიწვევს
O(n log n) დალაგება ჩქარი ან შერწყმით
მუშაობის დროის გაზრდას მცირედით
სორტირებით.
უფრო მეტჯერ ვიდრე 2-ია.
კვადრატული ზრდა — ამოცანის ზომის
მასივის სორტირების მარტივი
O(n²) ორჯერ გაზრდა გამოიწვევს მუშაობის
ალგორითმები
დროის ოთხჯერ გაზრდას.
კუბური ზრდა — ამოცანის ზომის ორჯერ მატრიცების გადამრავლების
O(n³) გაზრდა გამოიწვევს მუშაობის დროის ჩვეულებრივი მეთოდი. ფლოიდ-
რვაჯერ გაზრდას. ვორშელის ალგორითმი.

ექსპონენციალური ზრდა — ამოცანის


O(cn) ზომის ორჯერ გაზრდა გამოიწვევს კომივოიაჟერის ამოცანა.
მუშაობის დროის კვადრატულად გაზრდას.
მაგალითი
ვთქვათ, დასალაგებელია მილიარდი რიცხვი
პერსონალური კომპიუტერით, რომელიც წამში 100
მილიონ ოპერაციას აკეთებს.

ძალზე არაოპტიმალური ალგორითმი (ზოგი ასეთის დაწერასაც


ახერხებს):
O(2^n) =? (მზის სისტემის გაქრობამდე ნამდვილად ვერ მოასწრებს...)
“ბუშტულას” ალგორითმი:
O(n^2) = 1010 წამი ≈2777777 საათი (“ბუშტულაა” და მეტს ვერ მოსთხოვ...)
სორტირება გროვით:
O(n*log(n)) = 5 წუთი (თუ ძალიან არ გეჩქარებათ...)
წრფივი ალგორითმი:
O(n) = 10 წამი (ეს უკვე ზღვარია...)
და ბოლოს:
O(log(n)) = წამის მეასედი (ფანტასტიურად ჩქარი იქნებოდა, რომ
არსებობდეს...)

You might also like