package tpri;

import org.graphstream.algorithm.Toolkit;
import org.graphstream.graph.Graph;
import org.graphstream.graph.implementations.DefaultGraph;
import org.graphstream.stream.file.FileSource;
import org.graphstream.stream.file.FileSourceEdge;
import java.io.IOException;

/**
 * Classe simulant l'analyse de la propagation d'un virus sur le réseau DBLP.
 * Étudie la différence entre un réseau aléatoire et un réseau réel (Scale-free).
 */
public class TauxPropagation {

    public static void main(String[] args) {
        System.out.println("--- ÉTUDE DE LA PROPAGATION (TP2) ---");
        
        // --- 1. CHARGEMENT ET INITIALISATION DU GRAPHE ---
        String fichierDonnees = "com-dblp.ungraph.txt";
        Graph reseauDblp = new DefaultGraph("GrapheDBLP");
        FileSource sourceDonnees = new FileSourceEdge();
        sourceDonnees.addSink(reseauDblp);

        try {
            sourceDonnees.readAll(fichierDonnees);
        } catch (IOException e) {
            System.err.println("Erreur lors de la lecture du fichier : " + e.getMessage());
            return;
        }

        // --- 2. PARAMÈTRES ÉPIDÉMIOLOGIQUES (Modèle SIS) ---
        // Beta : probabilité d'infection lors d'un contact
        double beta = 1.0 / 7.0;  
        // Mu : probabilité de rétablissement (guérison)
        double mu = 1.0 / 15.0; 
        // Lambda : taux de propagation effectif
        double lambda = beta / mu;
        
        System.out.printf("Taux d'infection (β)     : %.4f%n", beta);
        System.out.printf("Taux de récupération (μ) : %.4f%n", mu);
        System.out.printf("Ratio de propagation (λ) : %.4f%n", lambda);

        // --- 3. ANALYSE STATISTIQUE DES DEGRÉS ---
        // Récupération de la distribution des degrés (Nk)
        int[] distributionDegres = Toolkit.degreeDistribution(reseauDblp);
        
        // Calcul du premier moment : degré moyen <k>
        double degreMoyenK = Toolkit.averageDegree(reseauDblp); 
        
        // Calcul du deuxième moment : <k^2>
        // Formule : Σ (k^2 * P(k)) ou (Σ k^2 * Nk) / N
        double sommeDegresCarres = 0;
        int nbNoeuxTotal = reseauDblp.getNodeCount();

        for (int k = 0; k < distributionDegres.length; k++) {
            if (distributionDegres[k] > 0) {
                // On multiplie le carré du degré par le nombre de nœuds ayant ce degré
                sommeDegresCarres += Math.pow(k, 2) * distributionDegres[k];
            }
        }
        double moyenneDegresCarres = sommeDegresCarres / nbNoeuxTotal;

        System.out.printf("Degré moyen <k>           : %.4f%n", degreMoyenK);
        System.out.printf("Moment d'ordre 2 <k²>     : %.4f%n", moyenneDegresCarres);

        // --- 4. DÉTERMINATION DES SEUILS ÉPIDÉMIQUES ---
        
        // Dans un réseau aléatoire (Erdős-Rényi), le seuil est 1 / (<k> + 1) ≈ 1/<k>
        double seuilReseauAleatoire = 1.0 / degreMoyenK;
        
        // Dans un réseau réel (hétérogène), le seuil est <k> / <k^2>
        // Plus la variance des degrés est forte, plus le seuil tend vers 0
        double seuilReseauReel = degreMoyenK / moyenneDegresCarres;

        System.out.println("\n--- ANALYSE COMPARATIVE DES SEUILS ---");
        System.out.printf("Seuil théorique (Réseau Aléatoire) : %.5f%n", seuilReseauAleatoire);
        System.out.printf("Seuil calculé (Réseau DBLP Réel)   : %.5f%n", seuilReseauReel);
        
        // --- 5. CONCLUSION ---
        System.out.println("--------------------------------------");
        if (seuilReseauReel < seuilReseauAleatoire) {
            System.out.println("OBSERVATION : Le seuil réel est nettement inférieur au seuil aléatoire.");
            System.out.println("CONSÉQUENCE : Le virus peut se propager même avec un taux d'infection très faible.");
            System.out.println("CAUSE       : La structure 'Scale-free' du réseau DBLP et ses 'Hubs' facilitent la contagion.");
        }
    }
}