"data/git@forgeb1.univ-lehavre.fr:acjj/fullstack-lab.git" n'existait pas sur "b39552330bf158c4985c1dd45b15ca87a5654c18"
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 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é
}
}
}
// 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);
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
epidemicThresholdAnalysis(graph,infectionProbability,recoveryProbability);
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);
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
}
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
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();
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 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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
}
}
// 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;
}
public static void calculateAverageDegrees(Graph graph, Set<Node> immune) {
// Groupes 0 (non immunisés) et 1 (immunisés)
Set<Node> group0 = new HashSet<>();
Set<Node> group1 = immune; // Groupe 1 est directement le set 'immune' (les nœuds immunisés)
// Ajouter 50 % des nœuds au groupe 0
Random random = new Random();
List<Node> nodes = new ArrayList<>();
for (Node node : graph) {
nodes.add(node);
}
Collections.shuffle(nodes); // Mélanger les nœuds pour une sélection aléatoire
int targetConvincers = graph.getNodeCount() / 2; // 50 % des nœuds
for (int i = 0; i < targetConvincers; i++) {
group0.add(nodes.get(i)); // Ajouter au groupe 0
}
// 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.println("Degré moyen du groupe 0 (non immunisé) : " + averageDegreeGroup0);
// Calcul du degré moyen pour le groupe 1 (immunisé)
double totalDegreeGroup1 = 0;
for (Node node : group1) {
totalDegreeGroup1 += node.getDegree();
double averageDegreeGroup1 = group1.isEmpty() ? 0 : totalDegreeGroup1 / group1.size();
System.out.println("Degré moyen du groupe 1 (immunisé) : " + averageDegreeGroup1);
}