package fr.univ.dblp; import fr.univ.dblp.analysis.*; import fr.univ.dblp.export.ResultsPrinter; import fr.univ.dblp.generators.CopyGenerator; import fr.univ.dblp.generators.NetworkGenerator; import fr.univ.dblp.loader.GraphLoader; import fr.univ.dblp.simulation.*; import org.graphstream.graph.Graph; import java.io.IOException; import java.util.*; /** * Point d'entrée principal pour l'analyse du réseau DBLP. * * Cette classe gère le menu interactif et orchestre l'exécution * des différentes analyses du réseau de collaboration scientifique DBLP. * * @author Hamadou BA * @see Dépôt Git */ public class Main { private static final String DBLP_FILE_PATH = "src/main/resources/snap/com-dblp.ungraph.txt"; private static Graph dblpGraph = null; private static Graph baGraph = null; public static void main(String[] args) { ResultsPrinter.printHeader("TP: ANALYSE DU RÉSEAU DBLP"); ResultsPrinter.printInfo("Mesures de réseaux d'interaction - Collaboration scientifique"); ResultsPrinter.printInfo("Données: DBLP (Digital Bibliography & Library Project)"); System.out.println(); // Chargement initial du graphe DBLP runQuestion1(); if (dblpGraph == null) { ResultsPrinter.printError("Impossible de charger le graphe DBLP!"); ResultsPrinter.printError("Vérifiez que le fichier existe: " + DBLP_FILE_PATH); return; } // Affichage du menu interactif Scanner scanner = new Scanner(System.in); boolean continueRunning = true; while (continueRunning) { displayMenu(); System.out.print("\nVotre choix: "); String choice = scanner.nextLine().trim(); switch (choice) { case "1": runQuestion1(); break; case "2": runQuestion2(); break; case "3": runQuestion3(); break; case "4": runQuestion4(); break; case "5": runQuestion5(); break; case "6": runQuestion6(); break; case "7": runQuestion7(); break; case "8": runAllQuestions(); break; case "9": runPartie2Question1(); break; case "10": runPartie2Question3(); break; case "11": runPartie2Question5(); break; case "12": runPartie2Question6(); break; case "13": runAllPartie2(); break; case "0": continueRunning = false; ResultsPrinter.printInfo("Au revoir!"); break; default: ResultsPrinter.printWarning("Choix invalide! Essayez encore."); } if (continueRunning && !choice.equals("8")) { System.out.println("\nAppuyez sur Entrée pour continuer..."); scanner.nextLine(); } } scanner.close(); } /** * Affiche le menu interactif principal. * * Ce menu permet à l'utilisateur de choisir quelle analyse exécuter * parmi les 7 questions du TP ou d'exécuter toutes les analyses en séquence. */ private static void displayMenu() { System.out.println("\n" + "=".repeat(80)); System.out.println("MENU PRINCIPAL"); System.out.println("=".repeat(80)); System.out.println("PARTIE 1 - Analyse du réseau:"); System.out.println(" 1. Question 1 - Chargement des données"); System.out.println(" 2. Question 2 - Mesures de base"); System.out.println(" 3. Question 3 - Analyse de connexité"); System.out.println(" 4. Question 4 - Distribution des degrés"); System.out.println(" 5. Question 5 - Distance moyenne"); System.out.println(" 6. Question 6 - Comparaison avec générateurs"); System.out.println(" 7. Question 7 - Générateur par copie (BONUS)"); System.out.println(" 8. TOUT EXÉCUTER (Partie 1: Questions 1-7)"); System.out.println("\nPARTIE 2 - Propagation virale:"); System.out.println(" 9. Seuils épidémiques (Questions 1-2)"); System.out.println(" 10. Simulation 3 scénarios (Questions 3-4)"); System.out.println(" 11. Analyse immunisation (Question 5)"); System.out.println(" 12. Comparaison réseaux (Question 6)"); System.out.println(" 13. TOUT EXÉCUTER (Partie 2: Questions 1-6)"); System.out.println("\n 0. Quitter"); System.out.println("=".repeat(80)); } /** * Question 1: Charge les données du réseau DBLP. * * Cette méthode charge le graphe de collaboration DBLP depuis le fichier * de données et affiche les informations de base sur le graphe chargé. */ private static void runQuestion1() { ResultsPrinter.printHeader("QUESTION 1: Chargement des données"); dblpGraph = GraphLoader.loadDBLP(DBLP_FILE_PATH); if (dblpGraph != null) { ResultsPrinter.printSuccess("Graphe DBLP chargé avec succès!"); GraphLoader.displayGraphInfo(dblpGraph); ResultsPrinter.printInfo("\nNote: La visualisation n'est pas recommandée pour ce graphe"); ResultsPrinter.printInfo(" (trop de nœuds: visualisation très lente et peu informative)"); } } /** * Question 2: Calcule et affiche les mesures de base du réseau. * * Cette méthode calcule le nombre de nœuds, d'arêtes, le degré moyen * et le coefficient de clustering du réseau DBLP. */ private static void runQuestion2() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } BasicMetrics.analyze(dblpGraph, "DBLP"); } /** * Question 3: Analyse la connexité du réseau. * * Cette méthode vérifie si le réseau est connexe, compte le nombre de * composantes connexes et détermine le degré critique pour la connexité. */ private static void runQuestion3() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } ConnectivityAnalyzer.analyze(dblpGraph); } /** * Question 4: Analyse la distribution des degrés du réseau. * * Cette méthode calcule la distribution des degrés, l'exporte pour * visualisation avec gnuplot et vérifie si elle suit une loi de puissance. */ private static void runQuestion4() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } DegreeAnalyzer.analyze(dblpGraph, "DBLP", "dblp"); ResultsPrinter.printInfo("\nPour générer les graphiques avec gnuplot:"); ResultsPrinter.printInfo(" cd gnuplot"); ResultsPrinter.printInfo(" gnuplot plot_dd_linear.gnu"); ResultsPrinter.printInfo(" gnuplot plot_dd_loglog.gnu"); ResultsPrinter.printInfo(" gnuplot plot_dd_powerlaw.gnu"); } /** * Question 5: Calcule la distance moyenne du réseau. * * Cette méthode effectue un échantillonnage de 1000 nœuds et calcule * la distance moyenne par parcours BFS. Attention: opération longue (15-25 min). */ private static void runQuestion5() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } ResultsPrinter.printWarning("ATTENTION: Cette analyse peut prendre 15-25 minutes!"); ResultsPrinter.printInfo("(1000 parcours BFS sur un graphe de 317k nœuds)"); System.out.print("\nContinuer? (o/n): "); Scanner scanner = new Scanner(System.in); String response = scanner.nextLine().trim().toLowerCase(); if (response.equals("o") || response.equals("oui") || response.equals("y") || response.equals("yes")) { DistanceAnalyzer.analyze(dblpGraph, "DBLP", "dblp"); ResultsPrinter.printInfo("\nPour générer le graphique avec gnuplot:"); ResultsPrinter.printInfo(" cd gnuplot && gnuplot plot_distances.gnu"); } else { ResultsPrinter.printInfo("Analyse annulée."); } } /** * Question 6: Compare le réseau DBLP avec des générateurs de réseaux. * * Cette méthode génère un réseau aléatoire (Erdős-Rényi) et un réseau * Barabási-Albert, puis compare leurs propriétés avec DBLP. Durée: 30-40 min. */ private static void runQuestion6() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } ResultsPrinter.printWarning("ATTENTION: Cette analyse peut prendre 30-40 minutes!"); ResultsPrinter.printInfo("(Génération et analyse de 2 grands réseaux)"); System.out.print("\nContinuer? (o/n): "); Scanner scanner = new Scanner(System.in); String response = scanner.nextLine().trim().toLowerCase(); if (response.equals("o") || response.equals("oui") || response.equals("y") || response.equals("yes")) { NetworkGenerator.analyze(dblpGraph); ResultsPrinter.printInfo("\nPour générer le graphique comparatif:"); ResultsPrinter.printInfo(" cd gnuplot && gnuplot plot_comparison_networks.gnu"); } else { ResultsPrinter.printInfo("Analyse annulée."); } } /** * Question 7 (BONUS): Teste le générateur par copie. * * Cette méthode génère un réseau avec le mécanisme de copie et compare * son clustering avec DBLP et Barabási-Albert. Durée: 15-20 min. */ private static void runQuestion7() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } // Génération du graphe BA si nécessaire pour la comparaison if (baGraph == null) { ResultsPrinter.printInfo("Génération du graphe Barabási-Albert pour comparaison..."); int n = Math.min(dblpGraph.getNodeCount(), 50000); double avgDegree = BasicMetrics.getAverageDegree(dblpGraph); int edgesPerNode = (int) Math.round(avgDegree / 2.0); baGraph = NetworkGenerator.generateBarabasiAlbert(n, Math.max(1, edgesPerNode)); } ResultsPrinter.printWarning("ATTENTION: Cette analyse peut prendre 15-20 minutes!"); System.out.print("\nContinuer? (o/n): "); Scanner scanner = new Scanner(System.in); String response = scanner.nextLine().trim().toLowerCase(); if (response.equals("o") || response.equals("oui") || response.equals("y") || response.equals("yes")) { CopyGenerator.analyze(dblpGraph, baGraph); } else { ResultsPrinter.printInfo("Analyse annulée."); } } /** * Exécute toutes les questions en séquence. * * Cette méthode lance l'exécution automatique de toutes les analyses * (Questions 1 à 7) sans interruption. Durée totale: environ 1h30. */ private static void runAllQuestions() { ResultsPrinter.printHeader("EXÉCUTION COMPLÈTE - TOUTES LES QUESTIONS"); ResultsPrinter.printWarning("ATTENTION: L'exécution complète peut prendre 1h30 à 2h!"); ResultsPrinter.printInfo("Les questions longues (Q5, Q6, Q7) seront exécutées automatiquement."); System.out.print("\nVoulez-vous vraiment tout exécuter? (o/n): "); Scanner scanner = new Scanner(System.in); String response = scanner.nextLine().trim().toLowerCase(); if (!response.equals("o") && !response.equals("oui") && !response.equals("y") && !response.equals("yes")) { ResultsPrinter.printInfo("Exécution annulée."); return; } long globalStart = System.currentTimeMillis(); // Question 1: Chargement if (dblpGraph == null) { runQuestion1(); } // Question 2: Mesures de base if (dblpGraph != null) { runQuestion2(); } // Question 3: Connexité if (dblpGraph != null) { runQuestion3(); } // Question 4: Distribution des degrés if (dblpGraph != null) { runQuestion4(); } // Question 5: Distance moyenne if (dblpGraph != null) { ResultsPrinter.printInfo("\n>>> Démarrage Question 5 (Distance moyenne)..."); DistanceAnalyzer.analyze(dblpGraph, "DBLP", "dblp"); } // Question 6: Comparaison avec générateurs if (dblpGraph != null) { ResultsPrinter.printInfo("\n>>> Démarrage Question 6 (Générateurs)..."); NetworkGenerator.analyze(dblpGraph); } // Question 7: Générateur par copie (BONUS) if (dblpGraph != null) { ResultsPrinter.printInfo("\n>>> Démarrage Question 7 (Générateur copie - BONUS)..."); // Génération du graphe BA si nécessaire if (baGraph == null) { int n = Math.min(dblpGraph.getNodeCount(), 50000); double avgDegree = BasicMetrics.getAverageDegree(dblpGraph); int edgesPerNode = (int) Math.round(avgDegree / 2.0); baGraph = NetworkGenerator.generateBarabasiAlbert(n, Math.max(1, edgesPerNode)); } CopyGenerator.analyze(dblpGraph, baGraph); } ResultsPrinter.printHeader("TOUTES LES ANALYSES TERMINÉES!"); ResultsPrinter.printElapsedTime(globalStart); ResultsPrinter.printInfo("\nPROCHAINES ÉTAPES:"); ResultsPrinter.printInfo(" 1. Générez les graphiques avec gnuplot (voir gnuplot/*.gnu)"); ResultsPrinter.printInfo(" 2. Consultez les fichiers de données dans output/data/"); ResultsPrinter.printInfo(" 3. Rédigez le rapport README.md avec les résultats et graphiques"); } // ============================================================================ // PARTIE 2 - PROPAGATION VIRALE // ============================================================================ /** * Partie 2 - Questions 1-2: Calcul des seuils épidémiques */ private static void runPartie2Question1() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } ResultsPrinter.printHeader("PARTIE 2 - QUESTIONS 1-2: Seuils épidémiques"); long startTime = System.currentTimeMillis(); // Paramètres du modèle double beta = ViralSimulator.DEFAULT_TRANSMISSION_RATE; double gamma = ViralSimulator.DEFAULT_RECOVERY_RATE; double r0 = EpidemicAnalyzer.calculateR0(beta, gamma); ResultsPrinter.printInfo("PARAMÈTRES DU MODÈLE:"); ResultsPrinter.printMetric("β (transmission)", String.format("%.4f par jour (1 mail/semaine)", beta)); ResultsPrinter.printMetric("γ (récupération)", String.format("%.4f par jour (2 màj/mois)", gamma)); ResultsPrinter.printMetric("R0 (taux reproduction)", String.format("%.4f", r0)); // Seuil épidémique du réseau DBLP double threshold = EpidemicAnalyzer.calculateEpidemicThreshold(dblpGraph); ResultsPrinter.printInfo("\nSEUIL ÉPIDÉMIQUE DU RÉSEAU DBLP:"); ResultsPrinter.printMetric("τ (seuil épidémique)", String.format("%.4f", threshold)); boolean epidemic = EpidemicAnalyzer.isEpidemicPossible(r0, threshold); ResultsPrinter.printMetric("Épidémie possible?", epidemic ? "OUI (R0 > τ)" : "NON (R0 ≤ τ)"); // Seuil théorique pour un réseau aléatoire double avgDegree = BasicMetrics.getAverageDegree(dblpGraph); double theoreticalThreshold = EpidemicAnalyzer.theoreticalRandomThreshold(avgDegree); ResultsPrinter.printInfo("\nCOMPARAISON AVEC RÉSEAU ALÉATOIRE:"); ResultsPrinter.printMetric("Degré moyen ", String.format("%.2f", avgDegree)); ResultsPrinter.printMetric("τ théorique (aléatoire)", String.format("%.4f", theoreticalThreshold)); ResultsPrinter.printMetric("τ réel (DBLP)", String.format("%.4f", threshold)); ResultsPrinter.printMetric("Ratio (DBLP/aléatoire)", String.format("%.2fx", threshold / theoreticalThreshold)); // Variance des degrés double variance = EpidemicAnalyzer.getDegreeVariance(dblpGraph); ResultsPrinter.printInfo("\nHÉTÉROGÉNÉITÉ DU RÉSEAU:"); ResultsPrinter.printMetric("Variance des degrés", String.format("%.2f", variance)); ResultsPrinter.printMetric("Écart-type", String.format("%.2f", Math.sqrt(variance))); ResultsPrinter.printInfo("\nINTERPRÉTATION:"); if (threshold > theoreticalThreshold) { ResultsPrinter.printInfo(" Le seuil épidémique est PLUS ÉLEVÉ que celui d'un réseau aléatoire"); ResultsPrinter.printInfo(" → Structure hétérogène avec hubs (loi de puissance)"); ResultsPrinter.printInfo(" → Plus difficile de déclencher une épidémie"); } else { ResultsPrinter.printInfo(" Le seuil épidémique est PLUS BAS que celui d'un réseau aléatoire"); } if (epidemic) { ResultsPrinter.printWarning("\n⚠ ATTENTION: Avec R0=" + String.format("%.2f", r0) + " > τ=" + String.format("%.2f", threshold) + ", l'épidémie VA SE PROPAGER!"); } ResultsPrinter.printElapsedTime(startTime); } /** * Partie 2 - Questions 3-4: Simulation des 3 scénarios */ private static void runPartie2Question3() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } ResultsPrinter.printHeader("PARTIE 2 - QUESTIONS 3-4: Simulation 3 scénarios"); ResultsPrinter.printWarning("Cette simulation peut prendre 5-10 minutes"); ResultsPrinter.printInfo("(10 runs × 3 scénarios × 90 jours sur graphe de 317k nœuds)"); System.out.print("\nContinuer? (o/n): "); Scanner scanner = new Scanner(System.in); String response = scanner.nextLine().trim().toLowerCase(); if (!response.equals("o") && !response.equals("oui") && !response.equals("y") && !response.equals("yes")) { ResultsPrinter.printInfo("Simulation annulée."); return; } long startTime = System.currentTimeMillis(); int numRuns = 10; int simulationDays = 90; List results = new ArrayList<>(); // Scénario 0: Aucune intervention ResultsPrinter.printInfo("\n>>> Scénario 0: Aucune intervention"); Set noImmune = ImmunizationStrategy.noImmunization(dblpGraph); ViralSimulator sim0 = new ViralSimulator(dblpGraph, noImmune); SimulationResult result0 = sim0.simulateMultipleRuns(numRuns, simulationDays, "Scenario_0_Aucune_intervention"); results.add(result0); ResultsPrinter.printMetric("Pic d'infection", result0.getPeakInfection() + " nœuds (jour " + result0.getPeakDay() + ")"); // Scénario 1: 50% immunisation aléatoire ResultsPrinter.printInfo("\n>>> Scénario 1: 50% immunisation aléatoire"); Set randomImmune = ImmunizationStrategy.randomImmunization(dblpGraph, 0.5); ViralSimulator sim1 = new ViralSimulator(dblpGraph, randomImmune); SimulationResult result1 = sim1.simulateMultipleRuns(numRuns, simulationDays, "Scenario_1_Immunisation_aleatoire"); results.add(result1); ResultsPrinter.printMetric("Nœuds immunisés", randomImmune.size()); ResultsPrinter.printMetric("Pic d'infection", result1.getPeakInfection() + " nœuds (jour " + result1.getPeakDay() + ")"); // Scénario 2: 50% immunisation sélective (acquaintance) ResultsPrinter.printInfo("\n>>> Scénario 2: 50% immunisation sélective (acquaintance)"); Set acquaintanceImmune = ImmunizationStrategy.acquaintanceImmunization(dblpGraph, 0.5); ViralSimulator sim2 = new ViralSimulator(dblpGraph, acquaintanceImmune); SimulationResult result2 = sim2.simulateMultipleRuns(numRuns, simulationDays, "Scenario_2_Immunisation_selective"); results.add(result2); ResultsPrinter.printMetric("Nœuds immunisés", acquaintanceImmune.size()); ResultsPrinter.printMetric("Pic d'infection", result2.getPeakInfection() + " nœuds (jour " + result2.getPeakDay() + ")"); // Export des résultats ResultsPrinter.printInfo("\n>>> Export des données"); try { for (SimulationResult result : results) { String filename = "output/data/partie2_" + result.getScenario() + ".dat"; SimulationExporter.exportSimulationResult(result, filename); ResultsPrinter.printSuccess("Exporté: " + filename); } SimulationExporter.exportScenarioComparison(results, "output/data/partie2_scenarios_comparison.dat"); ResultsPrinter.printSuccess("Exporté: output/data/partie2_scenarios_comparison.dat"); SimulationExporter.exportSummary(results, "output/data/partie2_scenarios_summary.dat"); ResultsPrinter.printSuccess("Exporté: output/data/partie2_scenarios_summary.dat"); } catch (IOException e) { ResultsPrinter.printError("Erreur lors de l'export: " + e.getMessage()); } // Comparaison des résultats ResultsPrinter.printInfo("\nCOMPARAISON DES SCÉNARIOS:"); ResultsPrinter.printInfo(String.format("%-30s %15s %15s", "Scénario", "Pic infection", "Jour pic")); ResultsPrinter.printInfo("-".repeat(60)); for (SimulationResult result : results) { ResultsPrinter.printInfo(String.format("%-30s %15d %15d", result.getScenario(), result.getPeakInfection(), result.getPeakDay())); } ResultsPrinter.printElapsedTime(startTime); ResultsPrinter.printInfo("\nPour visualiser les résultats:"); ResultsPrinter.printInfo(" cd gnuplot && gnuplot plot_epidemic_scenarios.gnu"); } /** * Partie 2 - Question 5: Analyse de l'immunisation */ private static void runPartie2Question5() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } ResultsPrinter.printHeader("PARTIE 2 - QUESTION 5: Analyse immunisation"); long startTime = System.currentTimeMillis(); // Immunisation aléatoire 50% Set randomImmune = ImmunizationStrategy.randomImmunization(dblpGraph, 0.5); Set randomNonImmune = new HashSet<>(); dblpGraph.nodes().forEach(node -> { if (!randomImmune.contains(node.getId())) { randomNonImmune.add(node.getId()); } }); // Immunisation sélective 50% Set acquaintanceImmune = ImmunizationStrategy.acquaintanceImmunization(dblpGraph, 0.5); Set acquaintanceNonImmune = new HashSet<>(); dblpGraph.nodes().forEach(node -> { if (!acquaintanceImmune.contains(node.getId())) { acquaintanceNonImmune.add(node.getId()); } }); // Calcul des degrés moyens double randomNonImmuneDegree = ImmunizationStrategy.getAverageDegree(dblpGraph, randomNonImmune); double acquaintanceNonImmuneDegree = ImmunizationStrategy.getAverageDegree(dblpGraph, acquaintanceNonImmune); double randomImmuneDegree = ImmunizationStrategy.getAverageDegree(dblpGraph, randomImmune); double acquaintanceImmuneDegree = ImmunizationStrategy.getAverageDegree(dblpGraph, acquaintanceImmune); ResultsPrinter.printInfo("DEGRÉ MOYEN DES GROUPES:"); ResultsPrinter.printInfo("\nImmunisation aléatoire:"); ResultsPrinter.printMetric("Degré moyen immunisés", String.format("%.2f", randomImmuneDegree)); ResultsPrinter.printMetric("Degré moyen non-immunisés", String.format("%.2f", randomNonImmuneDegree)); ResultsPrinter.printInfo("\nImmunisation sélective (acquaintance):"); ResultsPrinter.printMetric("Degré moyen immunisés", String.format("%.2f", acquaintanceImmuneDegree)); ResultsPrinter.printMetric("Degré moyen non-immunisés", String.format("%.2f", acquaintanceNonImmuneDegree)); ResultsPrinter.printInfo("\nCOMPARAISON:"); ResultsPrinter.printMetric("Ratio (selective/random) immunisés", String.format("%.2fx", acquaintanceImmuneDegree / randomImmuneDegree)); ResultsPrinter.printMetric("Ratio (selective/random) non-immunisés", String.format("%.2fx", acquaintanceNonImmuneDegree / randomNonImmuneDegree)); // Seuils épidémiques après immunisation double thresholdOriginal = EpidemicAnalyzer.calculateEpidemicThreshold(dblpGraph); double thresholdRandom = EpidemicAnalyzer.calculateThresholdAfterImmunization(dblpGraph, randomImmune); double thresholdAcquaintance = EpidemicAnalyzer.calculateThresholdAfterImmunization(dblpGraph, acquaintanceImmune); ResultsPrinter.printInfo("\nSEUILS ÉPIDÉMIQUES:"); ResultsPrinter.printMetric("τ original", String.format("%.4f", thresholdOriginal)); ResultsPrinter.printMetric("τ après immunisation aléatoire", String.format("%.4f", thresholdRandom)); ResultsPrinter.printMetric("τ après immunisation sélective", String.format("%.4f", thresholdAcquaintance)); ResultsPrinter.printInfo("\nINTERPRÉTATION:"); ResultsPrinter.printInfo(" L'immunisation sélective cible préférentiellement les HUBS"); ResultsPrinter.printInfo(" → Les nœuds immunisés ont un degré PLUS ÉLEVÉ"); ResultsPrinter.printInfo(" → Les nœuds non-immunisés ont un degré PLUS BAS"); ResultsPrinter.printInfo(" → Le seuil épidémique AUGMENTE davantage"); ResultsPrinter.printInfo(" → Stratégie PLUS EFFICACE pour bloquer l'épidémie"); ResultsPrinter.printElapsedTime(startTime); } /** * Partie 2 - Question 6: Comparaison avec différents réseaux */ private static void runPartie2Question6() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } ResultsPrinter.printHeader("PARTIE 2 - QUESTION 6: Comparaison réseaux"); ResultsPrinter.printWarning("Cette simulation peut prendre 15-20 minutes"); ResultsPrinter.printInfo("(Génération réseaux + simulations × 3 réseaux × 3 scénarios)"); System.out.print("\nContinuer? (o/n): "); Scanner scanner = new Scanner(System.in); String response = scanner.nextLine().trim().toLowerCase(); if (!response.equals("o") && !response.equals("oui") && !response.equals("y") && !response.equals("yes")) { ResultsPrinter.printInfo("Simulation annulée."); return; } long startTime = System.currentTimeMillis(); // Paramètres pour les réseaux générés int n = Math.min(50000, dblpGraph.getNodeCount()); // Limiter pour performance double avgDegree = BasicMetrics.getAverageDegree(dblpGraph); int edgesPerNode = Math.max(1, (int) Math.round(avgDegree / 2.0)); // Génération réseau aléatoire ResultsPrinter.printInfo("\n>>> Génération réseau aléatoire"); Graph randomGraph = NetworkGenerator.generateRandomGraph(n, avgDegree); ResultsPrinter.printSuccess("Réseau aléatoire généré: " + n + " nœuds, degré moyen " + String.format("%.2f", BasicMetrics.getAverageDegree(randomGraph))); // Génération réseau Barabási-Albert ResultsPrinter.printInfo("\n>>> Génération réseau Barabási-Albert"); Graph baGraph = NetworkGenerator.generateBarabasiAlbert(n, edgesPerNode); ResultsPrinter.printSuccess("Réseau BA généré: " + n + " nœuds, degré moyen " + String.format("%.2f", BasicMetrics.getAverageDegree(baGraph))); // Simulations sur chaque réseau (scénario 0 uniquement pour comparaison) int numRuns = 5; int simulationDays = 90; ResultsPrinter.printInfo("\n>>> Simulation sur réseau DBLP (échantillon)"); // Utiliser un sous-graphe de DBLP pour comparaison équitable Graph dblpSample = dblpGraph; // TODO: échantillonner si nécessaire ViralSimulator simDBLP = new ViralSimulator(dblpSample); SimulationResult resultDBLP = simDBLP.simulateMultipleRuns(numRuns, simulationDays, "DBLP"); ResultsPrinter.printInfo("\n>>> Simulation sur réseau aléatoire"); ViralSimulator simRandom = new ViralSimulator(randomGraph); SimulationResult resultRandom = simRandom.simulateMultipleRuns(numRuns, simulationDays, "Random"); ResultsPrinter.printInfo("\n>>> Simulation sur réseau Barabási-Albert"); ViralSimulator simBA = new ViralSimulator(baGraph); SimulationResult resultBA = simBA.simulateMultipleRuns(numRuns, simulationDays, "Barabasi_Albert"); // Export ResultsPrinter.printInfo("\n>>> Export des données"); try { List networkNames = Arrays.asList("DBLP", "Random", "Barabasi_Albert"); List results = Arrays.asList(resultDBLP, resultRandom, resultBA); SimulationExporter.exportNetworkComparison(networkNames, results, "output/data/partie2_networks_comparison.dat"); ResultsPrinter.printSuccess("Exporté: output/data/partie2_networks_comparison.dat"); } catch (IOException e) { ResultsPrinter.printError("Erreur lors de l'export: " + e.getMessage()); } // Comparaison ResultsPrinter.printInfo("\nCOMPARAISON DES RÉSEAUX:"); ResultsPrinter.printInfo(String.format("%-20s %15s %15s %15s", "Réseau", "Clustering", "Pic infection", "Jour pic")); ResultsPrinter.printInfo("-".repeat(70)); ResultsPrinter.printInfo(String.format("%-20s %15.4f %15d %15d", "DBLP", BasicMetrics.getClusteringCoefficient(dblpSample), resultDBLP.getPeakInfection(), resultDBLP.getPeakDay())); ResultsPrinter.printInfo(String.format("%-20s %15.4f %15d %15d", "Aléatoire", BasicMetrics.getClusteringCoefficient(randomGraph), resultRandom.getPeakInfection(), resultRandom.getPeakDay())); ResultsPrinter.printInfo(String.format("%-20s %15.4f %15d %15d", "Barabási-Albert", BasicMetrics.getClusteringCoefficient(baGraph), resultBA.getPeakInfection(), resultBA.getPeakDay())); ResultsPrinter.printElapsedTime(startTime); ResultsPrinter.printInfo("\nPour visualiser les résultats:"); ResultsPrinter.printInfo(" cd gnuplot && gnuplot plot_epidemic_networks.gnu"); } /** * Exécute toute la partie 2 en séquence */ private static void runAllPartie2() { if (dblpGraph == null) { ResultsPrinter.printError("Chargez d'abord le graphe (Question 1)!"); return; } ResultsPrinter.printHeader("EXÉCUTION COMPLÈTE - PARTIE 2"); ResultsPrinter.printWarning("ATTENTION: L'exécution complète peut prendre 30-45 minutes!"); System.out.print("\nVoulez-vous vraiment tout exécuter? (o/n): "); Scanner scanner = new Scanner(System.in); String response = scanner.nextLine().trim().toLowerCase(); if (!response.equals("o") && !response.equals("oui") && !response.equals("y") && !response.equals("yes")) { ResultsPrinter.printInfo("Exécution annulée."); return; } long globalStart = System.currentTimeMillis(); runPartie2Question1(); System.out.println("\nAppuyez sur Entrée pour continuer..."); scanner.nextLine(); runPartie2Question3(); System.out.println("\nAppuyez sur Entrée pour continuer..."); scanner.nextLine(); runPartie2Question5(); System.out.println("\nAppuyez sur Entrée pour continuer..."); scanner.nextLine(); runPartie2Question6(); ResultsPrinter.printHeader("PARTIE 2 TERMINÉE!"); ResultsPrinter.printElapsedTime(globalStart); } }