]> AND Private Git Repository - loba.git/blobdiff - deployment.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Do not go below expected_load when bookkeeping.
[loba.git] / deployment.cpp
index 2befb00bb9b7af1d506fcc6c07178490fea8885f..0b3042350db373fb6b13bdf9d83e087935400a17 100644 (file)
@@ -64,34 +64,28 @@ void deployment_generator::distribute_load()
     std::transform(loads.begin(), loads.end(), loads.begin(),
                    std::bind(std::multiplies<double>(), _1, factor));
     if (opt::integer_transfer) {
-        // round the loads
-        std::vector<double> iloads(hosts.size());
-        std::transform(loads.begin(), loads.end(), iloads.begin(), round);
-        // compute the differences between each load and its rounded value
-        std::vector<double> diffs(hosts.size());
-        std::transform(loads.begin(), loads.end(), iloads.begin(),
-                       diffs.begin(), std::minus<double>());
-        // compute the absolute values of the diffs
-        std::vector<double> adiffs(hosts.size());
-        std::transform(diffs.begin(), diffs.end(), adiffs.begin(), fabs);
-        // find i, index of the element farthest from its rounded value
+        double iload;
+        double residue = 0.0;
         unsigned i;
-        i = std::max_element(adiffs.begin(), adiffs.end()) - adiffs.begin();
-        // remove element i from diffs, and compute the residual part...
-        diffs[i] = diffs.back();
-        diffs.pop_back();
-        double residue = std::accumulate(diffs.begin(), diffs.end(), 0.0);
-        // ... and compute element i (rounded to avoid numerical errors)
-        iloads[i] = fabs(round(loads[i] + residue));
+        for (i = 0 ; i < hosts.size() - 1; ++i) {
+            if (residue < 0.0)
+                iload = floor(loads[i]);
+            else if (residue > 0.0)
+                iload = ceil(loads[i]);
+            else // residue == 0.0
+                iload = round(loads[i]);
+            residue += (loads[i] - iload);
+            loads[i] = iload;
+        }
+        // abs(round(...)) to avoid rounding errors, or a value of -0
+        iload = abs(round(loads[i] + residue)); // i == hosts.size() - 1
+        loads[i] = iload;
         // final sanity check
         xbt_assert(opt::auto_depl::load ==
-                   std::accumulate(iloads.begin(), iloads.end(), 0.0));
-        for (unsigned i = 0 ; i < hosts.size() ; ++i)
-            set_load(i, iloads[i]);
-    } else {
-        for (unsigned i = 0 ; i < hosts.size() ; ++i)
-            set_load(i, loads[i]);
+                   std::accumulate(loads.begin(), loads.end(), 0.0));
     }
+    for (unsigned i = 0 ; i < hosts.size() ; ++i)
+        set_load(i, loads[i]);
 }
 
 void deployment_generator::deploy()