You are on page 1of 20

Програмски јазик IV-4

максимално спојување во граф


спојување на темиња во дводелен (бипартитен)
граф
Максимално спојување во граф
Теоријата на графови се користи за решавање на разни
проблеми. Како што ќе видиме во продолжение, кај
голем дел од нив се среќаваат само два типа на објекти
(претставени како темиња во графот).
За ваквите графови, каде што темињата можат да се
поделат на две множества и секое теме од едното
множество може да се поврзе само со теме од другото
множество, велиме дека се дводелни или бипартитни
графови.
Максимално спојување во граф
На пример, да замислиме граф со кој сакаме да
претставиме работници (со едното множество) и
работни места (со другото множество). Сега,
ребрата можат да ги поврзуваат работните места со
работниците кои се способни да ги пополнат
истите - што значи дека ребрата ќе бидат помеѓу
темиња од едното множество (работници) и
темиња од другото множество (работни места).
Нормално, нема да има ребра помеѓу работниците,
или помеѓу работните места.
Максимално спојување во граф
Во продолжение, ќе зборуваме за проблемот на пресметка на максимално
спојување во дводелен граф (анг. maximum bipartite matching).
Кај овој проблем, сакаме да одредиме колку најмногу ребра можат да се
одберат од графот, така што секое од темињата е поврзано со најмногу
едно ребро (не постојат две ребра кои завршуваат во исто теме).
Доколку го искористиме проблемот со работниците и работните места кој
го споменавме претходно, ова значи дека ќе има најмногу едно ребро кај
секој работник и најмногу едно ребро кај секое работно место – односно,
со користење на овој алгоритам, ќе пресметаме колку најмногу работни
места можат да се пополнат, така што секој работник ќе работи најмногу
една работа, и секое работно место ќе биде доделено на најмногу еден
работник.
Ова е исклучително корисен алгоритам, кој наоѓа примена во многу
различни ситуации.
Максимално спојување во граф

 Како што можете да видите од сликите погоре, со црна боја се означени


ребрата кои се дел од максималното спојување. Забележете дека и кај
двете слики постои ребро од оригиналниот граф (работник кој е способен
за одредено работно место) кое што не е дел од максималното спојување
во дводелниот граф (означено со сива боја), бидејќи кај спојувањето не
може повеќе ребра да завршуваат во исто теме.
Максимално спојување во граф
Во овој случај, со сликата сакаме да претставиме дека
може да постојат повеќе начини да се изврши
спојувањето, така што бројот на ребра ќе биде
максимален (во овој случај, четири спојувања).
Доколку постојат повеќе начини, нашиот алгоритам ќе
одбере еден од нив - бидејќи целта е да се направи
максимално спојување (да пронајдеме работа за што е
можно повеќе работници), и не е важно кои ребра ќе
бидат одбрани од дводелниот граф.
Имплементација
Постојат повеќе алгоритми за решавање на овој
проблем. Во продолжение, ние ќе го разгледаме оној
кој што е наједноставен за имплементација, а сепак
функционира исклучително ефикасно.
 За претставување на графот, како и во повеќето
други алгоритми кои ги видовме досега, ќе
користиме листи на соседство (кои, во овој случај,
ќе ни ги означуваат почетните ребра – на пример, за
проблемот со работниците, тоа е информацијата кој
работник може да го пополни кое работно место).
Имплементација
Пред да ја видиме имплементацијата на овој
алгоритам во програмскиот јазик C++, да
споменеме накратко како истиот функционира.
Главната идеја е обидот да се поврзе одредено теме
од едното множество, разгледувајќи ги ребрата од
истото, со било кое теме од другото множество.
Доколку некое од темињата во другото множество е
слободно (не е поврзано сеуште), тогаш ги
означуваме овие две темиња (од едното и другото
множество) како поврзани.
Имплементација
Доколку пак темето (нека го наречеме Y) од другото множество е
веќе поврзано со некое теме X (од првото множество), тогаш
рекурзивно ќе се обидеме да пронајдеме друга врска од X, со цел
темето Y да ни се ослободи и да можеме истото да го искористиме.
Со други зборови, со секој чекор се обидуваме да го зголемиме
бројот на ребра (поврзувања) од едното до другото множество –
притоа, ако е потребно, како во овој случај, некое ребро кое веќе
сме го одбрале (X до Y) да го избришеме, тогаш тоа и ќе го
направиме.
Последното нешто на што треба да внимаваме е да имаме
дополнителна низа seen[], која ќе ни означува кои темиња веќе сме
ги разгледале, со цел рекурзијата да не заврши во бесконечен
циклус на изминување на истите темиња и ребра.
Задачи:
Во претходниот дел, веќе споменавме еден пример
каде што може да се примени овој алгоритам –
спојување на работници со потенцијални работни
места.
Истиот може да се примени и на други варијации од
истиот проблем – на пример, спојување на ментори со
ученици (каде ребрата означуваат кој ментор може да
му помогне на ученик во соодветната област – на
пример, ментор по математика со ученици кои имаат
проблем по тој предмет).
Покрај ова, можно е да постојат и проблеми каде што
треба да направиме мала анализа пред да го создадеме
графот, а потоа и само да го повикаме алгоритамот кој
го видовме погоре.
На пример, да замислиме дека во некој град има
проблем со пронаоѓање на паркинг места, и
одлучиме да направиме дводелен граф каде што од
едната страна на графот ќе претставиме множество
од коли, а од другата страна ќе претставиме
множество од паркинг места.
Да речеме дека од нас се бара да пресметаме на
колку најмногу коли може да им се доделат паркинг
места, доколку луѓето не сакаат да ја паркираат
нивната кола подалеку од 3 километри од местото
во кое живеат?
Во овој случај, веќе ни е дадено множеството на
коли и множеството на паркинг места, и ние само
треба да ги создадеме почетните ребра во
дводелниот граф (коли до потенцијални паркинг
места).
Единствено што треба да направиме е од секоја
кола (која припаѓа на некој жител), да направиме
ребра до паркинг местата кои се на оддалеченост од
најмногу 3 километри од местото каде живее
сопственикот на таа кола.
Овој граф ни е веќе комплетен (ги знаеме темињата
и листите на соседство), па само треба да го
извршиме алгоритамот прикажан погоре.
Да разгледаме сега уште еден проблем. Нека имаме
неколку коцки (коцките имаат 6 страни), на кои е
запишана по една цифра (0 до 9) на секоја страна
од коцките.
На пример, може да имаме коцка на која се
запишани цифрите 1, 3, 5, 3, 0, 4 – по една цифра на
секоја страна од коцката.
Што ако треба да пресметаме дали дел од овие
коцки може да се наредат една по друга, така што
на нив ќе биде испишан одреден број (на пример,
59391401), како што е прикажано на сликата? Дали
можеме да напишеме програма за решавање на овој
проблем?
И овој пример може да се реши со помош на алгоритамот
за пресметка на максимално спојување во дводелен граф.
Единствено што треба да направиме е да ги ставиме
коцките како едно множество во графот (секоја коцка е
едно теме), а секоја од цифрите во бројот кој треба да го
создадеме ќе биде дел од другото множество во
дводелниот граф.
Понатаму, ќе ги поврземе темињата (со ребра),
така што коцка (една страна на графот) ќе поврземе
со цифра (друга страна на графот), доколку коцката
ја има таа цифра на едната од шесте свои страни.
По извршување на алгоритамот, треба само да
провериме колку поврзувања успеал истиот да
направи.
Доколку сме успеале да ги поврземе сите цифри од
бројот со некоја коцка, тогаш сме го решиле
оригиналниот проблем – во спротивно, не е можно
со коцките кои ги имаме на располагање да го
решиме истиот.
Кај овој проблем, користевме ваков алгоритам бидејќи
секоја коцка може да се искористи само еднаш (за
запишување на само една цифра од бројот).
Доколку ова не беше случај, само ќе проверевме (со некој
едноставен алгоритам) дали постои секоја од цифрите кај
било која коцка.
За полесно да го разберете ова, замислете коцка каде што
на сите шест страни се наоѓа цифрата 1, и друга коцка каде
што на сите шест страни се наоѓа цифрата 2.
Сега, ако треба со помош на овие коцки да го запишеме
бројот "11", тоа не можеме да го направиме - бидејќи ако ја
искористиме првата коцка за пишување на првата цифра од
"11", тогаш веќе немаме друга коцка (на која имаме страна со
цифра 1) за да ја запишеме и втората цифра од "11".
 Имплементацијата на оваа програма е дадена во продолжение, со влезни податоци
кои се состојат од 5 коцки и бројот “2304” (се разбира, истите може да се променат).

You might also like