Strutture di dati per almacenà i grafici: una rivista di quelli esistenti è dui "quasi novi".

Bonghjornu.

In questa nota, aghju decisu di listà e strutture di dati principali utilizati per almacenà i grafici in l'informatica, è parleraghju ancu di un coppiu più di tali strutture chì in qualchì modu "cristalizatu" per mè.

Allora, cuminciamu. Ma micca da u principiu - Pensu chì tutti sapemu dighjà ciò chì hè un gràficu è ciò chì sò (direttu, undirected, ponderatu, unweighted, cù o senza multiple bordi è loops).

Allora, andemu. Chì opzioni per strutture di dati per "almacenamiento graficu" avemu?

1. Strutture di dati Matrix

1.1 Matrice di adiacenza. A matrice di adiacenza hè una matrice induve l'intestazione di fila è colonna currispondenu à i numeri di i vertici di u graficu, è u valore di ognunu di i so elementi a(i,j) hè determinatu da a prisenza o l'assenza di bordi trà i vertici. i è j (hè chjaru chì per un gràficu senza direzzione una tale matrice serà simmetrica, o pudemu accettà chì avemu guardatu tutti i valori solu sopra à a diagonale principale). Per i grafici micca ponderati, a (i,j) pò esse stabilitu da u numeru di bordi da i à j (se ùn ci hè micca un tali bordu, allora a (i,j) = 0), è per i grafici ponderati, ancu da u pesu. (pesu tutale) di i bordi citati.

1.2 Matrice d'incidenza. In questu casu, u nostru gràficu hè ancu guardatu in una tavula in quale, in regula, i numeri di fila currispondenu à i numeri di i so vertici, è i numeri di colonna currispondenu à i bordi pre-numerati. Se un vertice è un bordu sò incidenti l'un à l'altru, allora un valore micca zero hè scrittu in a cellula currispundente (per i gràfici senza direzzione, 1 hè scrittu se u vertice è u bordu sò incidenti, per i grafici orientati - "1" se u bordu. "esce" da u vertice è "-1" s'ellu "include" in questu (hè abbastanza faciule da ricurdà, perchè u signu "minus" pari ancu esse "inclusi" in u numeru "-1"). Per i grafici ponderati, di novu, invece di 1 è -1, pudete specificà u pesu tutale di u bordu.

2. Strutture di dati di enumerazione

2.1 Lista di adiacenza. Ebbè, tuttu pare esse simplice quì. Ogni vertice di u graficu pò, in generale, esse assuciatu cù qualsiasi struttura di enumerazione (lista, vettore, array, ...), chì guardà i numeri di tutti i vertici adiacenti à quellu datu. Per i gràfici diretti, aghjunghje à una tale lista solu quelli vertici à quale ci hè una punta "diretta" da un vertice di funziunalità. Per i grafici ponderati l'implementazione serà più cumplessa.

2.2 Lista di costi. Una struttura di dati abbastanza populari. A lista di bordi, cum'è Captain Obviousness ci dice, hè in realtà una lista di bordi di u graficu, ognuna di quale hè specificatu da u vertice di partenza, u vertice finale (per i gràfici senza direzzione l'ordine ùn hè micca impurtante quì, anche se per l'unificazione pudete Aduprate diverse regule, per esempiu, specificendu i vertici in ordine crescente) è u pesu (per i gràfici ponderati solu).

Pudete guardà i liste di matrici listati sopra in più detail (è cù illustrazioni), per esempiu, ccà.

2.3 Array di adiacenza. Ùn hè micca a struttura più cumuna. In u so core, hè una forma di "imballa" liste di adiacenza in una struttura di enumerazione (array, vector). I primi n (sicondu u nùmeru di vertici di u graficu) elementi di un tali array cuntenenu l'indici di partenza di u stessu array, partendu da quale tutti i vertici adiacenti à quellu datu sò scritti in una fila.

Quì aghju trovu a spiegazione più comprensibile (per mè stessu): ejuo.livejournal.com/4518.html

3. Vettore di adiacenza è Array di adiacenza associativa

Risultava chì l'autore di sti linii, ùn essendu micca un programatore prufessiunale, ma chì periodicamente trattava cù gràfiche, a più spessu trattava liste di bordi. Infatti, hè convenientu se u graficu hà parechje loops è bordi. È cusì, in u sviluppu di i listi classici di bordi, pruponu à attentu à u so "sviluppu / ramu / mudificazione / mutazione", vale à dì: u vettore di adiacenza è l'array di adiacenza associativa.

3.1 Vettore di adiacenza

Casu (a1) : graficu micca ponderatu

Chjameremu un vettore di adiacenza per un gràficu micca ponderatu un inseme urdinatu di un numeru pari di numeri interi (a[2i], a[2i+1],..., induve i hè numeratu c 0), in quale ogni paru di numeri. hè a[2i], a[2i+1 ] specifica un bordu di u graficu trà i vertici a[2i] è a[2i+1], rispettivamente.
Stu formatu di registrazione ùn cuntene micca infurmazione nantu à se u graficu hè direttu (e duie opzioni sò pussibuli). Quandu si usa u formatu di digrafu, u bordu hè cunsideratu cum'è diretta da a[2i] à a[2i+1]. Quì è quì sottu: per i gràfici senza direzzione, se ne necessariu, i requisiti per l'ordine di i vertici di registrazione ponu esse applicati (per esempiu, chì u vertice cù u valore più bassu di u numeru assignatu hè prima).

In C++, hè cunsigliatu di specificà un vettore di adiacenza cù std::vector, da quì u nome di sta struttura di dati.

Casu (a2): graficu micca ponderatu, i pesi di u bordu sò interi

Per analogia cù u casu (a1), chjamemu u vettore di adiacenza per un gràficu ponderatu cù pesi di bordu interu un inseme urdinatu (matrice dinamica) di numeri (a[3i], a[3i+1], a[3i+2], ..., induve i hè numeratu c 0), induve ogni "triplettu" di numeri a[3i], a[3i+1], a[3i+2] specifica un bordu di u graficu trà i vertici numerati a[3i] è a[3i+1], rispittivamenti, è u valore a [3i+2] hè u pesu di stu bordu. Un tali gràficu pò ancu esse diretta o micca.

Casu (b): gràficu micca ponderatu, pesi di bordu senza interu

Siccomu hè impussibile di almacenà elementi eterogenei in un array (vector), per esempiu, l'implementazione seguente hè pussibule. U graficu hè almacenatu in un paru di vettori, in quale u primu vettore hè u vettore di adiacenza di u graficu senza specificà i pesi, è u sicondu vettore cuntene i pesi currispondenti (implementazione pussibule per C++: std::pair). ). Cusì, per un bordu definitu da una coppia di vertici sottu indici 2i, 2i+1 di u primu vettore, u pesu serà uguale à l'elementu sottu à l'indice i di u sicondu vettore.

Ebbè, perchè hè questu necessariu?

Ebbè, l'autore di sti linii hà trovu abbastanza utile per risolve una quantità di prublemi. Ebbè, da un puntu di vista formale, ci saranu i seguenti vantaghji:

  • U vettore di adiacenza, cum'è qualsiasi altra struttura "enumerativa", hè abbastanza compatta, occupa menu memoria di a matrice di adiacenza (per i gràfici sparsi), è hè relativamente faciule da implementà.
  • I vertici di u graficu, in principiu, ponu ancu esse marcati cù numeri negativi. E se una tale "perversione" hè necessariu?
  • I grafici ponu cuntene parechji bordi è cicli multipli, cù pesi diffirenti (pusitivi, negativi, ancu zero). Ùn ci sò micca restrizioni quì.
  • Pudete ancu assignà diverse proprietà à i bordi - ma per più nantu à questu, vede a sezione 4.

Tuttavia, deve esse admessu chì sta "lista" ùn implica micca un accessu rapidu à u bordu. E quì l'Associative Adjacency Array vene in salvezza, chì hè discutitu quì sottu.

3.2 Array di adiacenza associativa

Allora, se l'accessu à un bordu specificu, u so pesu è altre proprietà hè criticu per noi, è i bisogni di memoria ùn ci permettenu micca di utilizà a matrice di adiacenza, allora pensemu cumu pudemu cambià u vettore di adiacenza per risolve stu prublema. Allora, a chjave hè un bordu di u gràficu, chì pò esse specificatu cum'è un paru ordinatu di numeri interi. Chì pare questu? Ùn hè micca una chjave in un array assuciativu ? È, s'ellu hè cusì, perchè ùn l'avemu micca implementatu? Avemu un array assuciativu induve ogni chjave - un paru ordinatu di numeri interi - serà assuciatu cù un valore - un integer o un numeru reale chì specifica u pesu di u bordu. In C++, hè cunsigliatu di implementà sta struttura basatu annantu à u contenitore std::map (std::map). , int> o std::map , double>), o std::multap se sò previsti più bordi. Ebbè, avemu una struttura per almacenà gràfiche chì occupa menu memoria di e strutture "matrici", ponu definisce gràfiche cù cicli multipli è bordi, è ùn hà mancu esigenze strette per a non-negatività di i numeri di vertice (ùn sò micca sapè). quale hà bisognu di questu, ma ancu).

4. Strutture di dati sò pieni, ma qualcosa manca

È hè vera: quandu risolve una quantità di prublemi, pudemu avè bisognu di assignà alcune caratteristiche à i bordi di u graficu è, per quessa, guardà. Se hè pussibule di riduce senza ambiguità queste caratteristiche à interi, allora hè pussibule almacenà tali "grafichi cù funzioni supplementari" usendu versioni estese di u vettore di adiacenza è l'array di adiacenza associativa.

Dunque, avemu un gràficu micca ponderatu, per ogni bordu di quale hè necessariu di almacenà, per esempiu, 2 funzioni supplementari specificate da interi. In questu casu, hè pussibule di definisce u so vettore di adiacenza cum'è un inseme urdinatu micca di "coppie", ma di "quartetti" di numeri interi (a[2i], a[2i+1], a[2i+2], a [2i+3]…) , induve a[2i+2] è a[2i+3] determinaranu e caratteristiche di u bordu currispundenti. Per un gràficu cù pesi interi di i bordi, l'ordine hè in generale simili (a sola diferenza serà chì l'attributi seguitanu u pesu di u bordu è seranu specificati da l'elementi a[2i+3] è a[2i+4] , è u bordu stessu serà specificatu micca 4, ma 5 numeri urdinati). È per un gràficu cù pesi di bordu non integer, e caratteristiche ponu esse scritte in u so cumpunente micca ponderatu.

Quandu s'utilice una matrice di adiacenza associativa per i gràfiche cù pesi integeri, hè pussibule di specificà cum'è valore micca un solu numeru, ma un array (vector) di numeri chì specificanu, in più di u pesu di un bordu, tutti i so altri necessarii. caratteristiche. À u listessu tempu, un inconveniente per u casu di pesi non integer serà a necessità di specificà un signu cù un numeru in virgule flottante (iè, questu hè un inconveniente, ma s'ellu ùn ci hè micca tanti tali segni, è se ùn avete micca Ùn fate micca troppu "duppiu" duppiu, allora pò esse nunda). Questu significa chì in C ++ array di adiacenza associativa estesa ponu esse definite cum'è: std::map , std::vector> o std::map , std::vector, in quale u primu valore in u "key-value-vector" serà u pesu di u bordu, è dopu si trovanu i designazioni numerichi di e so caratteristiche.

Literatura:

Circa i grafici è l'algoritmi in generale:

1. Cormen, Thomas H., Leiserson, Charles I., Rivest, Ronald L., Stein, Clifford. Algoritmi : custruzzione è analisi, 2ª edizione : Trans. da l'inglese – M.: Edizioni Williams, 2011.
2. Harari Frank. Teoria di i grafi. M.: Mir, 1973.
U rapportu di l'autore nantu à sti stessi vettori è array associative di adiacenze:
3. Chernoukhov S.A. Vettore di adiacenza è array di adiacenza assuciativa cum'è modi per rapprisintà è almacenà grafici / SA Chernouhov. Vettore di adiacenza è mappa di adiacenza cum'è strutture di dati per rapprisintà un gràficu // Raccolta di articuli di a Cunferenza Scientifica è Pratica Internaziunale "Problemi di implementazione di i risultati di sviluppi innovatori è modi per risolviri" (Saratov, 14.09.2019 settembre 2019). – Sterlitamak : AMI, 65, p. 69-XNUMX
Fonti utili in linea nantu à u tema:
4. prog-cpp.ru/data-graph
5. ejuo.livejournal.com/4518.html

Source: www.habr.com

Add a comment