package org.example; import org.graphstream.graph.Graph; import org.graphstream.graph.Node; import org.graphstream.graph.implementations.SingleGraph; import org.graphstream.stream.file.FileSourceEdge; import org.graphstream.algorithm.Toolkit; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.Random; public class Propagation { public static void main(String[] args) throws Exception { String filePath = "C:/Users/celia/IdeaProjects/TP_RI/com-dblp.ungraph.txt/com-dblp.ungraph.txt"; Graph graph = new SingleGraph("DBLP Collaboration Network"); // --- Chargement des données --- FileSourceEdge fileSource = new FileSourceEdge(); fileSource.addSink(graph); try { fileSource.readAll(filePath); } finally { fileSource.removeSink(graph); } // --- Paramètres --- int daysToSimulate = 90; // 3 months double infectionProbability = 1.0; // β = 1 double recoveryProbability = 0.5; // μ = 0.5 // Tableau pour stocker les résultats des scénarios double[][] results = new double[3][daysToSimulate]; String[] fileNames = {"scenario1_no_control.dat", "scenario2_random_immunization.dat", "scenario3_selective_immunization.dat"}; // --- Scenarios --- System.out.println("Scenario 1: No Control"); results[0] = simulateAndCaptureResults(graph, infectionProbability, recoveryProbability, daysToSimulate, 0, false); System.out.println("Scenario 2: Random Immunization"); results[1] = simulateAndCaptureResults(graph, infectionProbability, recoveryProbability, daysToSimulate, 0.5, true); System.out.println("Scenario 3: Selective Immunization"); results[2] = simulateAndCaptureResults(graph, infectionProbability, recoveryProbability, daysToSimulate, 0.5, false); // Sauvegarde des résultats dans des fichiers saveResultsToFiles(results, fileNames); System.out.println("Les résultats ont été sauvegardés dans les fichiers pour Gnuplot."); // Calculer les degrés moyens des groupes 0 et 1 calculateAverageDegreeSelectiveImmunization(graph); epidemicThresholdAnalysis(graph,infectionProbability,recoveryProbability); } private static void epidemicThresholdAnalysis(Graph graph, double infectionRate, double recoveryRate) { double avgDegree = Toolkit.averageDegree(graph); // Utilisation de Toolkit pour le degré moyen double avgDegreeSquared = calculateSquaredAverageDegree(graph); // Calcul direct du carré moyen des degrés // Calcul des seuils double tau = infectionRate / recoveryRate; // Taux de propagation double cReal = avgDegree / avgDegreeSquared; // Seuil épidémique réel double cTheoretical = 1.0 / (avgDegree + 1); // Seuil théorique pour un réseau aléatoire avec normalisation // Affichage des résultats System.out.println("Taux de propagation (τ) : " + tau); System.out.println("Seuil épidémique réel (c_réel) : " + cReal); System.out.println("Seuil épidémique théorique (c_théorique) : " + cTheoretical); // Prédiction dans le réseau réel if (tau > cReal) { System.out.println("La maladie persiste dans le réseau réel (τ > c_réel).\n"); } else { System.out.println("La maladie disparaît dans le réseau réel (τ < c_réel).\n"); } // Comparaison avec le réseau aléatoire if (cReal < cTheoretical) { System.out.println("Le réseau réel est plus vulnérable que le réseau aléatoire (c_réel < c_théorique).\n"); } else { System.out.println("Le réseau réel est plus résistant que le réseau aléatoire (c_réel >= c_théorique).\n"); } } private static double calculateSquaredAverageDegree(Graph graph) { double totalDegreeSquared = 0; for (Node node : graph) { totalDegreeSquared += Math.pow(node.getDegree(), 2); // Somme des carrés des degrés } return totalDegreeSquared / graph.getNodeCount(); // Moyenne des carrés des degrés } private static void saveResultsToFiles(double[][] results, String[] fileNames) { for (int i = 0; i < results.length; i++) { try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileNames[i]))) { for (int day = 0; day < results[i].length; day++) { writer.write((day + 1) + "\t" + results[i][day]); writer.newLine(); } } catch (IOException e) { System.err.println("Erreur lors de l'écriture dans le fichier : " + fileNames[i]); e.printStackTrace(); } } } private static double[] simulateAndCaptureResults(Graph graph, double infectionRate, double recoveryRate, int days, double immunizationFraction, boolean randomImmunization) { double[] infectedFractions = new double[days]; Random random = new Random(); // Reset states for (Node node : graph) { node.setAttribute("state", "susceptible"); node.removeAttribute("immune"); } // Immunization if (immunizationFraction > 0) { int immunizedCount = (int) (immunizationFraction * graph.getNodeCount()); if (randomImmunization) { // Immunisation aléatoire : immuniser des nœuds directement for (int i = 0; i < immunizedCount; i++) { Node node = graph.getNode(random.nextInt(graph.getNodeCount())); node.setAttribute("immune", true); } } else { // Immunisation sélective : immuniser un voisin for (Node node : graph) { if (random.nextDouble() < immunizationFraction && node.getDegree() > 0) { Node neighbor = node.neighborNodes().toList().get(0); // Prendre un voisin neighbor.setAttribute("immune", true); } } } } // Infect patient zero Node patientZero = graph.getNode(new Random().nextInt(graph.getNodeCount())); patientZero.setAttribute("state", "infected"); // Simulation for (int day = 0; day < days; day++) { int infectedCount = 0; int totalNonImmune = 0; for (Node node : graph) { if (!node.hasAttribute("immune")) { totalNonImmune++; if (node.getAttribute("state").equals("infected")) { infectedCount++; for (Node neighbor : node.neighborNodes().toList()) { if (!neighbor.hasAttribute("immune") && neighbor.getAttribute("state").equals("susceptible") && random.nextDouble() < infectionRate) { neighbor.setAttribute("nextState", "infected"); } } if (random.nextDouble() < recoveryRate) { node.setAttribute("nextState", "susceptible"); } } } } for (Node node : graph) { if (node.hasAttribute("nextState")) { node.setAttribute("state", node.getAttribute("nextState")); node.removeAttribute("nextState"); } } infectedFractions[day] = (double) infectedCount / totalNonImmune; } return infectedFractions; } private static void calculateAverageDegreeSelectiveImmunization(Graph graph) { double totalDegreeGroup0 = 0; // Somme des degrés des nœuds du groupe 0 double totalDegreeGroup1 = 0; // Somme des degrés des nœuds du groupe 1 int countGroup0 = 0; // Nombre de nœuds dans le groupe 0 int countGroup1 = 0; // Nombre de nœuds dans le groupe 1 // Parcourir tous les nœuds pour identifier les groupes for (Node node : graph) { if (node.hasAttribute("selected")) { // Groupe 0 : nœuds choisis aléatoirement totalDegreeGroup0 += node.getDegree(); countGroup0++; // Groupe 1 : voisins immunisés de ces nœuds for (Node neighbor : node.neighborNodes().toList()) { if (neighbor.hasAttribute("immune")) { totalDegreeGroup1 += neighbor.getDegree(); countGroup1++; } } } } // Calcul des degrés moyens double avgDegreeGroup0 = countGroup0 > 0 ? totalDegreeGroup0 / countGroup0 : 0; double avgDegreeGroup1 = countGroup1 > 0 ? totalDegreeGroup1 / countGroup1 : 0; // Afficher les résultats System.out.printf("Degré moyen (Groupe 0 - Nœuds sélectionnés aléatoirement) : %.9f%n", avgDegreeGroup0); System.out.printf("Degré moyen (Groupe 1 - Voisins immunisés) : %.9f%n", avgDegreeGroup1); } }