summaryrefslogtreecommitdiff
path: root/ero1/src/demo/demo_exec.py
blob: 1242ff56df3bee060863e84f97f1a734ba1fae7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# DEMO IMPORT
from src.demo.print_demo import print_demo
from src.demo.ask_variable import ask_variable
from src.helper.color_suburbs import display_suburbs_with_colors
from src.demo.demo_cost import export_deneigeuse, export_drone, get_edge_length
from src.demo.demo_stats import stats_deneigeuses, stats_drone
from src.demo.demo_final_report import *  # nsm, flemme de trier

# IMPORT FOR GENERATION
from src.generation.graph_generation import generate_graph
from src.generation.suburb_snowplow_generation import generate_quartiers_from_path

# IMPORT FOR DRONE:
from src.drone.postier_chinoisV2 import final_path, postier_chinois_process_v2, connect_circuits
from src.drone.postier_chinoisV1 import postier_chinois_process_v1
from src.drone.postier_chinoisV3 import postier_chinois_process_v3

# IMPORT FOR DENEIGEUSE:
from src.deneigeuses.hierholzer_v1 import process_hierholzer_v1
from src.deneigeuses.hierholzer_v2 import process_hierholzer_v2
from src.deneigeuses.directed_cpp import oriented_cpt
from src.deneigeuses.drone_path import drone_path
from src.helper.partitions import partition
from src.deneigeuses.hangar_to_deneigeuse import path_hangar_to_deneigeuse, path_deneigeuse_to_hangar

# IMPORT FOR YAML & KML
from src.helper.export_to_kml import export_to_kml
from src.helper.export_import_yaml import load_paths_from_yaml
import os
import time


def demo_exec(place, drone, deneigeuse, debug):
    """
    Fonction principale pour le démarrage de la démo.
    Parameters:
        place : Liste des arrondissements à parcourir.
        drone : Type de drone à utiliser.
        deneigeuse : Type de déneigeuse à utiliser.
        debug : Mode debug activé ou non.
    """

    # ---------------------- INITIALISATION  ---------------------------

    os.system('cls' if os.name == 'nt' else 'clear')
    print_demo("Démarrage du programme sur :", time=True)
    for lieu in place:
        print_demo(lieu, indent=1)
    print("")

    # ---------------------- GENERATION DU GRAPHE  ---------------------------

    print_demo("Génération du graph de Montréal en cours...", time=True)
    graph = generate_graph("Montréal, Québec, Canada", debug_mode=debug)
    print_demo("Graph généré avec succès.", indent=1)

    # ---------------------- PARCOURS - DRONE  ---------------------------

    start_time_drone = time.time()
    if drone == "postier_chinoisV1":
        print_demo("Parcours du drone sur Montréal avec la version 1.", time=True)
        parcours_drone, finalPath = postier_chinois_process_v1(graph, debug)

    elif drone == "postier_chinoisV2":
        print_demo("Parcours du drone sur Montréal avec la version 2.", time=True)
        parcours_drone, finalPath = postier_chinois_process_v2(graph, debug)

    elif drone == "postier_chinoisV3":
        print_demo("Parcours du drone sur Montréal avec la version 3.", time=True)
        parcours_drone, finalPath = postier_chinois_process_v3(graph, debug)
    else:
        print_demo(f"Récupération du parcours de Montréal sur le fichier : {drone}", time=True)
        parcours_drone = load_paths_from_yaml(graph, drone)
        finalPath = final_path(graph, parcours_drone)

    end_time_drone = time.time()
    print_demo("Parcours du drone effectué avec succès.", indent=1)

    # ---------------------- AFFICHAGE DU GRAPHE  ---------------------------

    Q_display = "Voulez-vous afficher le graph du parcours du drone ?"
    A_display = [("Oui", True), ("Non", False)]
    display = ask_variable(Q_display, A_display)
    if display:
        connections = connect_circuits(graph, parcours_drone)
        display_suburbs_with_colors(graph, parcours_drone, connections)

    # ---------------------- RECUPERATION DU PARCOURS DU DRONE  ---------------------------

    parcours_drone_arrondissements = []
    for elt in place:
        if elt in parcours_drone:
            parcours_drone_arrondissements.extend(parcours_drone[elt])
        else:
            raise ValueError(f"{elt} introuvable dans le parcours du drone.")

    # ---------------------- CALCUL DES COUTS - DRONE  ---------------------------

    cost_drone = export_drone(
        graph, end_time_drone-start_time_drone, finalPath)
    stat_drone = stats_drone(cost_drone)

    # ---------------------- CALCUL DU NOMBRE OPTIMAL DE DÉNEIGEUSES  ---------------------------

    if deneigeuse == "naive":
        print_demo("/!\\ L'algorithme de déneigeuse choisi ne dispose pas de la possibilité d'avoir plusieurs déneigeuses.", time=True)
        number_of_deneigeuses = [1]
    else:
        optimal_number_deneigeuses = max(1, round((sum(get_edge_length(
            graph, u, v) for u, v in parcours_drone_arrondissements)) / 200000))

        Q_deneigeuse_number = "Avec quel nombre de déneigeuses voulez-vous comparer les coûts ?"
        A_deneigeuse_number = [
            ("1 déneigeuse", 1), 
            (f"{optimal_number_deneigeuses} déneigeuses - Version Optimale", optimal_number_deneigeuses), 
            (f"{optimal_number_deneigeuses * 2} déneigeuses", optimal_number_deneigeuses * 2), (f"{optimal_number_deneigeuses * 3} déneigeuses", optimal_number_deneigeuses * 3), 
            ("Faire toutes les partitions et comparer les coûts", 0)]
        number_reply = ask_variable(Q_deneigeuse_number, A_deneigeuse_number)
        if number_reply == 0:
            number_of_deneigeuses = [optimal_number_deneigeuses, 1,
                                    optimal_number_deneigeuses * 2, optimal_number_deneigeuses * 3]
        else:
            number_of_deneigeuses = [number_reply]
    print("")

    # ---------------------- GENERATION DU GRAPHE DE PARTITIONS  ---------------------------

    G_partition = generate_quartiers_from_path(
        parcours_drone, graph, suburb_list=place, debug_mode=debug)

    # ---------------------- PARCOURS - DÉNEIGEUSES  ---------------------------

    if deneigeuse == "hierholzer_v1" or deneigeuse == "hierholzer_v2":
        print_demo("Parcours de la déneigeuse à partir de l'algorithme de Hierholzer", time=True)
    elif deneigeuse == "naive":
        print_demo("Parcours de la déneigeuse à partir de l'implémentation naïve", time=True)
    else:
        print_demo("Parcours de la déneigeuse à partir de l'algorithme du Postier Chinois Orienté", time=True)

    cost_deneigeuses = {}
    parcours_deneigeuses = {}
    for i in number_of_deneigeuses:
        cost_deneigeuses[i] = []
        parcours_deneigeuses[i] = []
        
        if i == 1 and (deneigeuse == "naive" or "hierholzer" in deneigeuse):
            temp = []
            for arrondissement in place:
                temp.extend(parcours_drone[arrondissement])
            partitions = [temp]
        else:
            partitions = partition(G_partition, i, debug_mode=debug)

        for part in partitions:
            start_time_deneigeuse = time.time()
            drone_edges = [(u, v) for u, v in part.edges()] if i != 1 else part

            if "hierholzer" in deneigeuse:
                if deneigeuse == "hierholzer_v2":
                    parcours_deneigeuse = process_hierholzer_v2(
                        graph, drone_edges, debug)
                else:
                    parcours_deneigeuse = process_hierholzer_v1(
                        graph, drone_edges, debug)

                start_node = parcours_deneigeuse[0][0]
                parcours_HangarDeneigeuse = path_hangar_to_deneigeuse(
                    graph, start_node)
                end_node = parcours_deneigeuse[-1][1]
                parcours_DeneigeuseHangar = path_deneigeuse_to_hangar(
                    graph, end_node)

                parcours_deneigeuse = parcours_HangarDeneigeuse + parcours_deneigeuse + parcours_DeneigeuseHangar
            if deneigeuse == "oriented_cpt":
                parcours_deneigeuse = oriented_cpt(part, graph, debug)

                start_node = parcours_deneigeuse[0][0]
                parcours_HangarDeneigeuse = path_hangar_to_deneigeuse(graph, start_node)
                end_node = parcours_deneigeuse[-1][1]
                parcours_DeneigeuseHangar = path_deneigeuse_to_hangar(graph, end_node)

                parcours_deneigeuse = parcours_HangarDeneigeuse + parcours_deneigeuse + parcours_DeneigeuseHangar
            if deneigeuse == "naive":
                parcours_deneigeuse = drone_path(drone_edges, graph)

                start_node = parcours_deneigeuse[0][0]
                parcours_HangarDeneigeuse = path_hangar_to_deneigeuse(graph, start_node)
                end_node = parcours_deneigeuse[-1][1]
                parcours_DeneigeuseHangar = path_deneigeuse_to_hangar(graph, end_node)

                parcours_deneigeuse = parcours_HangarDeneigeuse + parcours_deneigeuse + parcours_DeneigeuseHangar

            parcours_deneigeuses[i].append(parcours_deneigeuse)
            end_time_deneigeuse = time.time()

            cost_deneigeuse = export_deneigeuse(
                graph, end_time_deneigeuse-start_time_deneigeuse, parcours_deneigeuse)
            cost_deneigeuses[i].append(cost_deneigeuse)

    stat_déneigeuses = {}
    for i in number_of_deneigeuses:
        stat_déneigeuses[i] = stats_deneigeuses(cost_deneigeuses[i])

    print_demo("Parcours de la déneigeuse effectué avec succès.", indent=1)

    # ---------------------- CALCUL DES STATS - DÉNEIGEUSES  ---------------------------
    
    os.system('cls' if os.name == 'nt' else 'clear')

    print_recap_stat_drone(stat_drone, 0)

    print("")

    print_all_stat(stat_déneigeuses, 0)

    print("")
    print("--------------------")
    print("")

    # ---------------------- EXPORTATION DU PARCOURS EN KML  ---------------------------

    print_demo(
        "Exportation des parcours des déneigeuses avec le parcours du drone au format KML.")
    for i in parcours_deneigeuses:
        print_demo(
            f"{i} déneigeuses - Fichier KML : temp/parcours_{i}_deneigeuses.kml", indent=1)
        export_to_kml(parcours_deneigeuses[i], finalPath, graph, debug, name=f"parcours_{i}_deneigeuses")

    return True