Задача 3 - Описание на решението и реализирания алгоритъм
Задачата далеч не е толкова проста, колкото изглежда. Някои биха си казали "какво
пък толкова, поредното динамично оптимиране", но ще сгрешат - динамичното оптимиране
не е приложимо в случая (защото за него трябва да е налице условието, че ако оптималния
път от a до c минава през b, то той се състои от оптималния път от a до b и оптималния
път от b до c, нещо, което в дадения случай не е налице).
Решението, което съм предложил, реализира обхождане в ширина (по брой маршрутизатори),
което обаче не спира при първия намерен път, защото може по-дълъг път да се окаже
с по-добра ефективно-надеждна оценка.
За всеки връх освен това не се съхранява само по една ефективно надеждна оценка,
а много двойки максимална пропускливост/ефективност, с които се е стигнало до съответния
връх. Това се налага, защото оптималният път от a до b може да е с някаква пропускливост
и надеждност, но нататък да трябва да се продължи с по-малка пропускливост, и в
такъв случай би било по-удачно да използваме път от a до b с по-малка пропускливост,
но по-висока надеждност.
Идеята на алгоритъма е следната: правим обхождане в ширина, като за всеки връх
правим списък на пропускливостите, с която се е стигнало до него, и максималните
ефективности за съответната пропускливост. Ясно е, че ако имаме два пътя с еднаква
пропускливост между два маршрутизатора, по-добре е да изберем този с по-голяма ефективност.
При всяка стъпка в ширината опресняваме списъците на всички маршрутизатори, които
ни попаднат (ако за някоя пропускливост сме стигнали с по-голяма ефективност - записваме
новата ефективност). Също така, не е необходимо в списъците да се държат двойки
пропускливост/ефективност, чието произведение е по-малко от максималната за момента
ефективно-надеждна оценка, получена за крайния маршрутизатор. Това се обосновава
с факта, че, придвижвайки се от един маршрутизатор на друг, ефективно-надеждната
оценка може само да намалява, следователно ако е по-малка от максималната за момента,
няма шанс да я надвиши. Работата на алгоритъма приключва, ако в дадена стъпка не
е настъпило никакво опресняване.
В хода на работата си алгоритъмът може да премахва и ребра (връзки между маршрутизатори),
чието произведение на пропускливостта и ефективността е по-малко от текущата максимална
ефективно-надеждна оценка за финалния маршрутизатор. Това може да се прави, защото
всеки път, който мине през това ребро, няма шанс да получи по-голяма ефективно-надеждна
оценка.
Макар че на пръв поглед скоростта на алгоритъма изглежда ниска, той всъщност
се справя доста добре, защото много бързо отхвърля неперспективните ребра от графа
и двойки ефективност/пропускливост от списъците на върховете, т.е. алгоритъмът доста
бързо се приближава към оптималното решение.
Реализацията на алгоритъма (решението на задачата, което съм приложил)
първо определя дали има път между началния и крайния маршрутизатор. За целта се
прави едно бързичко обхождане в ширина, което приключва в момента, в който достигнем
крайния маршрутизатор (или не успеем да стигнем до него). Освен това, ако има път,
така и така сме определили поне един от пътищата, нищо не ни струва да определим
и неговата ефективно-надеждна оценка, което ни дава един минимум, под който след
това се стремим да не падаме.
След като определи има ли път (и намери някаква ефективно-надеждна оценка), програмата
започва истинското обхождане в ширина. То всъщност свършва доста бързо. По-голямата
част от времето, което изразходва програмата, отива за прочитането на данните от
входния файл.
Стоян Йорданов Йорданов
|