Newer
Older
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;
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);
}
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
// Appliquer une immunisation aléatoire (immuniser 50 % des nœuds)
Set<Node> immune = new HashSet<>();
Random random = new Random();
int immuneCount = (int) (0.5 * graph.getNodeCount()); // Immuniser 50 % des nœuds
List<Node> nodes = new ArrayList<>(graph.nodes().toList());
Collections.shuffle(nodes, random);
for (int i = 0; i < immuneCount; i++) {
Node node = nodes.get(i);
node.setAttribute("immune", true); // Marquer comme immunisé
immune.add(node);
}
// Groupes
Set<Node> group0 = new HashSet<>(); // Groupe 0 : 50 % des nœuds non immunisés
Set<Node> group1 = new HashSet<>(); // Groupe 1 : Un voisin immunisé de chaque nœud du Groupe 0
// Sélectionner 50 % des nœuds non immunisés pour le Groupe 0
List<Node> nonImmuneNodes = new ArrayList<>();
for (Node node : graph) {
if (!immune.contains(node)) { // Nœuds non immunisés
nonImmuneNodes.add(node);
}
}
Collections.shuffle(nonImmuneNodes, random); // Mélanger les nœuds non immunisés
int targetCount = (int) (0.5 * nonImmuneNodes.size()); // 50 % des nœuds non immunisés
for (int i = 0; i < targetCount; i++) {
group0.add(nonImmuneNodes.get(i)); // Ajouter au groupe 0
}
// Pour chaque nœud du Groupe 0, ajouter un voisin immunisé au Groupe 1
for (Node node : group0) {
List<Node> neighbors = node.neighborNodes().toList();
for (Node neighbor : neighbors) {
if (immune.contains(neighbor)) { // Vérifier si le voisin est immunisé
group1.add(neighbor); // Ajouter un seul voisin immunisé au groupe 1
break; // Sortir de la boucle après avoir trouvé un voisin immunisé
}
}
}
double infectionProbability = 1.0; // β = 1
double recoveryProbability = 0.5; // μ = 0.5
// Nombre d'itérations pour chaque scénario
int iterations = 10;
// 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"};
// --- Scénarios avec itérations ---
for (int scenario = 0; scenario < 3; scenario++) {
double[] averageFractions = new double[daysToSimulate];
Arrays.fill(averageFractions, 0); // Initialiser à zéro pour chaque scénario
for (int iteration = 0; iteration < iterations; iteration++) {
// Cloner le graphe pour garantir une nouvelle simulation à chaque itération
Graph graphClone = cloneGraph(graph);
// Définir les paramètres spécifiques au scénario
double immunizationFraction = 0;
boolean randomImmunization = false;
if (scenario == 1) { // Immunisation aléatoire
immunizationFraction = 0.5;
randomImmunization = true;
} else if (scenario == 2) { // Immunisation sélective
immunizationFraction = 0.5;
randomImmunization = false;
}
// Exécuter la simulation et capturer les résultats
double[] fractions = simulateAndCaptureResults(graphClone, infectionProbability, recoveryProbability, daysToSimulate, immunizationFraction, randomImmunization);
// Ajouter les résultats de cette itération à la moyenne
for (int day = 0; day < daysToSimulate; day++) {
averageFractions[day] += fractions[day];
}
}
// Diviser par le nombre d'itérations pour obtenir la moyenne
for (int day = 0; day < daysToSimulate; day++) {
averageFractions[day] /= iterations;
}
// Stocker les résultats du scénario
results[scenario] = averageFractions;
// Enregistrer les résultats dans un fichier
writeResultsToFile(fileNames[scenario], averageFractions);
}
epidemicThresholdAnalysis(graph,infectionProbability,recoveryProbability);
// Calcul du degré moyen pour le Groupe 0 (non immunisé)
double totalDegreeGroup0 = 0;
for (Node node : group0) {
totalDegreeGroup0 += node.getDegree();
}
double averageDegreeGroup0 = group0.isEmpty() ? 0 : totalDegreeGroup0 / group0.size();
System.out.printf("Degré moyen (Groupe 0 - Non immunisé) : %.9f%n", averageDegreeGroup0);
// Calcul du degré moyen pour le Groupe 1 (voisins immunisés)
double totalDegreeGroup1 = 0;
for (Node node : group1) {
totalDegreeGroup1 += node.getDegree();
}
double averageDegreeGroup1 = group1.isEmpty() ? 0 : totalDegreeGroup1 / group1.size();
System.out.printf("Degré moyen (Groupe 1 - Voisins immunisés) : %.9f%n", averageDegreeGroup1);
System.out.println("Analyse après immunisation aléatoire :");
Graph randomImmunizedGraph = cloneGraph(graph);
applyRandomImmunization(randomImmunizedGraph, 0.5); // 50% des nœuds immunisés
epidemicThresholdAnalysis(randomImmunizedGraph, infectionProbability, recoveryProbability);
// Réseau modifié après immunisation sélective
System.out.println("Analyse après immunisation sélective :");
Graph selectiveImmunizedGraph = cloneGraph(graph);
applySelectiveImmunization(selectiveImmunizedGraph, 0.5); // 50% des voisins des hubs immunisés
epidemicThresholdAnalysis(selectiveImmunizedGraph, infectionProbability, recoveryProbability);
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
Graph barabasiGraph = DBLPNetworkAnalysis.generateBarabasiAlbertGraph(graph); // Exemple : 3 connexions par nœud
System.out.println("Simulation sur réseau Barabási-Albert :");
runSimulations(barabasiGraph);
}
// --- Méthode pour écrire les résultats dans un fichier ---
private static void writeResultsToFile(String fileName, double[] data) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
for (int day = 0; day < data.length; day++) {
writer.write(day + " " + data[day]);
writer.newLine();
}
} catch (IOException e) {
System.err.println("Erreur lors de l'écriture du fichier : " + e.getMessage());
}
}
private static void runSimulations(Graph graph) {
int daysToSimulate = 90; // 3 mois
double infectionProbability = 1.0; // β = 1
double recoveryProbability = 0.5; // μ = 0.5
// Scénario 1 : Aucune immunisation
System.out.println("Scénario 1 : Aucune immunisation");
simulateAndCaptureResults(graph, infectionProbability, recoveryProbability, daysToSimulate, 0, false);
// Scénario 2 : Immunisation aléatoire
System.out.println("Scénario 2 : Immunisation aléatoire");
applyRandomImmunization(graph, 0.5); // Immunisation aléatoire de 50 %
simulateAndCaptureResults(graph, infectionProbability, recoveryProbability, daysToSimulate, 0, true);
// Scénario 3 : Immunisation sélective
System.out.println("Scénario 3 : Immunisation sélective");
applySelectiveImmunization(graph, 0.5); // Immunisation sélective de 50 %
simulateAndCaptureResults(graph, infectionProbability, recoveryProbability, daysToSimulate, 0, false);
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
230
231
}
private static Graph cloneGraph(Graph original) {
Graph clone = new SingleGraph("Clone");
// Ajouter tous les nœuds au clone
original.nodes().toList().forEach(node -> clone.addNode(node.getId()));
// Ajouter toutes les arêtes au clone
original.edges().toList().forEach(edge -> {
String sourceId = edge.getSourceNode().getId();
String targetId = edge.getTargetNode().getId();
String edgeId = sourceId + "-" + targetId;
if (clone.getEdge(edgeId) == null) {
clone.addEdge(edgeId, sourceId, targetId);
}
});
return clone;
}
private static void applyRandomImmunization(Graph graph, double fraction) {
Random random = new Random();
int immunizedCount = (int) (fraction * graph.getNodeCount());
for (int i = 0; i < immunizedCount; i++) {
Node node = graph.getNode(random.nextInt(graph.getNodeCount()));
if (node != null) {
graph.removeNode(node);
}
}
}
private static void applySelectiveImmunization(Graph graph, double fraction) {
Random random = new Random();
var nodes = graph.nodes().toList();
for (Node node : nodes) {
if (node != null && random.nextDouble() < fraction) {
// Parcourir les voisins et les supprimer
var neighbors = node.neighborNodes().toList();
for (Node neighbor : neighbors) {
if (graph.getNode(neighbor.getId()) != null) { // Vérifier que le voisin existe toujours
graph.removeNode(neighbor.getId());
}
}
}
}
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);
private static double calculateSquaredAverageDegree(Graph graph) {
double totalDegreeSquared = 0;
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 double[] simulateAndCaptureResults(Graph graph, double infectionRate, double recoveryRate, int days, double immunizationFraction, boolean randomImmunization) {
double[] infectedFractions = new double[days];
Random random = new Random();
for (Node node : graph) {
node.setAttribute("state", "susceptible");
node.removeAttribute("immune");
}
// Immunization
if (immunizationFraction > 0) {
int immunizedCount = (int) (immunizationFraction * graph.getNodeCount());
if (randomImmunization) {
// Récupérer tous les nœuds dans une liste
List<Node> allNodes = new ArrayList<>(graph.nodes().toList());
// Mélanger la liste pour une sélection aléatoire unique
Collections.shuffle(allNodes, random);
// Immuniser les premiers `immunizedCount` nœuds
Node node = allNodes.get(i);
if (node != null) {
node.setAttribute("immune", true);
}
// Immunisation sélective : immuniser un voisin pour 50% des nœuds existants
List<Node> nodes = new ArrayList<>( graph.nodes().toList());
// Calculer le nombre de nœuds à immuniser (50% des nœuds existants)
int nodesToImmunize = (int) (immunizationFraction * nodes.size());
// Mélanger les nœuds pour garantir une sélection aléatoire
Collections.shuffle(nodes, random);
// Sélectionner les premiers `nodesToImmunize` nœuds et immuniser un voisin pour chacun
for (int i = 0; i < nodesToImmunize; i++) {
Node node = nodes.get(i);
// Vérifier que le nœud a des voisins
if (node.getDegree() > 0) {
// Prendre un voisin aléatoire
List<Node> neighbors = node.neighborNodes().toList();
Node neighbor = neighbors.get(random.nextInt(neighbors.size()));
// Immuniser ce voisin
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
}
}
// 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;
}