1. Grafs: Sistema fluvial (4 Punts)

../../../../_images/concaAmazones1.png

Representarem un sistema fluvial, és a dir, un conjunt de rius més els seus afluents, com un graf dirigit de networkx (un DiGraph). En aquest graf, els nodes són els noms dels rius i una aresta indica que un riu és afluent d’un altre. La direcció de l’aresta va de l’afluent, que és més petit, al riu al qual desemboca, que és més gran, tal com es mostra al dibuix.

Un riu que aporta les seves aigües, directa o indirectament, a les d’un altre se l’anomena tributari. Per exemple, els rius Jari, Juruena, i Arinos són tributaris de l’Amazones.

../../../../_images/rius1.svg

En el següent exemple, el graf gr representa una petita part del sistema fluvial dels rius Amazones i Orinoco, el que està dibuixat més amunt:

>>> import networkx as nx

>>> lrius = [ ['Jari', 'Amazones'], ['Xingú', 'Amazones'], ['Iriri', 'Xingú'],
...  ['Paru', 'Amazones'], ['Tapajós', 'Amazones'], ['Teles Pires', 'Tapajós'],
...  ['Juruena', 'Tapajós'], ['Arinos', 'Juruena'], 
...  ['Guaviare', 'Orinoco'], ['Inírida', 'Guaviare'], ['Arauca', 'Orinoco'] ]
>>> gr = nx.DiGraph()
>>> gr.add_edges_from(lrius)

1.1. Funció afegeix_cabals

Al mòdul rius (fitxer rius.py), implementeu-hi la funció modificadora següent:

rius.afegeix_cabals(gr, dc)
Paràmetres:
  • gr – graf de NetworkX que representa un sistema fluvial.

  • dc – diccionari, on les claus són noms de rius i els valors són el cabal anual promig del riu, en \(m^3/s\).

Modifica gr assignant als rius els cabals associats als noms de dc com un atribut de node anomenat 'cabal'. Si algun dels noms de dc no és un riu de gr, no se li assigna el cabal.

Per exemple, si gr és el graf de més amunt sense cap cabal assignat, aquesta funció ha de respondre així:


>>> afegeix_cabals(gr, {'Amazones': 230000})
>>> gr.nodes['Amazones']
{'cabal': 230000}
>>> dcabals = {'Jari': 1003, 'Orinoco': 33000, 'Ebre': 426,
...  'Tapajós': 13000, 'Teles Pires': 3978, 'Xingú': 9700}
>>> afegeix_cabals(gr, dcabals)
>>> sorted(gr.nodes(data=True))
[('Amazones', {'cabal': 230000}), ('Arauca', {}), ('Arinos', {}), ('Guaviare', {}), ('Inírida', {}), ('Iriri', {}), ('Jari', {'cabal': 1003}), ('Juruena', {}), ('Orinoco', {'cabal': 33000}), ('Paru', {}), ('Tapajós', {'cabal': 13000}), ('Teles Pires', {'cabal': 3978}), ('Xingú', {'cabal': 9700})]

Disposeu de més jocs de proves al fitxer tests-cabals.txt.

1.2. Funció max_tributaris

Al mateix mòdul rius (fitxer rius.py), implementeu-hi la funció següent:

rius.max_tributaris(gr, nriu)
Paràmetres:
  • gr – graf de NetworkX que representa un sistema fluvial.

  • nriu – nom d’un riu.

Retorna:

nom de l’afluent de nriu que té més rius tributaris. Si hi ha dos o més afluents de nriu que tenen el mateix nombre de tributaris, retorna el nom de qualsevol d’ells. En el cas que nriu no tingui afluents, retorna l’string buit.

Per exemple, si gr és el graf de més amunt, aquesta funció ha de respondre així:


>>> max_tributaris(gr, 'Orinoco')
'Guaviare'
>>> max_tributaris(gr, 'Tapajós')
'Juruena'
>>> max_tributaris(gr, 'Jari')
''
>>> max_tributaris(gr, 'Amazones')
'Tapajós'

Nota

Per a resoldre aquest apartat resulta útil fer servir la funció ancestors().

Disposeu de més jocs de proves al fitxer tests-tributaris.txt.