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;
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 ---
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);
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
// Réseau modifié après immunisation aléatoire
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);
}
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();
// Créer une liste des nœuds pour éviter les modifications concurrentes du graphe
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);
// 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");
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;
totalDegreeSquared += Math.pow(node.getDegree(), 2); // Somme des carrés des degrés
return totalDegreeSquared / graph.getNodeCount(); // Moyenne des carrés des degrés
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
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
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);