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);
}
}