un Grafo(V,E)
V es un conjunto de vértices o nodos, con una relación entre ellos;
E es un conjunto de pares (u,v) donde u,v Є V llamados aristas o arcos.
v es adyacente a u si existe una arista (u,v) Є E.
en un grafo no dirigido, {u,v} Є E incide en los nodos u y v.
en un grafo dirigido, (u,v) Є E incide en v, y parte de u.
v es alcanzable desde u, si existe un camino de u a v.
un camino de u a v, es una secuencia de vértices que comienza en u, termina en v y cada uno de los vértices intermedios es adyacente al anterior
Grafo que no contiene ciclos
Un grafo es conexo si cualquier nodo es alcanzables desde cualquier otro
es decir entre cada dos nodos hay un camino
O (|V| 2 )
Representación es útil para grafos con número de vértices pequeño, o grafos densos (|E|≈|V|×|V|)Comprobar si una arista (u,v) pertenece a E => consultar posición A(u,v)
Representación apropiada para grafos con |E| menor que |V| 2
Desventaja: si se quiere comprobar si una arista (u,v) pertenece a E ⇒ buscar v en la lista de adyacencia de u.
BFS
DFS
Depth First Search o Recorrido en Profundidad
comparemos con el recorrido de árboles
marcar todos los nodos como no visitados
u = un vertice no visitado
3. marcar u como vistado
4. procesar u
5. para cada vertice v adyacente a u:
6. si v no está visitado:
7. ejecutar recursivamente 3,4,5 para v
8. Si quedaron nodos sin visitar:
9. repetir desde 2 con un nuevo vertice no visitado
Breadth First Search o Recorrido en Amplitud
comparemos con el recorrido de árboles
marcar todos los nodos como no visitados
u = un vertice no visitado
encolar u
marcar u como vistado
mientras haya vertices:
desencolo un vertice u
proceso u
para cada nodo v adyacente a u:
si v no está visitado:
encolar v
marcar v como visitado
si quedan nodos sin visitar, tomo uno y vuelvo a empezar
def min_path(G, s):
tabla = inicializar_tabla
c = Cola.new
c.push(s)
tabla[s]['conocido'] = true
while(!q.empty):
v = q.pop()
tabla[v]['conocido'] = true
for u in v.adyacentes():
if ! tabla[u]['conocido']:
tabla[u]['distancia']=tabla[u]['distancia'] + 1
tabla[u]['paso'] = v
q.push(v)
tabla[v]['conocido'] = true
def dijkstra(G, s):
tabla = inicializar_tabla
tabla[s]['distancia'] = 0
for v in G.vertices():
u = buscar_vertice_desconocido_con_menor_distancia
tabla[u]['conocido'] = true
for w in u.adyacentes():
if !tabla[w]['conocido']:
if tabla[w]['dist'] > tabla[u]['dist'] + u.peso(w)
tabla[w]['dist'] = tabla[u]['dist'] + u.peso(w)
tabla[u]['paso'] = u
La actualización de la distancia de los adyacentes w se realiza si:utiliza 2 matrices (D y P) de V x V
D : matriz de costos mínimos
def floyd(G, s):
D = inicializar_matriz_distancias
P = inicializar_matriz_pasos
for k in G.vertices().lenght():
for i in G.vertices().lenght():
for j in G.vertices().lenght():
if D[i,j] > D[i,k] + D[k,j]:
D[i,j] = D[i,k] + D[k,j]
P[i,j] = k