diff --git a/src/algo/carbone.cpp b/src/algo/carbone.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..31d6fd46f541880255d6015a2507c222c2481a31
--- /dev/null
+++ b/src/algo/carbone.cpp
@@ -0,0 +1,130 @@
+#include "carbone.hpp"
+#include <loguru.hpp>
+
+#include "../pempek_assert.hpp"
+
+using namespace std;
+
+CarboneAlgorithm::CarboneAlgorithm(Workload * workload,
+                                   SchedulingDecision * decision,
+                                   Queue * queue,
+                                   ResourceSelector * selector,
+                                   double rjms_delay,
+                                   rapidjson::Document * variant_options) :
+    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options) {
+    // Initialisation spécifique à CarboneAlgorithm
+    carbonFootprintDcA = 0;
+    carbonFootprintDcB = 0;
+    carbonFootprintDcC = 0;
+}
+
+
+void CarboneAlgorithm::updateCarbonFootprint(int dcA, int dcB, int dcC) {
+    carbonFootprintDcA = dcA;
+    carbonFootprintDcB = dcB;
+    carbonFootprintDcC = dcC;
+}
+
+void CarboneAlgorithm::on_simulation_start(double date, const rapidjson::Value & batsim_config) {
+    _schedule = Schedule(_nb_machines, date);
+    
+    (void) batsim_config;  
+}
+
+void CarboneAlgorithm::on_simulation_end(double date) {
+    
+    (void) date;  
+}
+
+void CarboneAlgorithm::make_decisions(double date, SortableJobOrder::UpdateInformation *update_info, SortableJobOrder::CompareInformation *compare_info) {
+    const Job * priority_job_before = _queue->first_job_or_nullptr(); // Identifier la première tâche prioritaire avant de commencer les décisions
+
+    for (const string & ended_job_id : _jobs_ended_recently) { 
+        _schedule.remove_job((*_workload)[ended_job_id]); // Supprimer les tâches terminées de l'ordonnancement
+    }
+
+    std::vector<std::string> recently_queued_jobs; // Préparer une liste pour conserver les IDs des tâches récemment ajoutées à la file d'attente
+    for (const string & new_job_id : _jobs_released_recently) { // Parcourir les tâches récemment libérées et décider de les rejeter ou de les ajouter à la file d'attente
+        const Job * new_job = (*_workload)[new_job_id];
+
+        if (new_job->nb_requested_resources > _nb_machines) { 
+            _decision->add_reject_job(new_job_id, date); // Rejeter la tâche si elle demande plus de ressources que disponibles
+        } else if (!new_job->has_walltime) {
+            _decision->add_reject_job(new_job_id, date); // Rejeter la tâche si elle n'a pas de walltime défini
+        } else {
+            _queue->append_job(new_job, update_info); // Ajouter la tâche éligible à la file d'attente
+            recently_queued_jobs.push_back(new_job_id);
+        }
+    }
+
+    _schedule.update_first_slice(date); // Mettre à jour l'état actuel de l'ordonnancement
+
+    const Job * priority_job_after = nullptr; // Identifier la première tâche prioritaire après le tri et la mise à jour de la file
+    sort_queue_while_handling_priority_job(priority_job_before, priority_job_after, update_info, compare_info);
+
+    int nb_available_machines = _schedule.begin()->available_machines.size(); // Calculer le nombre de machines disponibles actuellement
+
+    for (const string & new_job_id : recently_queued_jobs) { //exécuter les tâches récemment ajoutées à la file, en tenant compte de la disponibilité des ressources
+        const Job * new_job = (*_workload)[new_job_id];
+        if (_queue->contains_job(new_job) && new_job != priority_job_after && new_job->nb_requested_resources <= nb_available_machines) {
+            string optimalDC = select_datacenter_with_lowest_carbon_footprint();  // Sélection du data center avec l'empreinte carbone la plus faible
+            Schedule::JobAlloc alloc = _schedule.add_job_first_fit(new_job, _selector, optimalDC); // Allouer la tâche dans le data center sélectionné
+            if (alloc.started_in_first_slice) {
+                _decision->add_execute_job(new_job_id, alloc.used_machines, date, optimalDC);  // Exécuter la tâche si elle peut démarrer immédiatement
+                _queue->remove_job(new_job);
+                nb_available_machines -= new_job->nb_requested_resources;
+            } else {
+                _schedule.remove_job(new_job); // Retirer la tâche de l'ordonnancement si elle ne peut pas démarrer immédiatement
+            }
+        }
+    }
+    // Parcourir la file d'attente pour essayer d'exécuter les tâches restantes, en tenant compte de la priorité et de la disponibilité des ressources
+    auto job_it = _queue->begin();
+    while (job_it != _queue->end() && nb_available_machines > 0) {
+        const Job * job = (*job_it)->job;
+        if (_schedule.contains_job(job)) _schedule.remove_job(job);
+        if (job == priority_job_after) {
+            string optimalDC = select_datacenter_with_lowest_carbon_footprint();
+            Schedule::JobAlloc alloc = _schedule.add_job_first_fit(job, _selector,optimalDC);
+            if (alloc.started_in_first_slice) {
+                _decision->add_execute_job(job->id, alloc.used_machines, date,optimalDC);
+                job_it = _queue->remove_job(job_it);
+                priority_job_after = _queue->first_job_or_nullptr();
+            } else {
+                ++job_it;
+            }
+        } else {
+            Schedule::JobAlloc alloc = _schedule.add_job_first_fit(job, _selector);
+            if (alloc.started_in_first_slice) {
+                _decision->add_execute_job(job->id, alloc.used_machines, date);
+                job_it = _queue->remove_job(job_it);
+            } else {
+                ++job_it;
+            }
+        }
+    }
+}
+
+
+std::string  CarboneAlgorithm::select_datacenter_with_lowest_carbon_footprint() {
+    int lowestCarbonFootprint = std::min({carbonFootprintDcA, carbonFootprintDcB, carbonFootprintDcC});
+
+    string lowestDcID = "dcA"; 
+
+    if (carbonFootprintDcB < lowestCarbonFootprint) {
+        lowestCarbonFootprint = carbonFootprintDcB;
+        lowestDcID = "dcB";
+    }
+
+    if (carbonFootprintDcC < lowestCarbonFootprint) {
+        lowestCarbonFootprint = carbonFootprintDcC;
+        lowestDcID = "dcC";
+    }
+
+    std::string result = "La valeur de l’empreinte carbone la plus optimale est : " + std::to_string(lowestCarbonFootprint) + " de datacenter " + lowestDcName;
+    return result;
+
+}
+
+
+