added ex2
This commit is contained in:
parent
70daa208d0
commit
9c6bf54f20
12
README.md
12
README.md
@ -36,7 +36,7 @@ def function1(
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/ex1_.py)
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/Ex1.py)
|
||||
/
|
||||
[Tests](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/tests/test_ex1.py)
|
||||
|
||||
@ -46,7 +46,7 @@ def function1(
|
||||
<table>
|
||||
<tr>
|
||||
<td><strong>But</strong></td>
|
||||
<td></td>
|
||||
<td>...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Input</strong></td>
|
||||
@ -70,7 +70,7 @@ def function2(
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/ex2_.py)
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/Ex2.py)
|
||||
/
|
||||
[Tests](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/tests/test_ex2.py)
|
||||
|
||||
@ -104,7 +104,7 @@ def function3(
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/ex3_.py)
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/Ex3.py)
|
||||
/
|
||||
[Tests](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/tests/test_ex3.py)
|
||||
|
||||
@ -138,7 +138,7 @@ def function4(
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/ex4_.py)
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/Ex4.py)
|
||||
/
|
||||
[Tests](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/tests/test_ex4.py)
|
||||
|
||||
@ -172,6 +172,6 @@ def function5(
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/ex5_.py)
|
||||
[Source](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/src/Ex5.py)
|
||||
/
|
||||
[Tests](https://git.kb28.ch/HEL/AlgoDS-Examen2025/src/branch/main/tests/test_ex5.py)
|
||||
|
95
src/Ex2.py
Normal file
95
src/Ex2.py
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
"""
|
||||
Nom/Prénom: Heredero/Louis
|
||||
Explications:
|
||||
Tout d'abord, le réseau de routes et d'intersections peut être représenté par un graphe,
|
||||
dans lequel les interséctions sont les nœuds et les routes les arêtes.
|
||||
|
||||
Ainsi, nous cherchons à trouver le chemin le plus court du point de départ au
|
||||
point d'arrivée, tel que les routes marquées 1 ne soient parcourues que de jour
|
||||
(c'est-à-dire si leurs index dans le chemin parcouru est pair), et celles marquées -1
|
||||
seulement de nuit (index impair). En plus des routes données, nous pouvons aussi
|
||||
rester sur un même nœud pour une nuit.
|
||||
Afin de bien gérer les différences d'états entre jour et nuit, nous pouvons intégrer le demi-jour
|
||||
associé à chaque visite de nœud. Ainsi, une même intersection peut avoir deux nœud:
|
||||
un pour une visite de jour, et un de nuit.
|
||||
|
||||
Pour résoudre ce problème, comme nous ne pouvons pas établir d'heuristique mesurant
|
||||
notre distance au point d'arrivée, nous pouvons utiliser un algorithme BFS assez simple:
|
||||
- Initialiser la liste des nœuds à traiter avec le nœud de départ et le demi-jour de départ (`DAY`)
|
||||
- Tant que nous n'avons pas trouvé le nœud d'arrivée:
|
||||
- Pour chaque nœud à traiter :
|
||||
- Visiter les nœuds voisins non visités (liés par une route praticable)
|
||||
- Indiquer pour chaque voisin son parent
|
||||
- L'ajouter à la nouvelle liste des nœuds à traiter
|
||||
- Alterner le demi-jour courant
|
||||
- Recommencer avec la nouvelle liste de nœuds à traiter
|
||||
"""
|
||||
from typing import Optional
|
||||
|
||||
ALWAYS = 0
|
||||
DAY = 1
|
||||
NIGHT = -1
|
||||
|
||||
|
||||
def get_path(visited: dict[tuple[int, int], Optional[int]], end: int, end_time: int) -> list[int]:
|
||||
path: list[int] = []
|
||||
parent: Optional[int] = end
|
||||
|
||||
time: int = end_time
|
||||
while parent is not None:
|
||||
path.append(parent)
|
||||
parent = visited[(parent, time)]
|
||||
time = -time
|
||||
|
||||
return list(reversed(path))
|
||||
|
||||
def findSafestPath(start: int, end: int, intersections: list[tuple[int, int, int]]) -> list[int]:
|
||||
edges: dict[int, dict[int, set[int]]] = {
|
||||
ALWAYS: {},
|
||||
DAY: {},
|
||||
NIGHT: {}
|
||||
}
|
||||
|
||||
for i1, i2, mode in intersections:
|
||||
edge_dict: dict[int, set[int]] = edges[mode]
|
||||
if i1 not in edge_dict:
|
||||
edge_dict[i1] = set()
|
||||
if i2 not in edge_dict:
|
||||
edge_dict[i2] = set()
|
||||
edge_dict[i1].add(i2)
|
||||
edge_dict[i2].add(i1)
|
||||
|
||||
visited: dict[tuple[int, int], Optional[int]] = {
|
||||
(start, DAY): None
|
||||
}
|
||||
to_process: list[int] = [start]
|
||||
time = DAY
|
||||
while len(to_process) != 0:
|
||||
to_process2 = []
|
||||
time2 = -time
|
||||
for idx in to_process:
|
||||
always: set[int] = edges[ALWAYS].get(idx, set())
|
||||
matching_time: set[int] = edges[time].get(idx, set())
|
||||
neighbors: set[int] = always | matching_time
|
||||
neighbors.add(idx)
|
||||
|
||||
for neighbor in neighbors:
|
||||
key = (neighbor, time2)
|
||||
# Skip if already visited
|
||||
if key in visited:
|
||||
continue
|
||||
visited[key] = idx
|
||||
if neighbor == end:
|
||||
return get_path(visited, end, time2)
|
||||
to_process2.append(neighbor)
|
||||
|
||||
to_process = to_process2
|
||||
time = time2
|
||||
|
||||
return []
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(findSafestPath(0,2,[(0, 1, -1), (1, 2, 0)]) == [0, 0, 1, 2])
|
||||
print(findSafestPath(0, 5, [(0,1,0), (0,2,1), (2,1,-1), (1,3,-1), (2,4,-1), (3,5,1), (3,4,0), (4,5,-1)]) == [0, 1, 3, 5])
|
@ -1,8 +1,20 @@
|
||||
import unittest
|
||||
|
||||
from Ex2 import findSafestPath
|
||||
|
||||
|
||||
class MyTestCase(unittest.TestCase):
|
||||
def test_simple1(self):
|
||||
pass
|
||||
self.assertEqual(
|
||||
findSafestPath(0, 2, [(0, 1, -1), (1, 2, 0)]),
|
||||
[0, 0, 1, 2]
|
||||
)
|
||||
|
||||
def test_simple2(self):
|
||||
self.assertEqual(
|
||||
findSafestPath(0, 5, [(0,1,0), (0,2,1), (2,1,-1), (1,3,-1), (2,4,-1), (3,5,1), (3,4,0), (4,5,-1)]),
|
||||
[0, 1, 3, 5]
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user