3 /* Copyright (c) 2007 Arnaud Legrand, Pedro Velho. All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
9 * Modelling the proportional fairness using the Lagrange Optimization
10 * Approach. For a detailed description see:
11 * "ssh://username@scm.gforge.inria.fr/svn/memo/people/pvelho/lagrange/ppf.ps".
14 #include "xbt/sysdep.h"
15 #include "xbt/mallocator.h"
16 #include "maxmin_private.h"
24 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_lagrange, surf,
25 "Logging specific to SURF (lagrange)");
27 void lagrange_solve(lmm_system_t sys);
29 void lagrange_solve(lmm_system_t sys)
35 double epsilon_min_error = 1e-6;
36 double overall_error = 1;
37 double sigma_step = 0.5e-3;
38 double capacity_error=0, bound_error=0;
42 * Variables to manipulate the data structure proposed to model the maxmin
43 * fairness. See docummentation for more details.
45 xbt_swag_t elem_list = NULL;
46 lmm_element_t elem1 = NULL;
47 lmm_element_t elem2 = NULL;
49 xbt_swag_t cnst_list = NULL;
50 lmm_constraint_t cnst1 = NULL;
51 lmm_constraint_t cnst2 = NULL;
53 xbt_swag_t var_list = NULL;
54 lmm_variable_t var1 = NULL;
55 lmm_variable_t var2 = NULL;
62 int max_iterations=100000;
64 double lambda_partial=0;
69 if ( !(sys->modified))
73 * Initialize the var list variable with only the active variables.
74 * Associate an index in the swag variables. Saves the initial value
75 * of bound associated with.
77 var_list = &(sys->variable_set);
79 xbt_swag_foreach(var1, var_list) {
80 if(var1->weight != 0.0){
82 var1->initial_bound = var1->bound;
87 * Saves the initial bound of each constraint.
89 cnst_list=&(sys->active_constraint_set);
90 xbt_swag_foreach(cnst1, cnst_list) {
91 cnst1->initial_bound = cnst1->bound;
96 * While doesn't reach a minimun error or a number maximum of iterations.
98 while(overall_error > epsilon_min_error && iteration < max_iterations){
104 * Compute the value of ----------- (\lambda^k, \mu^k) this portion
106 * of code depends on function f(x).
108 var_list = &(sys->variable_set);
109 xbt_swag_foreach(var1, var_list) {
113 //for each link with capacity cnsts[i] that uses flow of variable var1 do
114 for(i=0; i<var1->cnsts_number; i++){
115 elem1 = &(var1->cnsts[i]);
116 mu_partial += (elem1->constraint)->bound + var1->initial_bound;
119 mu_partial = -1 / mu_partial + var1->initial_bound;
120 var1->bound = var1->bound + sigma_step * mu_partial;
125 * Compute the value of ------------- (\lambda^k, \mu^k) this portion
127 * of code depends on function f(x).
129 cnst_list=&(sys->active_constraint_set);
130 xbt_swag_foreach(cnst1, cnst_list) {
134 elem_list = &(cnst1->active_element_set);
136 xbt_swag_foreach(elem1, elem_list) {
139 var2 = elem1->variable;
141 //for each link with capacity cnsts[i] that uses flow of variable var1 do
142 for(i=0; i<var2->cnsts_number; i++){
143 elem2 = &(var2->cnsts[i]);
144 tmp += (elem2->constraint)->bound + var2->bound;
147 lambda_partial += -1 / tmp;
150 lambda_partial += cnst1->initial_bound;
151 cnst1->bound = cnst1->bound + sigma_step * lambda_partial;
157 * Verify for each capacity constraint (lambda) the error associated.
159 cnst_list=&(sys->active_constraint_set);
160 xbt_swag_foreach(cnst1, cnst_list) {
161 cnst2 = xbt_swag_getNext(cnst1,(var_list)->offset);
163 capacity_error += fabs( cnst1->bound - cnst2->bound );
168 * Verify for each variable the error of round trip time constraint (mu).
171 var_list = &(sys->variable_set);
172 xbt_swag_foreach(var1, var_list) {
173 var2 = xbt_swag_getNext(var1,(var_list)->offset);
175 bound_error += fabs( var2->bound - var1->bound);
179 overall_error = capacity_error + bound_error;
183 if(overall_error > epsilon_min_error){
184 DEBUG1("The method converge in %d iterations.", iteration);
188 * Now computes the values of each variable (\rho) based on
189 * the values of \lambda and \mu.
191 var_list = &(sys->variable_set);
192 xbt_swag_foreach(var1, var_list) {
194 for(i=0; i<var1->cnsts_number; i++){
195 elem1 = &(var1->cnsts[i]);
196 tmp += (elem1->constraint)->bound + var1->bound;
198 var1->weight = 1 / tmp;