# TP1, OLA : graphes
## Exercice 1
Pour la suite, pour écrire des fonctions génériques, il sera utile de savoir si un graphe donné est représenté comme un matrice ou comme une liste.
```python
def check_type(g):
if g == []:
return "mat"
elif g[0] == []:
return "list"
elif type(g[0][0]) == bool:
return "mat"
else:
return "list"
```
```python
# Question 2
def compte_sommets(g):
return len(g)
def compte_aretes(g):
res = 0
if check_type(g) == "mat":
for ligne in g:
for coeff in ligne:
if coeff:
res += 1
else:
for sommet in g:
res += len(sommet)
return res
# Question 3
def adjacents(g, i, j):
res = False
if check_type(g) == "mat":
res = g[i][j]
else:
res = j in g[i]
return res
# Question 4
def successeurs(g,s) :
res = []
if check_type(g) == "mat" :
for i, test in enumerate(g[s]) :
if test == True :
res.append(i)
return res
else:
return g[s]
# Question 5
def predecesseurs(g, s):
res = []
if check_type(g) == "mat":
for i in range(len(g)):
if g[i][s] == True :
res.append(i)
else:
for i in range(len(g)):
if s in g[i]:
res.append(i)
return res
# Question 6
def reflexif(g):
res = True
for k in range(compte_sommets(g)):
if not adjacents(g, k, k):
return False
return res
# Question 7
def symetrique (g) :
bol = True
n = compte_sommets(g)
for i in range(n):
for j in range(n):
if adjacents(g, i, j) != adjacents(g, j, i) :
bol = False
return bol
# Question 8
def symetrisation(g):
n = compte_sommets(g)
if check_type(g) == "mat":
res = [[False for k in range(n)] for j in range(n)]
for i in range(n):
for j in range(n):
res[i][j] = g[i][j] or g[j][i]
else:
res = [sommet.copy() for sommet in g]
for i, sommet in enumerate(g):
for adjacent in sommet:
if i not in g[adjacent]:
res[adjacent].append(i)
return res
def l_to_m(list_adj):
n = compte_sommets(list_adj)
res = [[False for k in range(n)] for j in range(n)]
for i, sommet in enumerate(list_adj):
for adjacent in sommet:
print(i, adjacent)
res[i][adjacent] = True
return res
```
## Exercice 2 : Chemins et longueurs
### Question 1
```python
mat_adj_pond = [[None, 1 , 1 , None, 1 , None, None, None],
[None, None, None, 2 , None, 2 , None, None],
[None, None, None, -3 , None, None, -3 , None],
[None, None, None, None, None, None, None, 4 ],
[None, None, None, None, None, -5 , -5 , None],
[None, None, None, None, None, None, None, 6 ],
[None, None, None, None, None, None, None, 7 ],
[None, None, None, None, None, None, None, None]]
# Question 1-a
def verifie_chemin(g, c):
n = compte_sommets(g)
for i, s in enumerate(c[:-1]):
if not 0 <= s and s < n:
print("Un des sommets n'est pas dans le graphe")
return False
if g[s][c[i+1]] is None:
print("Une des arêtes n'est pas dans le graphe")
return False
return True
# verifie_chemin(mat_adj_pond, [0,1,3])
# Question 1-b
def longueur(g, c):
if not verifie_chemin(g, c):
return None
res = 0
for i, s in enumerate(c[:-1]):
res += g[s][c[i+1]]
return res
# longueur(mat_adj_pond, [0,1,3])
```
### Question 2
a) Il faut rajouter des zeros sur la diagonale pour prendre en compte les chemins à un seul sommet.
b) cf https://fr.wikipedia.org/wiki/Algorithme_de_Floyd-Warshall
```python
# Question 2-c
def dist_min(a, b):
if a is None:
return b
elif b is None:
return a
else:
return min(a, b)
def floyd_warshall(g):
n = len(g)
C = [[[0 for j in range(n)] for i in range(n)] for k in range(n+1)]
C[0] = g
for i in range(len(g)):
C[0][i][i] = 0
for k in range(n):
for i in range(n):
for j in range(n):
C[k+1][i][j] = dist_min(C[k][i][j],
dist_add(C[k][i][k], C[k][k][j]))
return C[n]
```
## Exercice 3 : Coloration de graphe
```python
# Question 1
def totale(c):
for s in c:
if s is None:
return False
return True
# totale([1,0])
# totale([1,None])
# Question 2
def verifie_coloration(g, c):
n = compte_sommets(g)
for s1 in range(n):
for s2 in range(n):
if adjacents(g, s1, s2):
if c[s1] == c[s2]:
return False
return True
# verifie_coloration(list_symm, [0,1])
# verifie_coloration(list_symm, [0,0])
# Question 3
def couleur_minimale(l, c):
utilisees = {c[s] for s in l if c[s] is not None}
return(min(k for k in range(len(c)) if k not in utilisees))
# couleur_minimale([2,1],[None, 1, 0, 3, None])
# Question 4
def coloriage_glouton(g):
coloration = [None for k in range(compte_sommets(g))]
for s in range(compte_sommets(g)):
adjacents = predecesseurs(g,s) + successeurs(g,s)
coloration[s] = couleur_minimale(adjacents, coloration)
return coloration, len(set(coloration))
# coloriage_glouton(list_adj)
```