├── CompareAlgs ├── MPC │ ├── README.TXT │ ├── Results │ │ ├── Barab100_NonStar.pdf │ │ ├── Barab100_NonStar_Stable.mat │ │ ├── Barab100_NonStar_Unstable.pdf │ │ ├── Barab100_Stable.mat │ │ ├── Barab100_Stable.pdf │ │ ├── Barab100_Unstable.mat │ │ ├── Barab100_Unstable.pdf │ │ ├── Barab100_Unstable_NonStar.mat │ │ ├── PowerGridStable.pdf │ │ ├── PowerGridStable_NonStar.pdf │ │ ├── PowerGrid_Stable.mat │ │ └── PowerGrid_Stable_NonStar.mat │ ├── RunExperiments_Barab100.m │ ├── RunExperiments_Barab100_NonStar.m │ ├── RunExperiments_Barab100_NonStar_Unstable.m │ ├── RunExperiments_Barab2000.m │ ├── RunExperiments_PowerGrid.m │ └── RunExperiments_PowerGrid_NonStar.m └── NetworkFlow │ ├── README.TXT │ ├── Results │ ├── NetFlow_Barab100.mat │ ├── NetFlow_Barab2000.mat │ └── NetFlow_Barab2000.pdf │ ├── RunExperiments_NF.m │ └── RunExperiments_NF2000.m ├── DADMM_Partial.m ├── GenerateData ├── Data │ ├── MPC │ │ ├── Data │ │ │ ├── Barab_NonStar_P_100_STABLE.mat │ │ │ ├── Barab_NonStar_P_100_STABLE.txt │ │ │ ├── Barab_NonStar_P_100_UNSTABLE.mat │ │ │ ├── Barab_NonStar_P_100_UNSTABLE.txt │ │ │ ├── Barab_NonStar_P_6_STABLE.mat │ │ │ ├── Barab_NonStar_P_6_STABLE.txt │ │ │ ├── Barab_P_100_STABLE.mat │ │ │ ├── Barab_P_100_STABLE.txt │ │ │ ├── Barab_P_100_UNSTABLE.mat │ │ │ ├── Barab_P_100_UNSTABLE.txt │ │ │ ├── Barab_P_2000_STABLE.mat │ │ │ ├── Barab_P_2000_STABLE.txt │ │ │ ├── MPC_PGrid_P_4941_STABLE.mat │ │ │ ├── MPC_PGrid_P_4941_STABLE.txt │ │ │ ├── PGrid_NonStar_P_4941_STABLE.mat │ │ │ └── PGrid_NonStar_P_4941_STABLE.txt │ │ ├── Readme │ │ │ ├── MPC.pdf │ │ │ └── MPC.tex │ │ ├── genDataMPC.m │ │ └── genDataMPC_NonStar.m │ └── NetworkFlows │ │ ├── GenerateNetworkFlows.sage │ │ ├── Results │ │ ├── NFData_Barabasi_P_100.mat │ │ ├── NFData_Barabasi_P_100.txt │ │ ├── NFData_Barabasi_P_2000.mat │ │ ├── NFData_Barabasi_P_2000.txt │ │ └── NFData_Barabasi_P_6.mat │ │ └── TreatData.m ├── FactorGraphs │ ├── CreateVarPartialConnected.m │ ├── CreateVarScript.m │ ├── GeneratedFGs │ │ ├── FG_Nets_10_nodes.mat │ │ ├── FG_Nets_2000_nodes.mat │ │ ├── FG_Nets_500_nodes.mat │ │ ├── FG_Nets_50_nodes.mat │ │ └── README.TXT │ └── README.TXT ├── Networks │ ├── Bipartite │ │ ├── Bipartite_Nets.mat │ │ ├── README.TXT │ │ ├── gen_bipartite_erdos.py │ │ └── generate_series_bipartite.m │ ├── MPC │ │ ├── ProcessedNetwork │ │ │ ├── Barabasi_P_100.mat │ │ │ ├── Barabasi_P_100.txt │ │ │ ├── Barabasi_P_2000.mat │ │ │ ├── Barabasi_P_2000.txt │ │ │ ├── Barabasi_P_6.mat │ │ │ ├── Barabasi_P_6.txt │ │ │ ├── Network_PowerGrid.mat │ │ │ └── Stats_PowerGrid.txt │ │ ├── README.TXT │ │ ├── RawNetwork │ │ │ ├── date_retrieved.txt │ │ │ ├── power.gml │ │ │ └── power.txt │ │ └── Scripts │ │ │ ├── Barabasi.py │ │ │ ├── Barabasi.sage │ │ │ ├── READ_FROM_RAW.m │ │ │ ├── processPowerGrid.py │ │ │ └── processPowerGrid.sage │ └── README.TXT └── README.txt ├── KekatosADMM └── KekatosADMM.m ├── README.md ├── READOTHER.md ├── SpecialPurposeAlgs ├── BoydADMM │ ├── BoydADMM.m │ └── Documentation │ │ ├── BoydADMM.bib │ │ ├── BoydADMM.pdf │ │ └── BoydADMM.tex ├── GradientMethod │ ├── Documentation │ │ ├── GradientMethod.pdf │ │ └── GradientMethod.tex │ └── GradientMethod.m ├── NesterovMethod │ ├── MPC │ │ ├── GradientsMPC.m │ │ ├── RunMPC.m │ │ └── projConsMPC.m │ ├── NesterovMethod.m │ ├── NetworkFlow │ │ ├── Documentation │ │ │ ├── NestNetFlow.pdf │ │ │ └── NestNetFlow.tex │ │ ├── Error_gradNetFlow.m │ │ ├── RunNetworkFlow.m │ │ ├── grads_NetFlowNest.m │ │ └── proj_NetFlowNest.m │ └── README.TXT └── README.TXT ├── UsageExamples ├── MPC_PowerGrid │ ├── RunMPC_PowerGrid.m │ └── SolverMPC.m └── NetworkFlow │ ├── Delays_f.m │ ├── Delays_grad.m │ ├── Delays_proj.m │ ├── Documentation │ ├── NetworkFlow.bib │ ├── NetworkFlow.pdf │ └── NetworkFlow.tex │ ├── NetFlowSolver.m │ ├── NetFlowSolver_proj.m │ ├── README.TXT │ ├── RunNetworkFlow.m │ └── SPG_BB.m └── svgs ├── 2da32a437e1e022c68095bcb359d92a2.svg ├── 2ec6e630f199f589a2402fdf3e0289d5.svg ├── 332cc365a4987aacce0ead01b8bdcc0b.svg ├── 55a049b8f161ae7cfeb0197d75aff967.svg ├── 6ec3283e6e3265a8f069c5185acc3866.svg ├── 8c929ed4f1683c97667250dcfd5e3a5a.svg └── b7dec1314efeadd1815bf346b3472200.svg /CompareAlgs/MPC/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | The files in this folder reproduce the results in Figure 5 of the paper 3 | 4 | J. Mota, J. Xavier, P. Aguiar, M. Püschel, 5 | Distributed Optimization With Local Domains: Applications in MPC and Network 6 | Flows, to appear in IEEE Transactions on Automatic Control, 2015 7 | 8 | Namely, 9 | 10 | RunExperiments_PowerGrid.m reproduces Figure 5(a) 11 | 12 | RunExperiments_Barab100_NonStar_Unstable.m reproduces Figure 5(b) 13 | 14 | 15 | -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/Barab100_NonStar.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/Barab100_NonStar.pdf -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/Barab100_NonStar_Stable.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/Barab100_NonStar_Stable.mat -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/Barab100_NonStar_Unstable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/Barab100_NonStar_Unstable.pdf -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/Barab100_Stable.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/Barab100_Stable.mat -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/Barab100_Stable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/Barab100_Stable.pdf -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/Barab100_Unstable.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/Barab100_Unstable.mat -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/Barab100_Unstable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/Barab100_Unstable.pdf -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/Barab100_Unstable_NonStar.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/Barab100_Unstable_NonStar.mat -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/PowerGridStable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/PowerGridStable.pdf -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/PowerGridStable_NonStar.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/PowerGridStable_NonStar.pdf -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/PowerGrid_Stable.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/PowerGrid_Stable.mat -------------------------------------------------------------------------------- /CompareAlgs/MPC/Results/PowerGrid_Stable_NonStar.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/MPC/Results/PowerGrid_Stable_NonStar.mat -------------------------------------------------------------------------------- /CompareAlgs/MPC/RunExperiments_Barab100.m: -------------------------------------------------------------------------------- 1 | 2 | % Filename for saving data 3 | FILE_SAVE = 'Results/Barab100_Unstable.mat'; 4 | 5 | % ========================================================================= 6 | % Execution parameters of the algorithms: 7 | 8 | max_communications = 1000; 9 | eps_opt = 1e-4; % Has to be one of {1e-1, 1e-2, ..., 1e-9, 1e-10} 10 | 11 | % We will select the rho that is best for 1e-4 of accuracy 12 | % In the unstable case, rho = 120 is best for Boyd, rho = 135 is best for 13 | % the others (precision 5) 14 | rhos = [120 135]; 15 | %rhos = 25; % For the stable (precision +/- 5) 16 | % ========================================================================= 17 | 18 | 19 | % ========================================================================= 20 | % Directories and filenames 21 | 22 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 23 | addpath('../../GenerateData/Data/MPC/Data/'); % Data 24 | 25 | % Algorithms to be compared 26 | addpath('../../'); 27 | addpath('../../KekatosADMM'); 28 | addpath('../../SpecialPurposeAlgs/BoydADMM'); 29 | addpath('../../SpecialPurposeAlgs/NesterovMethod'); 30 | 31 | % Solvers and auxiliary functions 32 | addpath('../../UsageExamples/MPC_PowerGrid'); 33 | addpath('../../SpecialPurposeAlgs/NesterovMethod/MPC'); 34 | 35 | file_networks = 'Barabasi_P_100.mat'; 36 | file_data = 'Barab_P_100_UNSTABLE.mat'; 37 | %file_data = 'Barab_P_100_STABLE.mat'; 38 | % ========================================================================= 39 | 40 | 41 | % ========================================================================= 42 | % Extract Data 43 | 44 | % Load files 45 | load(file_networks); 46 | load(file_data); 47 | 48 | pos_iter_errors = -log10(eps_opt); % Corresponding row in iter_for_errors 49 | 50 | len_rhos = length(rhos); 51 | 52 | % Network data 53 | P = Network.P; 54 | Adj = Network.Adj; 55 | Num_Colors = Network.Num_Colors; 56 | Partition = Network.Partition; 57 | Neighbors = Network.Neighbors; 58 | Degrees = Network.Degrees; 59 | 60 | centers = kron(1:P,ones(1,T*m_p)); 61 | % ========================================================================= 62 | 63 | 64 | % ========================================================================= 65 | % vars_prob for all algorithms 66 | 67 | % ********************************************************** 68 | % D-ADMM, Kekatos, and BoydADMM 69 | vars_prob = struct('handler', {@SolverMPC}, ... 70 | 'components', {components}, ... 71 | 'centers', {centers}, ... % For Boyd's algorithm 72 | 'E_p', {E_p}, ... 73 | 'w_p', {w_p} ... 74 | ); 75 | 76 | vars_network = struct('P', {P}, ... 77 | 'neighbors', {Neighbors}, ... 78 | 'partition_colors', {Partition} ... 79 | ); 80 | % ********************************************************** 81 | 82 | % ********************************************************** 83 | % Gradient and Nesterov Methods 84 | vars_prob_Grad = struct('gradients', {@GradientsMPC}, ... 85 | 'proj_constraints', {@projConsMPC}, ... 86 | 'components', {components}, ... 87 | 'centers', {centers}, ... 88 | 'E_p', {E_p}, ... 89 | 'w_p', {w_p} ... 90 | ); 91 | % ========================================================================= 92 | 93 | 94 | % ========================================================================= 95 | % Execute Algorithms 96 | 97 | 98 | %****************************************************************** 99 | % DADMM_Partial 100 | errors_DADMM_Partial = 0; 101 | best_rhos_DADMM_Partial = 0; 102 | iter_for_errors_DADMM_Partial = 0; 103 | 104 | best_iter_DADMM_Partial = Inf; 105 | for i_rhos = 1 : len_rhos 106 | 107 | % Optional input 108 | ops = struct('rho', {rhos(i_rhos)}, ... 109 | 'max_iter', {max_communications}, ... 110 | 'x_opt', {solution}, ... 111 | 'eps_opt', {eps_opt} ... 112 | ); 113 | 114 | fprintf('DADMM_Partial: start\n'); 115 | [X_DADMM_Partial, vars_prob_DADMM_Partial, ops_out] = ... 116 | DADMM_Partial(length(solution), vars_prob, vars_network, ops); 117 | fprintf('DADMM_Partial: finish\n'); 118 | 119 | iterations = ops_out.iterations; 120 | stop_crit = ops_out.stop_crit; 121 | error_iterations = ops_out.error_iterations; 122 | iter_for_errors = ops_out.iter_for_errors; 123 | 124 | fprintf('Number of iterations = %d\n', iterations); 125 | fprintf('stop_crit = %s\n', stop_crit); 126 | for i_g = 1 : 6 127 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 128 | end 129 | 130 | if iter_for_errors(pos_iter_errors,2) < best_iter_DADMM_Partial 131 | best_iter_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 132 | errors_DADMM_Partial = error_iterations; 133 | best_rhos_DADMM_Partial = rhos(i_rhos); 134 | iter_for_errors_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 135 | end 136 | end 137 | %****************************************************************** 138 | 139 | 140 | %****************************************************************** 141 | % Kekatos ADMM 142 | errors_KekatosADMM = 0; 143 | best_rhos_KekatosADMM = 0; 144 | iter_for_errors_KekatosADMM = 0; 145 | 146 | best_iter_KekatosADMM = Inf; 147 | for i_rhos = 1 : len_rhos 148 | 149 | % Optional input 150 | ops = struct('rho', {rhos(i_rhos)}, ... 151 | 'max_iter', {max_communications}, ... 152 | 'x_opt', {solution}, ... 153 | 'eps_opt', {eps_opt} ... 154 | ); 155 | 156 | fprintf('KekatosADMM: start\n'); 157 | [X_KekatosADMM, vars_prob_KekatosADMM, ops_out] = ... 158 | KekatosADMM(length(solution), vars_prob, vars_network, ops); 159 | fprintf('KekatosADMM: finish\n'); 160 | 161 | iterations = ops_out.iterations; 162 | stop_crit = ops_out.stop_crit; 163 | error_iterations = ops_out.error_iterations; 164 | iter_for_errors = ops_out.iter_for_errors; 165 | 166 | fprintf('Number of iterations = %d\n', iterations); 167 | fprintf('stop_crit = %s\n', stop_crit); 168 | for i_g = 1 : 6 169 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 170 | end 171 | 172 | if iter_for_errors(pos_iter_errors,2) < best_iter_KekatosADMM 173 | best_iter_KekatosADMM = iter_for_errors(pos_iter_errors,2); 174 | errors_KekatosADMM = error_iterations; 175 | best_rhos_KekatosADMM = rhos(i_rhos); 176 | iter_for_errors_KekatosADMM = iter_for_errors(pos_iter_errors,2); 177 | end 178 | end 179 | %****************************************************************** 180 | 181 | 182 | %****************************************************************** 183 | % BoydADMM 184 | 185 | errors_BoydADMM = 0; 186 | best_rhos_BoydADMM = 0; 187 | iter_for_errors_BoydADMM = 0; 188 | 189 | best_iter_BoydADMM = Inf; 190 | for i_rhos = 1 : len_rhos 191 | 192 | % Optional input 193 | ops = struct('rho', {rhos(i_rhos)}, ... 194 | 'max_iter', {max_communications}, ... 195 | 'x_opt', {solution}, ... 196 | 'eps_opt', {eps_opt} ... 197 | ); 198 | 199 | fprintf('BoydADMM: start\n'); 200 | [X_BoydADMM, vars_prob_BoydADMM, ops_out] = ... 201 | BoydADMM(length(solution), vars_prob, vars_network, ops); 202 | fprintf('BoydADMM: finish\n'); 203 | 204 | iterations = ops_out.iterations; 205 | stop_crit = ops_out.stop_crit; 206 | error_iterations = ops_out.error_iterations; 207 | iter_for_errors = ops_out.iter_for_errors; 208 | 209 | fprintf('Number of iterations = %d\n', iterations); 210 | fprintf('stop_crit = %s\n', stop_crit); 211 | for i_g = 1 : 6 212 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 213 | end 214 | 215 | if iter_for_errors(pos_iter_errors,2) < best_iter_BoydADMM 216 | best_iter_BoydADMM = iter_for_errors(pos_iter_errors,2); 217 | errors_BoydADMM = error_iterations; 218 | best_rhos_BoydADMM = rhos(i_rhos); 219 | iter_for_errors_BoydADMM = iter_for_errors(pos_iter_errors,2); 220 | end 221 | end 222 | %****************************************************************** 223 | 224 | 225 | %****************************************************************** 226 | % Nesterov Method 227 | 228 | % Optional input 229 | ops = struct('max_iter', {max_communications}, ... 230 | 'x_opt', {solution}, ... 231 | 'eps_opt', {eps_opt} ... 232 | ); 233 | 234 | fprintf('Nesterov: start\n'); 235 | [X_Nest, vars_prob_Grad, ops_out] = NesterovMethod(length(solution), Lipschitz, ... 236 | vars_prob_Grad, vars_network, ops); 237 | fprintf('Nesterov: finish\n'); 238 | 239 | iterations = ops_out.iterations; 240 | stop_crit = ops_out.stop_crit; 241 | error_iterations = ops_out.error_iterations; 242 | iter_for_errors = ops_out.iter_for_errors; 243 | 244 | fprintf('Number of iterations = %d\n', iterations); 245 | fprintf('stop_crit = %s\n', stop_crit); 246 | for i_g = 1 : 6 247 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 248 | end 249 | 250 | errors_NesterovMethod = error_iterations; 251 | iter_for_errors_NesterovMethod = iter_for_errors(pos_iter_errors,2); 252 | %****************************************************************** 253 | 254 | 255 | % ========================================================================= 256 | 257 | 258 | % ========================================================================= 259 | % Save data 260 | save(FILE_SAVE, 'rhos', 'max_communications', 'eps_opt', ... 261 | 'errors_DADMM_Partial', 'best_rhos_DADMM_Partial', 'iter_for_errors_DADMM_Partial', ... 262 | 'errors_KekatosADMM', 'best_rhos_KekatosADMM', 'iter_for_errors_KekatosADMM', ... 263 | 'errors_BoydADMM', 'best_rhos_BoydADMM', 'iter_for_errors_BoydADMM', ... 264 | 'errors_NesterovMethod', 'iter_for_errors_NesterovMethod' ... 265 | ); 266 | % ========================================================================= 267 | 268 | 269 | figure(1);clf; 270 | semilogy(errors_DADMM_Partial, 'b-'); 271 | hold on; 272 | semilogy(errors_KekatosADMM, 'r-'); 273 | semilogy(errors_BoydADMM, 'k-'); 274 | semilogy(errors_NesterovMethod, 'c-'); 275 | legend('DADMMp', 'Kekatos', 'Boyd', 'Nesterov') 276 | drawnow; 277 | 278 | 279 | 280 | 281 | 282 | -------------------------------------------------------------------------------- /CompareAlgs/MPC/RunExperiments_Barab100_NonStar.m: -------------------------------------------------------------------------------- 1 | 2 | % Filename for saving data 3 | FILE_SAVE = 'Results/Barab100_NonStar_Stable.mat'; 4 | 5 | % ========================================================================= 6 | % Execution parameters of the algorithms: 7 | 8 | max_communications = 1000; 9 | eps_opt = 1e-4; % Has to be one of {1e-1, 1e-2, ..., 1e-9, 1e-10} 10 | 11 | % We will select the rho that is best for 1e-4 of accuracy 12 | rhos = 40; % Precision +/-5 13 | % ========================================================================= 14 | 15 | 16 | % ========================================================================= 17 | % Directories 18 | 19 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 20 | addpath('../../GenerateData/Data/MPC/Data/'); % Data 21 | 22 | % Algorithms to be compared 23 | addpath('../../'); 24 | addpath('../../KekatosADMM'); 25 | 26 | % Solvers and auxiliary functions 27 | addpath('../../UsageExamples/MPC_PowerGrid'); 28 | 29 | file_networks = 'Barabasi_P_100.mat'; 30 | file_data = 'Barab_NonStar_P_100_STABLE.mat'; 31 | % ========================================================================= 32 | 33 | 34 | % ========================================================================= 35 | % Extract Data 36 | 37 | % Load files 38 | load(file_networks); 39 | load(file_data); 40 | 41 | pos_iter_errors = -log10(eps_opt); % Corresponding row in iter_for_errors 42 | 43 | len_rhos = length(rhos); 44 | 45 | % Network data 46 | P = Network.P; 47 | Adj = Network.Adj; 48 | Num_Colors = Network.Num_Colors; 49 | Partition = Network.Partition; 50 | Neighbors = Network.Neighbors; 51 | Degrees = Network.Degrees; 52 | % ========================================================================= 53 | 54 | 55 | % ========================================================================= 56 | % vars_prob and vars_network 57 | 58 | vars_prob = struct('handler', {@SolverMPC}, ... 59 | 'components', {components}, ... 60 | 'E_p', {E_p}, ... 61 | 'w_p', {w_p} ... 62 | ); 63 | 64 | vars_network = struct('P', {P}, ... 65 | 'neighbors', {Neighbors}, ... 66 | 'partition_colors', {Partition} ... 67 | ); 68 | % ========================================================================= 69 | 70 | 71 | % ========================================================================= 72 | % Execute Algorithms 73 | 74 | 75 | %****************************************************************** 76 | % DADMM_Partial 77 | errors_DADMM_Partial = 0; 78 | best_rhos_DADMM_Partial = 0; 79 | iter_for_errors_DADMM_Partial = 0; 80 | 81 | best_iter_DADMM_Partial = Inf; 82 | for i_rhos = 1 : len_rhos 83 | 84 | % Optional input 85 | ops = struct('rho', {rhos(i_rhos)}, ... 86 | 'max_iter', {max_communications}, ... 87 | 'x_opt', {solution}, ... 88 | 'eps_opt', {eps_opt} ... 89 | ); 90 | 91 | fprintf('DADMM_Partial: start\n'); 92 | [X_DADMM_Partial, vars_prob_DADMM_Partial, ops_out] = ... 93 | DADMM_Partial(length(solution), vars_prob, vars_network, ops); 94 | fprintf('DADMM_Partial: finish\n'); 95 | 96 | iterations = ops_out.iterations; 97 | stop_crit = ops_out.stop_crit; 98 | error_iterations = ops_out.error_iterations; 99 | iter_for_errors = ops_out.iter_for_errors; 100 | 101 | fprintf('Number of iterations = %d\n', iterations); 102 | fprintf('stop_crit = %s\n', stop_crit); 103 | for i_g = 1 : 6 104 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 105 | end 106 | 107 | if iter_for_errors(pos_iter_errors,2) < best_iter_DADMM_Partial 108 | best_iter_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 109 | errors_DADMM_Partial = error_iterations; 110 | best_rhos_DADMM_Partial = rhos(i_rhos); 111 | iter_for_errors_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 112 | end 113 | end 114 | %****************************************************************** 115 | 116 | 117 | %****************************************************************** 118 | % Kekatos ADMM 119 | errors_KekatosADMM = 0; 120 | best_rhos_KekatosADMM = 0; 121 | iter_for_errors_KekatosADMM = 0; 122 | 123 | best_iter_KekatosADMM = Inf; 124 | for i_rhos = 1 : len_rhos 125 | 126 | % Optional input 127 | ops = struct('rho', {rhos(i_rhos)}, ... 128 | 'max_iter', {max_communications}, ... 129 | 'x_opt', {solution}, ... 130 | 'eps_opt', {eps_opt} ... 131 | ); 132 | 133 | fprintf('KekatosADMM: start\n'); 134 | [X_KekatosADMM, vars_prob_KekatosADMM, ops_out] = ... 135 | KekatosADMM(length(solution), vars_prob, vars_network, ops); 136 | fprintf('KekatosADMM: finish\n'); 137 | 138 | iterations = ops_out.iterations; 139 | stop_crit = ops_out.stop_crit; 140 | error_iterations = ops_out.error_iterations; 141 | iter_for_errors = ops_out.iter_for_errors; 142 | 143 | fprintf('Number of iterations = %d\n', iterations); 144 | fprintf('stop_crit = %s\n', stop_crit); 145 | for i_g = 1 : 6 146 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 147 | end 148 | 149 | if iter_for_errors(pos_iter_errors,2) < best_iter_KekatosADMM 150 | best_iter_KekatosADMM = iter_for_errors(pos_iter_errors,2); 151 | errors_KekatosADMM = error_iterations; 152 | best_rhos_KekatosADMM = rhos(i_rhos); 153 | iter_for_errors_KekatosADMM = iter_for_errors(pos_iter_errors,2); 154 | end 155 | end 156 | %****************************************************************** 157 | 158 | 159 | % ========================================================================= 160 | 161 | 162 | % ========================================================================= 163 | % Save data 164 | save(FILE_SAVE, 'rhos', 'max_communications', 'eps_opt', ... 165 | 'errors_DADMM_Partial', 'best_rhos_DADMM_Partial', 'iter_for_errors_DADMM_Partial', ... 166 | 'errors_KekatosADMM', 'best_rhos_KekatosADMM', 'iter_for_errors_KekatosADMM' ... 167 | ); 168 | % ========================================================================= 169 | 170 | 171 | figure(1);clf; 172 | semilogy(errors_DADMM_Partial, 'b-'); 173 | hold on; 174 | semilogy(errors_KekatosADMM, 'r-'); 175 | legend('DADMMp', 'Kekatos') 176 | drawnow; 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /CompareAlgs/MPC/RunExperiments_Barab100_NonStar_Unstable.m: -------------------------------------------------------------------------------- 1 | 2 | % Filename for saving data 3 | FILE_SAVE = 'Results/Barab100_Unstable_NonStar.mat'; 4 | 5 | % ========================================================================= 6 | % Execution parameters of the algorithms: 7 | 8 | max_communications = 300; 9 | eps_opt = 1e-4; % Has to be one of {1e-1, 1e-2, ..., 1e-9, 1e-10} 10 | 11 | % We will select the rho that is best for 1e-4 of accuracy 12 | rho_DADMM = [74, 75, 76]; % All rhos selected with precision +/-1 13 | rho_Kekatos = [74, 75, 76]; 14 | % ========================================================================= 15 | 16 | 17 | % ========================================================================= 18 | % Directories and filenames 19 | 20 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 21 | addpath('../../GenerateData/Data/MPC/Data/'); % Data 22 | 23 | % Algorithms to be compared 24 | addpath('../../'); 25 | addpath('../../KekatosADMM'); 26 | addpath('../../SpecialPurposeAlgs/BoydADMM'); 27 | addpath('../../SpecialPurposeAlgs/NesterovMethod'); 28 | 29 | % Solvers and auxiliary functions 30 | addpath('../../UsageExamples/MPC_PowerGrid'); 31 | addpath('../../SpecialPurposeAlgs/NesterovMethod/MPC'); 32 | 33 | file_networks = 'Barabasi_P_100.mat'; 34 | file_data = 'Barab_NonStar_P_100_UNSTABLE.mat'; 35 | % ========================================================================= 36 | 37 | 38 | % ========================================================================= 39 | % Extract Data 40 | 41 | % Load files 42 | load(file_networks); 43 | load(file_data); 44 | 45 | pos_iter_errors = -log10(eps_opt); % Corresponding row in iter_for_errors 46 | 47 | % Network data 48 | P = Network.P; 49 | Adj = Network.Adj; 50 | Num_Colors = Network.Num_Colors; 51 | Partition = Network.Partition; 52 | Neighbors = Network.Neighbors; 53 | Degrees = Network.Degrees; 54 | 55 | centers = kron(1:P,ones(1,T*m_p)); 56 | % ========================================================================= 57 | 58 | 59 | % ========================================================================= 60 | % vars_prob for all algorithms 61 | 62 | % ********************************************************** 63 | % D-ADMM, Kekatos, and BoydADMM 64 | 65 | vars_prob = struct('handler', {@SolverMPC}, ... 66 | 'components', {components}, ... 67 | 'centers', {centers}, ... % For Boyd's algorithm 68 | 'E_p', {E_p}, ... 69 | 'w_p', {w_p} ... 70 | ); 71 | 72 | 73 | vars_network = struct('P', {P}, ... 74 | 'neighbors', {Neighbors}, ... 75 | 'partition_colors', {Partition} ... 76 | ); 77 | % ********************************************************** 78 | 79 | % ********************************************************** 80 | % Gradient and Nesterov Methods 81 | 82 | vars_prob_Grad = struct('gradients', {@GradientsMPC}, ... 83 | 'proj_constraints', {@projConsMPC}, ... 84 | 'components', {components}, ... 85 | 'centers', {centers}, ... 86 | 'E_p', {E_p}, ... 87 | 'w_p', {w_p} ... 88 | ); 89 | % ========================================================================= 90 | 91 | 92 | % ========================================================================= 93 | % Execute Algorithms 94 | 95 | 96 | %****************************************************************** 97 | % DADMM_Partial 98 | 99 | errors_DADMM_Partial = 0; 100 | best_rhos_DADMM_Partial = 0; 101 | iter_for_errors_DADMM_Partial = 0; 102 | 103 | best_iter_DADMM_Partial = Inf; 104 | 105 | len_rhos_DADMM = length(rho_DADMM); 106 | 107 | for i_rhos = 1 : len_rhos_DADMM 108 | % Optional input 109 | ops = struct('rho', {rho_DADMM(i_rhos)}, ... 110 | 'max_iter', {max_communications}, ... 111 | 'x_opt', {solution}, ... 112 | 'eps_opt', {eps_opt} ... 113 | ); 114 | 115 | fprintf('DADMM_Partial: start\n'); 116 | [X_DADMM_Partial, vars_prob_DADMM_Partial, ops_out] = ... 117 | DADMM_Partial(length(solution), vars_prob, vars_network, ops); 118 | fprintf('DADMM_Partial: finish\n'); 119 | 120 | iterations = ops_out.iterations; 121 | stop_crit = ops_out.stop_crit; 122 | error_iterations = ops_out.error_iterations; 123 | iter_for_errors = ops_out.iter_for_errors; 124 | 125 | fprintf('Number of iterations = %d\n', iterations); 126 | fprintf('stop_crit = %s\n', stop_crit); 127 | for i_g = 1 : 6 128 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 129 | end 130 | 131 | if iter_for_errors(pos_iter_errors,2) < best_iter_DADMM_Partial 132 | best_iter_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 133 | errors_DADMM_Partial = error_iterations; 134 | best_rhos_DADMM_Partial = rho_DADMM(i_rhos); 135 | iter_for_errors_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 136 | end 137 | end 138 | %****************************************************************** 139 | 140 | 141 | %****************************************************************** 142 | % Kekatos ADMM 143 | 144 | errors_KekatosADMM = 0; 145 | best_rhos_KekatosADMM = 0; 146 | iter_for_errors_KekatosADMM = 0; 147 | 148 | best_iter_KekatosADMM = Inf; 149 | 150 | len_rhos_Kekatos = length(rho_Kekatos); 151 | 152 | for i_rhos = 1 : len_rhos_Kekatos 153 | % Optional input 154 | ops = struct('rho', {rho_Kekatos(i_rhos)}, ... 155 | 'max_iter', {max_communications}, ... 156 | 'x_opt', {solution}, ... 157 | 'eps_opt', {eps_opt} ... 158 | ); 159 | 160 | fprintf('KekatosADMM: start\n'); 161 | [X_KekatosADMM, vars_prob_KekatosADMM, ops_out] = ... 162 | KekatosADMM(length(solution), vars_prob, vars_network, ops); 163 | fprintf('KekatosADMM: finish\n'); 164 | 165 | iterations = ops_out.iterations; 166 | stop_crit = ops_out.stop_crit; 167 | error_iterations = ops_out.error_iterations; 168 | iter_for_errors = ops_out.iter_for_errors; 169 | 170 | fprintf('Number of iterations = %d\n', iterations); 171 | fprintf('stop_crit = %s\n', stop_crit); 172 | for i_g = 1 : 6 173 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 174 | end 175 | 176 | if iter_for_errors(pos_iter_errors,2) < best_iter_KekatosADMM 177 | best_iter_KekatosADMM = iter_for_errors(pos_iter_errors,2); 178 | errors_KekatosADMM = error_iterations; 179 | best_rhos_KekatosADMM = rho_Kekatos(i_rhos); 180 | iter_for_errors_KekatosADMM = iter_for_errors(pos_iter_errors,2); 181 | end 182 | 183 | 184 | end 185 | %****************************************************************** 186 | 187 | % ========================================================================= 188 | 189 | 190 | % ========================================================================= 191 | % Save data 192 | save(FILE_SAVE, 'rho_DADMM', 'rho_Kekatos', 'max_communications', 'eps_opt', ... 193 | 'errors_DADMM_Partial', 'best_rhos_DADMM_Partial', 'iter_for_errors_DADMM_Partial', ... 194 | 'errors_KekatosADMM', 'best_rhos_KekatosADMM', 'iter_for_errors_KekatosADMM' ... 195 | ); 196 | % ========================================================================= 197 | 198 | 199 | figure(1);clf; 200 | semilogy(errors_DADMM_Partial, 'b-'); 201 | hold on; 202 | semilogy(errors_KekatosADMM, 'r-'); 203 | legend('DADMMp', 'Kekatos') 204 | drawnow; 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /CompareAlgs/MPC/RunExperiments_Barab2000.m: -------------------------------------------------------------------------------- 1 | 2 | % Filename for saving data 3 | FILE_SAVE = 'Results/Barab100_Stable.mat'; 4 | 5 | % ========================================================================= 6 | % Execution parameters of the algorithms: 7 | 8 | max_communications = 1000; 9 | eps_opt = 1e-4; % Has to be one of {1e-1, 1e-2, ..., 1e-9, 1e-10} 10 | 11 | % We will select the rho that is best for 1e-4 of accuracy 12 | rhos = 30; % This rho was obtained with a +/-5 precision 13 | % ========================================================================= 14 | 15 | 16 | % ========================================================================= 17 | % Directories and filenames 18 | 19 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 20 | addpath('../../GenerateData/Data/MPC/Data/'); % Data 21 | 22 | % Algorithms to be compared 23 | addpath('../../'); 24 | addpath('../../KekatosADMM'); 25 | addpath('../../SpecialPurposeAlgs/BoydADMM'); 26 | addpath('../../SpecialPurposeAlgs/NesterovMethod'); 27 | 28 | % Solvers and auxiliary functions 29 | addpath('../../UsageExamples/MPC_PowerGrid'); 30 | addpath('../../SpecialPurposeAlgs/NesterovMethod/MPC'); 31 | 32 | file_networks = 'Barabasi_P_2000.mat'; 33 | file_data = 'Barab_P_2000_STABLE.mat'; 34 | % ========================================================================= 35 | 36 | 37 | % ========================================================================= 38 | % Extract Data 39 | 40 | % Load files 41 | load(file_networks); 42 | load(file_data); 43 | 44 | pos_iter_errors = -log10(eps_opt); % Corresponding row in iter_for_errors 45 | 46 | len_rhos = length(rhos); 47 | 48 | % Network data 49 | P = Network.P; 50 | Adj = Network.Adj; 51 | Num_Colors = Network.Num_Colors; 52 | Partition = Network.Partition; 53 | Neighbors = Network.Neighbors; 54 | Degrees = Network.Degrees; 55 | 56 | centers = kron(1:P,ones(1,T*m_p)); 57 | % ========================================================================= 58 | 59 | 60 | % ========================================================================= 61 | % vars_prob for all algorithms 62 | 63 | % ********************************************************** 64 | % D-ADMM, Kekatos, and BoydADMM 65 | 66 | vars_prob = struct('handler', {@SolverMPC}, ... 67 | 'components', {components}, ... 68 | 'centers', {centers}, ... % For Boyd's algorithm 69 | 'E_p', {E_p}, ... 70 | 'w_p', {w_p} ... 71 | ); 72 | 73 | vars_network = struct('P', {P}, ... 74 | 'neighbors', {Neighbors}, ... 75 | 'partition_colors', {Partition} ... 76 | ); 77 | % ********************************************************** 78 | 79 | % ********************************************************** 80 | % Gradient and Nesterov Methods 81 | 82 | vars_prob_Grad = struct('gradients', {@GradientsMPC}, ... 83 | 'proj_constraints', {@projConsMPC}, ... 84 | 'components', {components}, ... 85 | 'centers', {centers}, ... 86 | 'E_p', {E_p}, ... 87 | 'w_p', {w_p} ... 88 | ); 89 | % ========================================================================= 90 | 91 | 92 | % ========================================================================= 93 | % Execute Algorithms 94 | 95 | 96 | %****************************************************************** 97 | % DADMM_Partial 98 | errors_DADMM_Partial = 0; 99 | best_rhos_DADMM_Partial = 0; 100 | iter_for_errors_DADMM_Partial = 0; 101 | 102 | best_iter_DADMM_Partial = Inf; 103 | for i_rhos = 1 : len_rhos 104 | 105 | % Optional input 106 | ops = struct('rho', {rhos(i_rhos)}, ... 107 | 'max_iter', {max_communications}, ... 108 | 'x_opt', {solution}, ... 109 | 'eps_opt', {eps_opt} ... 110 | ); 111 | 112 | fprintf('DADMM_Partial: start\n'); 113 | [X_DADMM_Partial, vars_prob_DADMM_Partial, ops_out] = ... 114 | DADMM_Partial(length(solution), vars_prob, vars_network, ops); 115 | fprintf('DADMM_Partial: finish\n'); 116 | 117 | iterations = ops_out.iterations; 118 | stop_crit = ops_out.stop_crit; 119 | error_iterations = ops_out.error_iterations; 120 | iter_for_errors = ops_out.iter_for_errors; 121 | 122 | fprintf('Number of iterations = %d\n', iterations); 123 | fprintf('stop_crit = %s\n', stop_crit); 124 | for i_g = 1 : 6 125 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 126 | end 127 | 128 | if iter_for_errors(pos_iter_errors,2) < best_iter_DADMM_Partial 129 | best_iter_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 130 | errors_DADMM_Partial = error_iterations; 131 | best_rhos_DADMM_Partial = rhos(i_rhos); 132 | iter_for_errors_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 133 | end 134 | end 135 | %****************************************************************** 136 | 137 | 138 | %****************************************************************** 139 | % Kekatos ADMM 140 | errors_KekatosADMM = 0; 141 | best_rhos_KekatosADMM = 0; 142 | iter_for_errors_KekatosADMM = 0; 143 | 144 | best_iter_KekatosADMM = Inf; 145 | for i_rhos = 1 : len_rhos 146 | 147 | % Optional input 148 | ops = struct('rho', {rhos(i_rhos)}, ... 149 | 'max_iter', {max_communications}, ... 150 | 'x_opt', {solution}, ... 151 | 'eps_opt', {eps_opt} ... 152 | ); 153 | 154 | fprintf('KekatosADMM: start\n'); 155 | [X_KekatosADMM, vars_prob_KekatosADMM, ops_out] = ... 156 | KekatosADMM(length(solution), vars_prob, vars_network, ops); 157 | fprintf('KekatosADMM: finish\n'); 158 | 159 | iterations = ops_out.iterations; 160 | stop_crit = ops_out.stop_crit; 161 | error_iterations = ops_out.error_iterations; 162 | iter_for_errors = ops_out.iter_for_errors; 163 | 164 | fprintf('Number of iterations = %d\n', iterations); 165 | fprintf('stop_crit = %s\n', stop_crit); 166 | for i_g = 1 : 6 167 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 168 | end 169 | 170 | if iter_for_errors(pos_iter_errors,2) < best_iter_KekatosADMM 171 | best_iter_KekatosADMM = iter_for_errors(pos_iter_errors,2); 172 | errors_KekatosADMM = error_iterations; 173 | best_rhos_KekatosADMM = rhos(i_rhos); 174 | iter_for_errors_KekatosADMM = iter_for_errors(pos_iter_errors,2); 175 | end 176 | end 177 | %****************************************************************** 178 | 179 | 180 | %****************************************************************** 181 | % BoydADMM 182 | errors_BoydADMM = 0; 183 | best_rhos_BoydADMM = 0; 184 | iter_for_errors_BoydADMM = 0; 185 | 186 | best_iter_BoydADMM = Inf; 187 | for i_rhos = 1 : len_rhos 188 | 189 | % Optional input 190 | ops = struct('rho', {rhos(i_rhos)}, ... 191 | 'max_iter', {max_communications}, ... 192 | 'x_opt', {solution}, ... 193 | 'eps_opt', {eps_opt} ... 194 | ); 195 | 196 | fprintf('BoydADMM: start\n'); 197 | [X_BoydADMM, vars_prob_BoydADMM, ops_out] = ... 198 | BoydADMM(length(solution), vars_prob, vars_network, ops); 199 | fprintf('BoydADMM: finish\n'); 200 | 201 | iterations = ops_out.iterations; 202 | stop_crit = ops_out.stop_crit; 203 | error_iterations = ops_out.error_iterations; 204 | iter_for_errors = ops_out.iter_for_errors; 205 | 206 | fprintf('Number of iterations = %d\n', iterations); 207 | fprintf('stop_crit = %s\n', stop_crit); 208 | for i_g = 1 : 6 209 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 210 | end 211 | 212 | if iter_for_errors(pos_iter_errors,2) < best_iter_BoydADMM 213 | best_iter_BoydADMM = iter_for_errors(pos_iter_errors,2); 214 | errors_BoydADMM = error_iterations; 215 | best_rhos_BoydADMM = rhos(i_rhos); 216 | iter_for_errors_BoydADMM = iter_for_errors(pos_iter_errors,2); 217 | end 218 | end 219 | %****************************************************************** 220 | 221 | 222 | %****************************************************************** 223 | % Nesterov Method 224 | 225 | % Optional input 226 | ops = struct('max_iter', {max_communications}, ... 227 | 'x_opt', {solution}, ... 228 | 'eps_opt', {eps_opt} ... 229 | ); 230 | 231 | fprintf('Nesterov: start\n'); 232 | [X_Nest, vars_prob_Grad, ops_out] = NesterovMethod(length(solution), Lipschitz, ... 233 | vars_prob_Grad, vars_network, ops); 234 | fprintf('Nesterov: finish\n'); 235 | 236 | iterations = ops_out.iterations; 237 | stop_crit = ops_out.stop_crit; 238 | error_iterations = ops_out.error_iterations; 239 | iter_for_errors = ops_out.iter_for_errors; 240 | 241 | fprintf('Number of iterations = %d\n', iterations); 242 | fprintf('stop_crit = %s\n', stop_crit); 243 | for i_g = 1 : 6 244 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 245 | end 246 | 247 | errors_NesterovMethod = error_iterations; 248 | iter_for_errors_NesterovMethod = iter_for_errors(pos_iter_errors,2); 249 | %****************************************************************** 250 | 251 | 252 | % ========================================================================= 253 | 254 | 255 | % ========================================================================= 256 | % Save data 257 | save(FILE_SAVE, 'rhos', 'max_communications', 'eps_opt', ... 258 | 'errors_DADMM_Partial', 'best_rhos_DADMM_Partial', 'iter_for_errors_DADMM_Partial', ... 259 | 'errors_KekatosADMM', 'best_rhos_KekatosADMM', 'iter_for_errors_KekatosADMM', ... 260 | 'errors_BoydADMM', 'best_rhos_BoydADMM', 'iter_for_errors_BoydADMM', ... 261 | 'errors_NesterovMethod', 'iter_for_errors_NesterovMethod' ... 262 | ); 263 | % ========================================================================= 264 | 265 | 266 | figure(1);clf; 267 | semilogy(errors_DADMM_Partial, 'b-'); 268 | hold on; 269 | semilogy(errors_KekatosADMM, 'r-'); 270 | semilogy(errors_BoydADMM, 'k-'); 271 | semilogy(errors_NesterovMethod, 'c-'); 272 | legend('DADMMp', 'Kekatos', 'Boyd', 'Nesterov') 273 | drawnow; 274 | 275 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /CompareAlgs/MPC/RunExperiments_PowerGrid.m: -------------------------------------------------------------------------------- 1 | 2 | % Filename for saving data 3 | FILE_SAVE = 'Results/PowerGrid_Stable.mat'; 4 | 5 | % ========================================================================= 6 | % Execution parameters of the algorithms: 7 | 8 | max_communications = 1000; 9 | eps_opt = 1e-4; % Has to be one of {1e-1, 1e-2, ..., 1e-9, 1e-10} 10 | 11 | % We will select the rho that is best for 1e-4 of accuracy 12 | %rhos = [20, 25, 30, 35]; 13 | rho_DADMM = 25; % All rhos selected with precision +/-5 14 | rho_Kekatos = 30; 15 | rho_Boyd = 25; 16 | % ========================================================================= 17 | 18 | 19 | % ========================================================================= 20 | % Directories and filenames 21 | 22 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 23 | addpath('../../GenerateData/Data/MPC/Data/'); % Data 24 | 25 | % Algorithms to be compared 26 | addpath('../../'); 27 | addpath('../../KekatosADMM'); 28 | addpath('../../SpecialPurposeAlgs/BoydADMM'); 29 | addpath('../../SpecialPurposeAlgs/NesterovMethod'); 30 | 31 | % Solvers and auxiliary functions 32 | addpath('../../UsageExamples/MPC_PowerGrid'); 33 | addpath('../../SpecialPurposeAlgs/NesterovMethod/MPC'); 34 | 35 | file_networks = 'Network_PowerGrid.mat'; 36 | file_data = 'MPC_PGrid_P_4941_STABLE.mat'; 37 | % ========================================================================= 38 | 39 | % ========================================================================= 40 | % Extract Data 41 | 42 | % Load files 43 | load(file_networks); 44 | load(file_data); 45 | 46 | pos_iter_errors = -log10(eps_opt); % Corresponding row in iter_for_errors 47 | 48 | % Network data 49 | P = Network.P; 50 | Adj = Network.Adj; 51 | Num_Colors = Network.Num_Colors; 52 | Partition = Network.Partition; 53 | Neighbors = Network.Neighbors; 54 | Degrees = Network.Degrees; 55 | 56 | centers = kron(1:P,ones(1,T*m_p)); 57 | % ========================================================================= 58 | 59 | 60 | % ========================================================================= 61 | % vars_prob for all algorithms 62 | 63 | % ********************************************************** 64 | % D-ADMM, Kekatos, and BoydADMM 65 | 66 | vars_prob = struct('handler', {@SolverMPC}, ... 67 | 'components', {components}, ... 68 | 'centers', {centers}, ... % For Boyd's algorithm 69 | 'E_p', {E_p}, ... 70 | 'w_p', {w_p} ... 71 | ); 72 | 73 | 74 | vars_network = struct('P', {P}, ... 75 | 'neighbors', {Neighbors}, ... 76 | 'partition_colors', {Partition} ... 77 | ); 78 | % ********************************************************** 79 | 80 | % ********************************************************** 81 | % Gradient and Nesterov Methods 82 | 83 | vars_prob_Grad = struct('gradients', {@GradientsMPC}, ... 84 | 'proj_constraints', {@projConsMPC}, ... 85 | 'components', {components}, ... 86 | 'centers', {centers}, ... 87 | 'E_p', {E_p}, ... 88 | 'w_p', {w_p} ... 89 | ); 90 | 91 | % ========================================================================= 92 | 93 | 94 | % ========================================================================= 95 | % Execute Algorithms 96 | 97 | 98 | %****************************************************************** 99 | % DADMM_Partial 100 | 101 | % Optional input 102 | ops = struct('rho', {rho_DADMM}, ... 103 | 'max_iter', {max_communications}, ... 104 | 'x_opt', {solution}, ... 105 | 'eps_opt', {eps_opt} ... 106 | ); 107 | 108 | fprintf('DADMM_Partial: start\n'); 109 | [X_DADMM_Partial, vars_prob_DADMM_Partial, ops_out] = ... 110 | DADMM_Partial(length(solution), vars_prob, vars_network, ops); 111 | fprintf('DADMM_Partial: finish\n'); 112 | 113 | iterations = ops_out.iterations; 114 | stop_crit = ops_out.stop_crit; 115 | error_iterations = ops_out.error_iterations; 116 | iter_for_errors = ops_out.iter_for_errors; 117 | 118 | fprintf('Number of iterations = %d\n', iterations); 119 | fprintf('stop_crit = %s\n', stop_crit); 120 | for i_g = 1 : 6 121 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 122 | end 123 | 124 | errors_DADMM_Partial = error_iterations; 125 | best_rhos_DADMM_Partial = rho_DADMM; 126 | iter_for_errors_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 127 | %****************************************************************** 128 | 129 | 130 | %****************************************************************** 131 | % Kekatos ADMM 132 | 133 | % Optional input 134 | ops = struct('rho', {rho_Kekatos}, ... 135 | 'max_iter', {max_communications}, ... 136 | 'x_opt', {solution}, ... 137 | 'eps_opt', {eps_opt} ... 138 | ); 139 | 140 | fprintf('KekatosADMM: start\n'); 141 | [X_KekatosADMM, vars_prob_KekatosADMM, ops_out] = ... 142 | KekatosADMM(length(solution), vars_prob, vars_network, ops); 143 | fprintf('KekatosADMM: finish\n'); 144 | 145 | iterations = ops_out.iterations; 146 | stop_crit = ops_out.stop_crit; 147 | error_iterations = ops_out.error_iterations; 148 | iter_for_errors = ops_out.iter_for_errors; 149 | 150 | fprintf('Number of iterations = %d\n', iterations); 151 | fprintf('stop_crit = %s\n', stop_crit); 152 | for i_g = 1 : 6 153 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 154 | end 155 | 156 | errors_KekatosADMM = error_iterations; 157 | best_rhos_KekatosADMM = rho_Kekatos; 158 | iter_for_errors_KekatosADMM = iter_for_errors(pos_iter_errors,2); 159 | %****************************************************************** 160 | 161 | 162 | %****************************************************************** 163 | % BoydADMM 164 | 165 | % Optional input 166 | ops = struct('rho', {rho_Boyd}, ... 167 | 'max_iter', {max_communications}, ... 168 | 'x_opt', {solution}, ... 169 | 'eps_opt', {eps_opt} ... 170 | ); 171 | 172 | fprintf('BoydADMM: start\n'); 173 | [X_BoydADMM, vars_prob_BoydADMM, ops_out] = ... 174 | BoydADMM(length(solution), vars_prob, vars_network, ops); 175 | fprintf('BoydADMM: finish\n'); 176 | 177 | iterations = ops_out.iterations; 178 | stop_crit = ops_out.stop_crit; 179 | error_iterations = ops_out.error_iterations; 180 | iter_for_errors = ops_out.iter_for_errors; 181 | 182 | fprintf('Number of iterations = %d\n', iterations); 183 | fprintf('stop_crit = %s\n', stop_crit); 184 | for i_g = 1 : 6 185 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 186 | end 187 | 188 | errors_BoydADMM = error_iterations; 189 | best_rhos_BoydADMM = rho_Boyd; 190 | iter_for_errors_BoydADMM = iter_for_errors(pos_iter_errors,2); 191 | %****************************************************************** 192 | 193 | 194 | %****************************************************************** 195 | % Nesterov Method 196 | 197 | % Optional input 198 | ops = struct('max_iter', {max_communications}, ... 199 | 'x_opt', {solution}, ... 200 | 'eps_opt', {eps_opt} ... 201 | ); 202 | 203 | fprintf('Nesterov: start\n'); 204 | [X_Nest, vars_prob_Grad, ops_out] = NesterovMethod(length(solution), Lipschitz, ... 205 | vars_prob_Grad, vars_network, ops); 206 | fprintf('Nesterov: finish\n'); 207 | 208 | iterations = ops_out.iterations; 209 | stop_crit = ops_out.stop_crit; 210 | error_iterations = ops_out.error_iterations; 211 | iter_for_errors = ops_out.iter_for_errors; 212 | 213 | fprintf('Number of iterations = %d\n', iterations); 214 | fprintf('stop_crit = %s\n', stop_crit); 215 | for i_g = 1 : 6 216 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 217 | end 218 | 219 | errors_NesterovMethod = error_iterations; 220 | iter_for_errors_NesterovMethod = iter_for_errors(pos_iter_errors,2); 221 | %****************************************************************** 222 | 223 | % ========================================================================= 224 | 225 | 226 | 227 | % ========================================================================= 228 | % Save data 229 | save(FILE_SAVE, 'rho_DADMM', 'rho_Kekatos', 'rho_Boyd', 'max_communications', 'eps_opt', ... 230 | 'errors_DADMM_Partial', 'best_rhos_DADMM_Partial', 'iter_for_errors_DADMM_Partial', ... 231 | 'errors_KekatosADMM', 'best_rhos_KekatosADMM', 'iter_for_errors_KekatosADMM', ... 232 | 'errors_BoydADMM', 'best_rhos_BoydADMM', 'iter_for_errors_BoydADMM', ... 233 | 'errors_NesterovMethod', 'iter_for_errors_NesterovMethod' ... 234 | ); 235 | % ========================================================================= 236 | 237 | 238 | figure(1);clf; 239 | semilogy(errors_DADMM_Partial, 'b-'); 240 | hold on; 241 | semilogy(errors_KekatosADMM, 'r-'); 242 | semilogy(errors_BoydADMM, 'k-'); 243 | semilogy(errors_NesterovMethod, 'c-'); 244 | legend('DADMMp', 'Kekatos', 'Boyd', 'Nesterov') 245 | drawnow; 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /CompareAlgs/MPC/RunExperiments_PowerGrid_NonStar.m: -------------------------------------------------------------------------------- 1 | 2 | % Filename for saving data 3 | FILE_SAVE = 'Results/PowerGrid_Stable_NonStar.mat'; 4 | 5 | % ========================================================================= 6 | % Execution parameters of the algorithms: 7 | 8 | max_communications = 200; 9 | eps_opt = 1e-4; % Has to be one of {1e-1, 1e-2, ..., 1e-9, 1e-10} 10 | 11 | % We will select the rho that is best for 1e-4 of accuracy 12 | rho_DADMM = [22, 23, 24]; % All rhos selected with precision +/-1 13 | rho_Kekatos = [22, 23, 24]; 14 | % ========================================================================= 15 | 16 | 17 | % ========================================================================= 18 | % Directories and filenames 19 | 20 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 21 | addpath('../../GenerateData/Data/MPC/Data/'); % Data 22 | 23 | % Algorithms to be compared 24 | addpath('../../'); 25 | addpath('../../KekatosADMM'); 26 | addpath('../../SpecialPurposeAlgs/BoydADMM'); 27 | addpath('../../SpecialPurposeAlgs/NesterovMethod'); 28 | 29 | % Solvers and auxiliary functions 30 | addpath('../../UsageExamples/MPC_PowerGrid'); 31 | addpath('../../SpecialPurposeAlgs/NesterovMethod/MPC'); 32 | 33 | file_networks = 'Network_PowerGrid.mat'; 34 | file_data = 'PGrid_NonStar_P_4941_STABLE.mat'; 35 | % ========================================================================= 36 | 37 | 38 | % ========================================================================= 39 | % Extract Data 40 | 41 | % Load files 42 | load(file_networks); 43 | load(file_data); 44 | 45 | pos_iter_errors = -log10(eps_opt); % Corresponding row in iter_for_errors 46 | 47 | % Network data 48 | P = Network.P; 49 | Adj = Network.Adj; 50 | Num_Colors = Network.Num_Colors; 51 | Partition = Network.Partition; 52 | Neighbors = Network.Neighbors; 53 | Degrees = Network.Degrees; 54 | 55 | centers = kron(1:P,ones(1,T*m_p)); 56 | % ========================================================================= 57 | 58 | 59 | % ========================================================================= 60 | % vars_prob for all algorithms 61 | 62 | % ********************************************************** 63 | % D-ADMM, Kekatos, and BoydADMM 64 | 65 | vars_prob = struct('handler', {@SolverMPC}, ... 66 | 'components', {components}, ... 67 | 'centers', {centers}, ... % For Boyd's algorithm 68 | 'E_p', {E_p}, ... 69 | 'w_p', {w_p} ... 70 | ); 71 | 72 | vars_network = struct('P', {P}, ... 73 | 'neighbors', {Neighbors}, ... 74 | 'partition_colors', {Partition} ... 75 | ); 76 | % ********************************************************** 77 | 78 | % ********************************************************** 79 | % Gradient and Nesterov Methods 80 | 81 | vars_prob_Grad = struct('gradients', {@GradientsMPC}, ... 82 | 'proj_constraints', {@projConsMPC}, ... 83 | 'components', {components}, ... 84 | 'centers', {centers}, ... 85 | 'E_p', {E_p}, ... 86 | 'w_p', {w_p} ... 87 | ); 88 | % ========================================================================= 89 | 90 | 91 | % ========================================================================= 92 | % Execute Algorithms 93 | 94 | 95 | %****************************************************************** 96 | % DADMM_Partial 97 | 98 | errors_DADMM_Partial = 0; 99 | best_rhos_DADMM_Partial = 0; 100 | iter_for_errors_DADMM_Partial = 0; 101 | 102 | best_iter_DADMM_Partial = Inf; 103 | 104 | len_rhos_DADMM = length(rho_DADMM); 105 | 106 | for i_rhos = 1 : len_rhos_DADMM 107 | % Optional input 108 | ops = struct('rho', {rho_DADMM(i_rhos)}, ... 109 | 'max_iter', {max_communications}, ... 110 | 'x_opt', {solution}, ... 111 | 'eps_opt', {eps_opt} ... 112 | ); 113 | 114 | fprintf('DADMM_Partial: start\n'); 115 | [X_DADMM_Partial, vars_prob_DADMM_Partial, ops_out] = ... 116 | DADMM_Partial(length(solution), vars_prob, vars_network, ops); 117 | fprintf('DADMM_Partial: finish\n'); 118 | 119 | iterations = ops_out.iterations; 120 | stop_crit = ops_out.stop_crit; 121 | error_iterations = ops_out.error_iterations; 122 | iter_for_errors = ops_out.iter_for_errors; 123 | 124 | fprintf('Number of iterations = %d\n', iterations); 125 | fprintf('stop_crit = %s\n', stop_crit); 126 | for i_g = 1 : 6 127 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 128 | end 129 | 130 | if iter_for_errors(pos_iter_errors,2) < best_iter_DADMM_Partial 131 | best_iter_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 132 | errors_DADMM_Partial = error_iterations; 133 | best_rhos_DADMM_Partial = rho_DADMM(i_rhos); 134 | iter_for_errors_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 135 | end 136 | end 137 | %****************************************************************** 138 | 139 | 140 | %****************************************************************** 141 | % Kekatos ADMM 142 | 143 | errors_KekatosADMM = 0; 144 | best_rhos_KekatosADMM = 0; 145 | iter_for_errors_KekatosADMM = 0; 146 | 147 | best_iter_KekatosADMM = Inf; 148 | 149 | len_rhos_Kekatos = length(rho_Kekatos); 150 | 151 | for i_rhos = 1 : len_rhos_Kekatos 152 | % Optional input 153 | ops = struct('rho', {rho_Kekatos(i_rhos)}, ... 154 | 'max_iter', {max_communications}, ... 155 | 'x_opt', {solution}, ... 156 | 'eps_opt', {eps_opt} ... 157 | ); 158 | 159 | fprintf('KekatosADMM: start\n'); 160 | [X_KekatosADMM, vars_prob_KekatosADMM, ops_out] = ... 161 | KekatosADMM(length(solution), vars_prob, vars_network, ops); 162 | fprintf('KekatosADMM: finish\n'); 163 | 164 | iterations = ops_out.iterations; 165 | stop_crit = ops_out.stop_crit; 166 | error_iterations = ops_out.error_iterations; 167 | iter_for_errors = ops_out.iter_for_errors; 168 | 169 | fprintf('Number of iterations = %d\n', iterations); 170 | fprintf('stop_crit = %s\n', stop_crit); 171 | for i_g = 1 : 6 172 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 173 | end 174 | 175 | if iter_for_errors(pos_iter_errors,2) < best_iter_KekatosADMM 176 | best_iter_KekatosADMM = iter_for_errors(pos_iter_errors,2); 177 | errors_KekatosADMM = error_iterations; 178 | best_rhos_KekatosADMM = rho_Kekatos(i_rhos); 179 | iter_for_errors_KekatosADMM = iter_for_errors(pos_iter_errors,2); 180 | end 181 | 182 | 183 | end 184 | %****************************************************************** 185 | 186 | % ========================================================================= 187 | 188 | 189 | % ========================================================================= 190 | % Save data 191 | save(FILE_SAVE, 'rho_DADMM', 'rho_Kekatos', 'max_communications', 'eps_opt', ... 192 | 'errors_DADMM_Partial', 'best_rhos_DADMM_Partial', 'iter_for_errors_DADMM_Partial', ... 193 | 'errors_KekatosADMM', 'best_rhos_KekatosADMM', 'iter_for_errors_KekatosADMM' ... 194 | ); 195 | % ========================================================================= 196 | 197 | 198 | figure(1);clf; 199 | semilogy(errors_DADMM_Partial, 'b-'); 200 | hold on; 201 | semilogy(errors_KekatosADMM, 'r-'); 202 | legend('DADMMp', 'Kekatos') 203 | drawnow; 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /CompareAlgs/NetworkFlow/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | The script in RunExperiments_NF2000.m reproduces Figure 4 in the paper 3 | 4 | J. Mota, J. Xavier, P. Aguiar, M. Püschel, 5 | Distributed Optimization With Local Domains: Applications in MPC and Network 6 | Flows, to appear in IEEE Transactions on Automatic Control, 2015 7 | 8 | Please note that it might take a long time to run. To execute the same script 9 | on a smaller network (100 nodes), run RunExperiments_NF.m instead. 10 | 11 | -------------------------------------------------------------------------------- /CompareAlgs/NetworkFlow/Results/NetFlow_Barab100.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/NetworkFlow/Results/NetFlow_Barab100.mat -------------------------------------------------------------------------------- /CompareAlgs/NetworkFlow/Results/NetFlow_Barab2000.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/NetworkFlow/Results/NetFlow_Barab2000.mat -------------------------------------------------------------------------------- /CompareAlgs/NetworkFlow/Results/NetFlow_Barab2000.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/CompareAlgs/NetworkFlow/Results/NetFlow_Barab2000.pdf -------------------------------------------------------------------------------- /CompareAlgs/NetworkFlow/RunExperiments_NF2000.m: -------------------------------------------------------------------------------- 1 | 2 | % Filename for saving data 3 | FILE_SAVE = 'Results/NetFlow_Barab2000.mat'; 4 | 5 | % ========================================================================= 6 | % Execution parameters of the algorithms: 7 | 8 | max_communications = 2000; 9 | eps_opt = 1e-4; % Has to be one of {1e-1, 1e-2, ..., 1e-9, 1e-10} 10 | 11 | % We will select the rho that is best for 1e-4 of accuracy 12 | rhos_DADMM = [0.06 0.08 0.10]; 13 | rhos_Kekatos = [0.10 0.12 0.14]; 14 | % Same for the Lipschitz constant 15 | Lips = 15000; 16 | % ========================================================================= 17 | 18 | 19 | % ========================================================================= 20 | % Directories and filenames 21 | 22 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 23 | addpath('../../GenerateData/Data/NetworkFlows/Results/'); % Data 24 | 25 | % Algorithms to be compared 26 | addpath('../../'); 27 | addpath('../../KekatosADMM'); 28 | addpath('../../SpecialPurposeAlgs/BoydADMM'); 29 | addpath('../../SpecialPurposeAlgs/NesterovMethod'); 30 | 31 | % Solvers and auxiliary functions 32 | addpath('../../UsageExamples/NetworkFlow/'); 33 | addpath('../../SpecialPurposeAlgs/NesterovMethod/NetworkFlow'); 34 | 35 | file_networks = 'Barabasi_P_2000.mat'; 36 | file_data = 'NFData_Barabasi_P_2000.mat'; 37 | % ========================================================================= 38 | 39 | 40 | % ========================================================================= 41 | % Extract Data 42 | 43 | % Load files 44 | load(file_networks); 45 | load(file_data); 46 | 47 | pos_iter_errors = -log10(eps_opt); % Corresponding row in iter_for_errors 48 | 49 | len_rhos = length(rhos_DADMM); 50 | len_Lips = length(Lips); 51 | 52 | Adj = Network.Adj; % Adjacency matrix 53 | partition_colors = Network.Partition; % Color partition of network 54 | P = length(Adj); % Number of nodes 55 | neighbors = Network.Neighbors; 56 | Dp = Network.Degrees; 57 | 58 | % Create struct with network information 59 | vars_network = struct('P', {P}, ... 60 | 'neighbors', {neighbors}, ... 61 | 'partition_colors', {partition_colors} ... 62 | ); 63 | 64 | 65 | % Create vars_prob 66 | B = incidence_matrix; 67 | num_edges = size(incidence_matrix,2); 68 | d = flows; 69 | 70 | components = cell(P,1); 71 | 72 | for p = 1 : P 73 | components{p} = find(B(p,:) ~= 0); 74 | end 75 | % ========================================================================= 76 | 77 | 78 | % ========================================================================= 79 | % vars_prob for all algorithms 80 | 81 | centers_primal = zeros(num_edges,1); 82 | for edge = 1 : num_edges 83 | centers_primal(edge) = find(B(:,edge) == -1); 84 | end 85 | 86 | % For D-ADMM, Kekatos 87 | vars_prob = struct('handler', {@NetFlowSolver}, ... 88 | 'function_eval' , {@Delays_f}, ... 89 | 'gradient_eval' , {@Delays_grad}, ... 90 | 'projection' , {@Delays_proj}, ... 91 | 'NetFlowSolver_proj', {@NetFlowSolver_proj}, ... 92 | 'spg_bb' , {@SPG_BB}, ... 93 | 'components', {components}, ... 94 | 'B', {B}, ... 95 | 'd', {d}, ... 96 | 'capacities', {capacities}, ... 97 | 'centers', {centers_primal}, ... 98 | 'Dp', {Dp} ... 99 | ); 100 | 101 | 102 | % For NesterovMethod 103 | components_Dual = cell(P,1); 104 | for p = 1 : P 105 | components_Dual{p} = sort([neighbors{p}, p]); 106 | end 107 | centers_Dual = (1:P)'; 108 | x_estimate = zeros(num_edges,1); % Will have the current estimate for x 109 | 110 | vars_prob_Nest = struct('components', {components_Dual}, ... 111 | 'centers', {centers_Dual}, ... 112 | 'gradients', {@grads_NetFlowNest}, ... 113 | 'proj_constraints', {@proj_NetFlowNest}, ... 114 | 'B', {B}, ... 115 | 'd', {d}, ... 116 | 'capacities', {capacities}, ... 117 | 'x_estimate', {x_estimate} ... 118 | ); 119 | % ========================================================================= 120 | 121 | 122 | % ========================================================================= 123 | % Execute Algorithms 124 | 125 | %****************************************************************** 126 | % DADMM_Partial 127 | errors_DADMM_Partial = 0; 128 | best_rhos_DADMM_Partial = 0; 129 | iter_for_errors_DADMM_Partial = 0; 130 | 131 | best_iter_DADMM_Partial = Inf; 132 | for i_rhos = 1 : len_rhos 133 | 134 | % Optional input 135 | ops = struct('rho', {rhos_DADMM(i_rhos)}, ... 136 | 'max_iter', {max_communications}, ... 137 | 'x_opt', {solution}, ... 138 | 'eps_opt', {eps_opt} ... 139 | ); 140 | 141 | fprintf('DADMM_Partial: start\n'); 142 | [X_DADMM_Partial, vars_prob_DADMM_Partial, ops_out] = ... 143 | DADMM_Partial(num_edges, vars_prob, vars_network, ops); 144 | fprintf('DADMM_Partial: finish\n'); 145 | 146 | iterations = ops_out.iterations; 147 | stop_crit = ops_out.stop_crit; 148 | error_iterations = ops_out.error_iterations; 149 | iter_for_errors = ops_out.iter_for_errors; 150 | 151 | fprintf('Number of iterations = %d\n', iterations); 152 | fprintf('stop_crit = %s\n', stop_crit); 153 | for i_g = 1 : 6 154 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 155 | end 156 | 157 | if iter_for_errors(pos_iter_errors,2) < best_iter_DADMM_Partial 158 | best_iter_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 159 | errors_DADMM_Partial = error_iterations; 160 | best_rhos_DADMM_Partial = rhos_DADMM(i_rhos); 161 | iter_for_errors_DADMM_Partial = iter_for_errors(pos_iter_errors,2); 162 | end 163 | end 164 | %****************************************************************** 165 | 166 | 167 | %****************************************************************** 168 | % Kekatos ADMM 169 | errors_KekatosADMM = 0; 170 | best_rhos_KekatosADMM = 0; 171 | iter_for_errors_KekatosADMM = 0; 172 | 173 | best_iter_KekatosADMM = Inf; 174 | for i_rhos = 1 : len_rhos 175 | 176 | % Optional input 177 | ops = struct('rho', {rhos_Kekatos(i_rhos)}, ... 178 | 'max_iter', {max_communications}, ... 179 | 'x_opt', {solution}, ... 180 | 'eps_opt', {eps_opt} ... 181 | ); 182 | 183 | fprintf('KekatosADMM: start\n'); 184 | [X_KekatosADMM, vars_prob_KekatosADMM, ops_out] = ... 185 | KekatosADMM(num_edges, vars_prob, vars_network, ops); 186 | fprintf('KekatosADMM: finish\n'); 187 | 188 | iterations = ops_out.iterations; 189 | stop_crit = ops_out.stop_crit; 190 | error_iterations = ops_out.error_iterations; 191 | iter_for_errors = ops_out.iter_for_errors; 192 | 193 | fprintf('Number of iterations = %d\n', iterations); 194 | fprintf('stop_crit = %s\n', stop_crit); 195 | for i_g = 1 : 6 196 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 197 | end 198 | 199 | if iter_for_errors(pos_iter_errors,2) < best_iter_KekatosADMM 200 | best_iter_KekatosADMM = iter_for_errors(pos_iter_errors,2); 201 | errors_KekatosADMM = error_iterations; 202 | best_rhos_KekatosADMM = rhos_Kekatos(i_rhos); 203 | iter_for_errors_KekatosADMM = iter_for_errors(pos_iter_errors,2); 204 | end 205 | end 206 | %****************************************************************** 207 | 208 | 209 | %****************************************************************** 210 | % Nesterov Method 211 | 212 | errors_NesterovMethod = 0; 213 | best_Lips_NesterovMethod = 0; 214 | iter_for_errors_NesterovMethod = 0; 215 | 216 | best_iter_Nesterov = Inf; 217 | for i_Lip = 1 : len_Lips 218 | 219 | Lipschitz = Lips(i_Lip); 220 | 221 | % Optional input 222 | ops = struct('max_iter', {max_communications}, ... 223 | 'x_opt', {solution}, ... 224 | 'error_fun', {@Error_gradNetFlow}, ... 225 | 'eps_opt', {eps_opt} ... 226 | ); 227 | 228 | fprintf('Nesterov: start\n'); 229 | cd(dir_NesterovMethod); 230 | [X_Nest, vars_prob_Nest, ops_out] = NesterovMethod(P, Lipschitz, ... 231 | vars_prob_Nest, vars_network, ops); 232 | cd(dir_current); 233 | fprintf('Nesterov: finish\n'); 234 | 235 | iterations = ops_out.iterations; 236 | stop_crit = ops_out.stop_crit; 237 | error_iterations = ops_out.error_iterations; 238 | iter_for_errors = ops_out.iter_for_errors; 239 | 240 | fprintf('Number of iterations = %d\n', iterations); 241 | fprintf('stop_crit = %s\n', stop_crit); 242 | for i_g = 1 : 6 243 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 244 | end 245 | 246 | if iter_for_errors(pos_iter_errors,2) < best_iter_Nesterov 247 | best_iter_Nesterov = iter_for_errors(pos_iter_errors,2); 248 | errors_NesterovMethod = error_iterations; 249 | best_Lips_NesterovMethod = Lips(i_Lip); 250 | iter_for_errors_NesterovMethod = iter_for_errors(pos_iter_errors,2); 251 | end 252 | 253 | % It does not reach 1e-4, se record it here 254 | errors_NesterovMethod = error_iterations; 255 | best_Lips_NesterovMethod = Lips(i_Lip); 256 | iter_for_errors_NesterovMethod = iter_for_errors(pos_iter_errors,2); 257 | end 258 | %****************************************************************** 259 | % ========================================================================= 260 | 261 | 262 | % ========================================================================= 263 | % Save data 264 | save(FILE_SAVE, 'rhos_DADMM', 'rhos_Kekatos', 'Lips', 'max_communications', 'eps_opt', ... 265 | 'errors_DADMM_Partial', 'best_rhos_DADMM_Partial', 'iter_for_errors_DADMM_Partial', ... 266 | 'errors_KekatosADMM', 'best_rhos_KekatosADMM', 'iter_for_errors_KekatosADMM', ... 267 | 'errors_NesterovMethod', 'best_Lips_NesterovMethod', 'iter_for_errors_NesterovMethod' ... 268 | ); 269 | % ========================================================================= 270 | 271 | 272 | figure(1);clf; 273 | semilogy(errors_DADMM_Partial, 'b-'); 274 | hold on; 275 | semilogy(errors_KekatosADMM, 'r-'); 276 | semilogy(errors_NesterovMethod(2:end), 'c-'); 277 | legend('DADMMp', 'Kekatos', 'Nesterov') 278 | drawnow; 279 | 280 | 281 | 282 | 283 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_NonStar_P_100_STABLE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Data/Barab_NonStar_P_100_STABLE.mat -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_NonStar_P_100_STABLE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------- 2 | Statistics about the Data in: Data/Barab_NonStar_P_100_STABLE.mat 3 | 4 | Path to Network: ../../../Networks/MPC/ProcessedNetwork/Barabasi_P_100.mat 5 | 6 | Parameters defined by the user: 7 | STABLE: 1 8 | T: 5 9 | n_p: 3 10 | m_p: 1 11 | Lipschitz: 2312.4839 12 | 13 | -------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_NonStar_P_100_UNSTABLE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Data/Barab_NonStar_P_100_UNSTABLE.mat -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_NonStar_P_100_UNSTABLE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------- 2 | Statistics about the Data in: Data/Barab_NonStar_P_100_UNSTABLE.mat 3 | 4 | Path to Network: ../../../Networks/MPC/ProcessedNetwork/Barabasi_P_100.mat 5 | 6 | Parameters defined by the user: 7 | STABLE: 0 8 | T: 5 9 | n_p: 3 10 | m_p: 1 11 | Lipschitz: 930293.0597 12 | 13 | -------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_NonStar_P_6_STABLE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Data/Barab_NonStar_P_6_STABLE.mat -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_NonStar_P_6_STABLE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------- 2 | Statistics about the Data in: Data/Barab_NonStar_P_6_STABLE.mat 3 | 4 | Path to Network: ../../../Networks/MPC/ProcessedNetwork/Barabasi_P_6.mat 5 | 6 | Parameters defined by the user: 7 | STABLE: 1 8 | T: 1 9 | n_p: 3 10 | m_p: 1 11 | Lipschitz: 166.1058 12 | 13 | -------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_P_100_STABLE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Data/Barab_P_100_STABLE.mat -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_P_100_STABLE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------- 2 | Statistics about the Data in: Data/Barab_P_100_STABLE.mat 3 | 4 | Path to Network: ../../../Networks/MPC/ProcessedNetwork/Barabasi_P_100.mat 5 | 6 | Parameters defined by the user: 7 | STABLE: 1 8 | T: 5 9 | n_p: 3 10 | m_p: 1 11 | Lipschitz: 2617.9753 12 | 13 | -------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_P_100_UNSTABLE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Data/Barab_P_100_UNSTABLE.mat -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_P_100_UNSTABLE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------- 2 | Statistics about the Data in: Data/Barab_P_100_UNSTABLE.mat 3 | 4 | Path to Network: ../../../Networks/MPC/ProcessedNetwork/Barabasi_P_100.mat 5 | 6 | Parameters defined by the user: 7 | STABLE: 0 8 | T: 5 9 | n_p: 3 10 | m_p: 1 11 | Lipschitz: 1626802.0646 12 | 13 | -------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_P_2000_STABLE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Data/Barab_P_2000_STABLE.mat -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/Barab_P_2000_STABLE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------- 2 | Statistics about the Data in: Data/Barab_P_2000_STABLE.mat 3 | 4 | Path to Network: ../../../Networks/MPC/ProcessedNetwork/Barabasi_P_2000.mat 5 | 6 | Parameters defined by the user: 7 | STABLE: 1 8 | T: 5 9 | n_p: 3 10 | m_p: 1 11 | Lipschitz: 9616.2477 12 | 13 | -------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/MPC_PGrid_P_4941_STABLE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Data/MPC_PGrid_P_4941_STABLE.mat -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/MPC_PGrid_P_4941_STABLE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------- 2 | Statistics about the Data in: Data/MPC_PGrid_P_4941_STABLE.mat 3 | 4 | Path to Network: ../../../Networks/MPC/ProcessedNetwork/Network_PowerGrid.mat 5 | 6 | Parameters defined by the user: 7 | STABLE: 1 8 | T: 5 9 | n_p: 3 10 | m_p: 1 11 | Lipschitz: 3395.3557 12 | 13 | -------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/PGrid_NonStar_P_4941_STABLE.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Data/PGrid_NonStar_P_4941_STABLE.mat -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Data/PGrid_NonStar_P_4941_STABLE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------- 2 | Statistics about the Data in: Data/PGrid_NonStar_P_4941_STABLE.mat 3 | 4 | Path to Network: ../../../Networks/MPC/ProcessedNetwork/Network_PowerGrid.mat 5 | 6 | Parameters defined by the user: 7 | STABLE: 1 8 | T: 5 9 | n_p: 3 10 | m_p: 1 11 | Lipschitz: 3566.8452 12 | 13 | -------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Readme/MPC.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Readme/MPC.pdf -------------------------------------------------------------------------------- /GenerateData/Data/MPC/Readme/MPC.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/MPC/Readme/MPC.tex -------------------------------------------------------------------------------- /GenerateData/Data/MPC/genDataMPC.m: -------------------------------------------------------------------------------- 1 | % Generates data for the MPC problem, given 2 | % 3 | % T: horizon of the MPC problem 4 | % 5 | % n_p: dimension of the state at each subsystem 6 | % 7 | % m_p: dimension of the input at each subsystem 8 | % 9 | % 10 | % The variable has the following format: 11 | % 12 | % var = [ u_1 ; % each with dim = m_p*T 13 | % u_2 ; 14 | % ... 15 | % u_P ] 16 | % 17 | % 18 | % This script also creates the factor graph for the problem. 19 | 20 | % ========================================================================= 21 | % Filenames 22 | 23 | % Network (Power grid) 24 | PATH_NETWORK = '../../Networks/MPC/ProcessedNetwork/'; 25 | 26 | FILENAME_NETWORK = 'Barabasi_P_100.mat'; 27 | %FILENAME_NETWORK = 'Barabasi_P_2000.mat'; 28 | %FILENAME_NETWORK = 'Network_PowerGrid.mat'; 29 | 30 | 31 | % Base to file for storing the data (.mat will be added) 32 | FILENAME_OUTPUT_BASE = 'Data/Barab'; 33 | %FILENAME_OUTPUT_BASE = 'Data/MPC_PGrid'; 34 | % ========================================================================= 35 | 36 | 37 | % ========================================================================= 38 | % Parameters 39 | 40 | STABLE = 0; % If True, each subsystem will be designed to be stable. 41 | 42 | T = 5; % Time horizon 43 | 44 | n_p = 3; % Dimension of each state 45 | 46 | m_p = 1; % Dimension of each control 47 | % ========================================================================= 48 | 49 | 50 | % ========================================================================= 51 | % Load Network 52 | 53 | filename_network = [PATH_NETWORK , FILENAME_NETWORK]; 54 | load(filename_network); 55 | 56 | P = Network.P; 57 | Neighbors = Network.Neighbors; 58 | Dp = Network.Degrees; 59 | % ========================================================================= 60 | 61 | 62 | % ========================================================================= 63 | % Create Factor Graph and Omega 64 | % 65 | % Omega is a P x 1 cell where the pth entry contains the neighbors of node 66 | % p plus node p, all ordered. 67 | 68 | components = cell(P,1); 69 | Omega = cell(P,1); 70 | 71 | ind_u = cell(P,1); % Given a node p gives the indices of u_p 72 | for p = 1 : P 73 | ind_u{p} = 1 + (p-1)*m_p*T : p*m_p*T; 74 | end 75 | 76 | for p = 1 : P 77 | neighbs_p = Neighbors{p}; % Neighbors of node p (only x's) 78 | Dp_p = Dp(p); 79 | 80 | Omega{p} = sort( [Neighbors{p} , p] ); 81 | 82 | comp_p = zeros(m_p*T*(Dp_p+1) , 1); 83 | 84 | for j = 1 : Dp_p 85 | ind = 1 + (j-1)*m_p*T : j*m_p*T; 86 | comp_p(ind) = ind_u{neighbs_p(j)}; 87 | end 88 | 89 | % Add component u of node p 90 | ind = 1 + Dp_p*m_p*T : (Dp_p+1)*m_p*T; 91 | comp_p(ind) = ind_u{p}; 92 | 93 | % Needs sorting (read DADMMp documentation) 94 | components{p} = sort(comp_p); 95 | end 96 | % ========================================================================= 97 | 98 | 99 | % ========================================================================= 100 | % First step: generate the following matrices (all cells Px1): 101 | % 102 | % A_pp: dynamics; the pth entry contains the internal matrix of 103 | % subsystem p 104 | % 105 | % B_pj: influence of input u_j on state x_p (j is as in components) 106 | % 107 | % Q_bar: state cost; each entry contains a vector representing the 108 | % diagonal of a (diagonal) matrix 109 | % 110 | % Q_f_bar: state cost final; same as Q 111 | % 112 | % R_bar: cost of inputs; same as Q 113 | % 114 | % x0: initial/measured state; each entry is a vector 115 | 116 | 117 | A_pp = cell(P,1); 118 | B_pj = cell(P,1); 119 | Q_bar = cell(P,1); 120 | Q_f_bar = cell(P,1); 121 | R_bar = cell(P,1); 122 | x0 = cell(P,1); 123 | 124 | for p = 1 : P 125 | 126 | % Matrix A_pp 127 | if STABLE == 1 % Generate stable subsystems 128 | aux_A_pp = randn(n_p,n_p); 129 | [aux_Q,aux_R] = qr(aux_A_pp); 130 | eigenvals = 2*rand(n_p,1) - ones(n_p,1); % each eig in [-1,1] 131 | A_pp{p} = aux_Q*diag(eigenvals)*aux_Q'; 132 | else 133 | A_pp{p} = randn(n_p,n_p); 134 | end 135 | 136 | 137 | % Matrices B_pj (ordered according to components) 138 | Dp_p = Dp(p); 139 | B_pj{p} = cell(Dp_p+1,1); 140 | 141 | for j = 1 : Dp_p + 1 142 | B_pj{p}{j} = randn(n_p,m_p); 143 | end 144 | 145 | % Matrices Q_bar, Q_f_bar, and R_bar 146 | Q_bar{p} = 9*rand(n_p,1) + ones(n_p,1); 147 | Q_f_bar{p} = 9*rand(n_p,1) + ones(n_p,1); 148 | R_bar{p} = 9*rand(m_p,1) + ones(m_p,1); 149 | 150 | % State initialization s0 151 | x0{p} = randn(n_p,1); 152 | end 153 | % ========================================================================= 154 | 155 | 156 | 157 | % ========================================================================= 158 | % Second step: generate the following matrices (all cells Px1); see the 159 | % documentation 160 | % 161 | % R_p, Q_p, C_p, D_p0, E_p, w_p 162 | % 163 | 164 | R_p = cell(P,1); 165 | Q_p = cell(P,1); 166 | C_p = cell(P,1); 167 | D_p0 = cell(P,1); 168 | E_p = cell(P,1); 169 | w_p = cell(P,1); 170 | 171 | Id_T = ones(T,1); 172 | 173 | for p = 1 : P 174 | 175 | % ********************************************************************* 176 | % Matrices R_p and Q_p (diagonal matrices, so we just store the diag) 177 | 178 | R_p{p} = kron(Id_T, R_bar{p}); 179 | Q_p{p} = [kron(Id_T, Q_bar{p}) ; Q_f_bar{p}]; 180 | % ********************************************************************* 181 | 182 | Dp_p = Dp(p); % Degree of node p 183 | neighbs_p = Neighbors{p}; % Neighbors of node p 184 | B_pj_cat = zeros(n_p,m_p*(Dp_p+1)); % Concatenation of matrices B_pj 185 | 186 | % Perform concatenation of B_pj 187 | for j = 1 : Dp_p + 1 188 | B_pj_cat(: , 1 + (j-1)*m_p : j*m_p) = B_pj{p}{j}; 189 | end 190 | 191 | % ********************************************************************* 192 | % Matrices C_p and D_p0 193 | C_p_aux = zeros( n_p*(T+1) , m_p*T*(Dp_p+1) ); 194 | D_p0_aux = zeros( n_p*(T+1) , 1); 195 | 196 | generating_vec_C = zeros(n_p,m_p*(Dp_p+1)*T); 197 | 198 | powers_of_A_pp = eye(n_p); 199 | 200 | D_p0_aux(1:n_p) = powers_of_A_pp * x0{p}; 201 | 202 | for t = 1 : T % Note: first line of C_p and E_p contains only zeros 203 | 204 | generating_vec_C = circshift(generating_vec_C, [0 m_p*(Dp_p+1)]); 205 | generating_vec_C(: , 1:m_p*(Dp_p+1)) = powers_of_A_pp*B_pj_cat; 206 | 207 | powers_of_A_pp = powers_of_A_pp*A_pp{p}; 208 | 209 | C_p_aux(1 + t*n_p : (t+1)*n_p , :) = generating_vec_C; 210 | 211 | D_p0_aux(1 + t*n_p : (t+1)*n_p) = powers_of_A_pp * x0{p}; 212 | end 213 | 214 | C_p{p} = C_p_aux; 215 | D_p0{p} = D_p0_aux; 216 | % ********************************************************************* 217 | 218 | 219 | % ********************************************************************* 220 | % Finally, matrix E_p and vector w_p 221 | 222 | Omega_p = Omega{p}; 223 | 224 | position_of_p = find(Omega_p == p); 225 | 226 | indices_of_p = 1 + (position_of_p - 1)*m_p*T : position_of_p*m_p*T; 227 | 228 | C_p_T_Q_p = C_p{p}'*diag(Q_p{p}); % Will be used twice 229 | 230 | E_p_aux = C_p_T_Q_p*C_p{p}; 231 | 232 | E_p_aux(indices_of_p, indices_of_p) = ... 233 | E_p_aux(indices_of_p, indices_of_p) + diag(R_p{p}); 234 | 235 | E_p{p} = E_p_aux; 236 | 237 | w_p{p} = 2*C_p_T_Q_p*D_p0{p}; 238 | % ********************************************************************* 239 | end 240 | 241 | 242 | % ========================================================================= 243 | % Compute the solution 244 | 245 | % Construct matrices E_global and w_global 246 | 247 | dim_variable = P*T*m_p; 248 | E_global = zeros(dim_variable , dim_variable); 249 | w_global = zeros(dim_variable , 1); 250 | 251 | for p = 1 : P 252 | ind_p = components{p}; 253 | E_global(ind_p, ind_p) = E_global(ind_p, ind_p) + E_p{p}; 254 | w_global(ind_p) = w_global(ind_p) + w_p{p}; 255 | end 256 | 257 | solution = -0.5*(E_global \ w_global); 258 | % ========================================================================= 259 | 260 | 261 | % ========================================================================= 262 | % Compute Lipschitz constant 263 | Lipschitz = 2*max(eigs(E_global)); 264 | % ========================================================================= 265 | 266 | 267 | % ========================================================================= 268 | % Save 269 | 270 | % Filename 271 | if STABLE == 1 272 | filename_ending = [FILENAME_OUTPUT_BASE, '_P_', num2str(P), '_STABLE']; 273 | else 274 | filename_ending = [FILENAME_OUTPUT_BASE, '_P_', num2str(P), '_UNSTABLE']; 275 | end 276 | 277 | filename_data = [filename_ending, '.mat']; 278 | 279 | save(filename_data, 'R_p', 'Q_p', 'C_p', 'D_p0', 'E_p', 'w_p', ... 280 | 'components', 'Omega', 'T', 'n_p', 'm_p', 'solution', 'Lipschitz', ... 281 | 'A_pp', 'B_pj', 'Q_bar', 'Q_f_bar', 'R_bar', 'x0'); 282 | % ========================================================================= 283 | 284 | % ========================================================================= 285 | % Save Statistics to text file 286 | 287 | filename_stat = [filename_ending, '.txt']; 288 | 289 | all_text = [... 290 | '--------------------------------------------------------------\n' ... 291 | 'Statistics about the Data in: ', filename_data, '\n\n' ... 292 | 'Path to Network: ../', filename_network, '\n\n' ... 293 | 'Parameters defined by the user: \n' ... 294 | ' STABLE: ', num2str(STABLE), '\n' ... 295 | ' T: ', num2str(T), '\n' ... 296 | ' n_p: ', num2str(n_p), '\n' ... 297 | ' m_p: ', num2str(m_p), '\n', ... 298 | ' Lipschitz: ', num2str(Lipschitz), '\n\n', ... 299 | '--------------------------------------------------------------\n']; 300 | 301 | fid = fopen(filename_stat, 'w'); 302 | fprintf(fid, all_text); 303 | fclose(fid); 304 | % ========================================================================= 305 | 306 | 307 | 308 | 309 | 310 | 311 | -------------------------------------------------------------------------------- /GenerateData/Data/NetworkFlows/Results/NFData_Barabasi_P_100.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/NetworkFlows/Results/NFData_Barabasi_P_100.mat -------------------------------------------------------------------------------- /GenerateData/Data/NetworkFlows/Results/NFData_Barabasi_P_100.txt: -------------------------------------------------------------------------------- 1 | pcost dcost gap pres dres 2 | 0: 0.0000e+00 -5.5340e+03 4e+02 1e+00 1e+00 3 | 1: -2.4997e-02 -3.6782e+03 4e+02 1e+00 1e+00 4 | 2: -1.0945e-01 -2.2762e+03 3e+02 1e+00 1e+00 5 | 3: -3.0384e-01 -1.2438e+03 3e+02 9e-01 9e-01 6 | 4: -6.7107e-01 -4.1018e+02 2e+02 9e-01 9e-01 7 | 5: -1.8079e-01 -7.9716e+01 2e+02 7e-01 7e-01 8 | 6: 1.5308e+00 6.9782e+00 1e+02 5e-01 6e-01 9 | 7: 1.3250e+00 1.7794e+00 1e+02 4e-01 5e-01 10 | 8: 2.0079e+00 -4.5715e+00 6e+01 2e-01 2e-01 11 | 9: 1.6433e+00 -2.4797e+00 3e+01 8e-02 1e-01 12 | 10: -4.8562e-01 -4.4786e-01 7e+00 2e-02 5e-02 13 | 11: 2.2192e-01 -4.5808e-01 3e+00 6e-03 2e-02 14 | 12: 6.5663e-01 -5.0799e-03 2e+00 3e-03 1e-02 15 | 13: 9.3461e-01 3.9098e-01 1e+00 2e-03 6e-03 16 | 14: 1.1444e+00 8.0544e-01 6e-01 7e-04 2e-03 17 | 15: 1.2123e+00 9.5747e-01 4e-01 3e-04 9e-04 18 | 16: 1.2142e+00 1.1022e+00 2e-01 8e-05 3e-04 19 | 17: 1.2090e+00 1.1597e+00 5e-02 2e-06 9e-06 20 | 18: 1.1983e+00 1.1873e+00 1e-02 6e-07 2e-06 21 | 19: 1.1964e+00 1.1918e+00 5e-03 2e-07 8e-07 22 | 20: 1.1954e+00 1.1944e+00 1e-03 6e-08 4e-07 23 | 21: 1.1951e+00 1.1950e+00 1e-04 1e-08 2e-07 24 | 22: 1.1951e+00 1.1951e+00 6e-06 2e-09 5e-08 25 | 23: 1.1951e+00 1.1951e+00 2e-07 1e-10 3e-09 26 | Optimal solution found. 27 | 28 | 29 | 30 | -------------------------------------------------- 31 | Data parameters and statistics: 32 | 33 | 34 | 35 | Network file: ../../Networks/MPC/ProcessedNetwork/Barabasi_P_100.mat 36 | 37 | 38 | Number of commodities: 20 39 | Random seed: 1234 40 | Division factor: 100.0 41 | Possible capacities: 42 | 10 : 0.2 43 | 20 : 0.2 44 | 30 : 0.2 45 | 50 : 0.1 46 | 40 : 0.2 47 | 100 : 0.1 48 | 49 | 50 | Lengths of paths in solution of multicommodity flow: 51 | 3 52 | 5 53 | 6 54 | 12 55 | 1 56 | 8 57 | 4 58 | 10 59 | 6 60 | 6 61 | 7 62 | 14 63 | 10 64 | 5 65 | 3 66 | 3 67 | 6 68 | 11 69 | 3 70 | 1 71 | 72 | 73 | -------------------------------------------------------------------------------- /GenerateData/Data/NetworkFlows/Results/NFData_Barabasi_P_2000.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/NetworkFlows/Results/NFData_Barabasi_P_2000.mat -------------------------------------------------------------------------------- /GenerateData/Data/NetworkFlows/Results/NFData_Barabasi_P_2000.txt: -------------------------------------------------------------------------------- 1 | pcost dcost gap pres dres 2 | 0: 0.0000e+00 -1.3553e+05 8e+03 1e+00 1e+00 3 | 1: 2.8064e+00 -8.4893e+04 8e+03 1e+00 1e+00 4 | 2: 6.2257e+00 -5.1618e+04 7e+03 1e+00 1e+00 5 | 3: 6.7634e+00 -3.0295e+04 6e+03 9e-01 9e-01 6 | 4: 1.2078e+00 -1.3261e+04 5e+03 9e-01 9e-01 7 | 5: -7.0070e+00 -4.9789e+03 4e+03 8e-01 8e-01 8 | 6: 2.3137e+00 -1.5116e+03 3e+03 7e-01 7e-01 9 | 7: 2.4430e+01 -2.8685e+02 3e+03 5e-01 5e-01 10 | 8: 3.2597e+01 -1.9747e+02 2e+03 4e-01 4e-01 11 | 9: 5.6061e+01 -2.0032e+02 1e+03 2e-01 3e-01 12 | 10: 5.5693e+01 -6.8472e+01 7e+02 1e-01 1e-01 13 | 11: 1.3429e+01 -1.9753e+01 2e+02 4e-02 8e-02 14 | 12: 1.2787e+01 -3.1646e+01 2e+02 2e-02 5e-02 15 | 13: 1.2974e+01 -2.6131e+01 1e+02 1e-02 3e-02 16 | 14: 1.4775e+01 -1.6425e+01 7e+01 7e-03 1e-02 17 | 15: 1.4892e+01 -4.6478e+00 4e+01 3e-03 6e-03 18 | 16: 1.5238e+01 3.7363e-01 2e+01 2e-03 4e-03 19 | 17: 1.5342e+01 3.2876e+00 2e+01 1e-03 2e-03 20 | 18: 1.4642e+01 7.5211e+00 1e+01 5e-04 1e-03 21 | 19: 1.4252e+01 9.9327e+00 6e+00 2e-04 4e-04 22 | 20: 1.3969e+01 1.0994e+01 4e+00 1e-04 2e-04 23 | 21: 1.3817e+01 1.1529e+01 3e+00 6e-05 1e-04 24 | 22: 1.3624e+01 1.2099e+01 2e+00 3e-05 6e-05 25 | 23: 1.3397e+01 1.2652e+01 9e-01 1e-05 2e-05 26 | 24: 1.3271e+01 1.2941e+01 4e-01 5e-06 1e-05 27 | 25: 1.3188e+01 1.3127e+01 6e-02 1e-07 1e-06 28 | 26: 1.3171e+01 1.3161e+01 1e-02 3e-08 4e-07 29 | 27: 1.3168e+01 1.3167e+01 9e-04 5e-09 1e-07 30 | 28: 1.3168e+01 1.3168e+01 2e-05 4e-10 1e-08 31 | 29: 1.3168e+01 1.3168e+01 4e-07 1e-11 5e-10 32 | Optimal solution found. 33 | 34 | 35 | 36 | -------------------------------------------------- 37 | Data parameters and statistics: 38 | 39 | 40 | 41 | Network file: ../../Networks/MPC/ProcessedNetwork/Barabasi_P_2000.mat 42 | 43 | 44 | Number of commodities: 100 45 | Random seed: 1234 46 | Division factor: 100.0 47 | Possible capacities: 48 | 10 : 0.2 49 | 20 : 0.2 50 | 30 : 0.2 51 | 50 : 0.1 52 | 40 : 0.2 53 | 100 : 0.1 54 | 55 | 56 | Lengths of paths in solution of multicommodity flow: 57 | 4 58 | 8 59 | 12 60 | 5 61 | 17 62 | 10 63 | 41 64 | 13 65 | 13 66 | 1 67 | 44 68 | 20 69 | 41 70 | 25 71 | 9 72 | 24 73 | 14 74 | 12 75 | 19 76 | 7 77 | 15 78 | 1 79 | 38 80 | 37 81 | 19 82 | 15 83 | 10 84 | 10 85 | 28 86 | 11 87 | 14 88 | 4 89 | 9 90 | 17 91 | 11 92 | 9 93 | 22 94 | 10 95 | 19 96 | 12 97 | 18 98 | 11 99 | 6 100 | 12 101 | 8 102 | 13 103 | 1 104 | 16 105 | 10 106 | 15 107 | 35 108 | 10 109 | 28 110 | 7 111 | 2 112 | 9 113 | 10 114 | 9 115 | 15 116 | 9 117 | 6 118 | 35 119 | 21 120 | 31 121 | 18 122 | 5 123 | 6 124 | 14 125 | 6 126 | 1 127 | 6 128 | 21 129 | 31 130 | 9 131 | 14 132 | 12 133 | 7 134 | 16 135 | 1 136 | 18 137 | 17 138 | 20 139 | 31 140 | 14 141 | 34 142 | 12 143 | 10 144 | 19 145 | 23 146 | 19 147 | 7 148 | 3 149 | 12 150 | 9 151 | 6 152 | 11 153 | 7 154 | 10 155 | 20 156 | 1 157 | 158 | 159 | -------------------------------------------------------------------------------- /GenerateData/Data/NetworkFlows/Results/NFData_Barabasi_P_6.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Data/NetworkFlows/Results/NFData_Barabasi_P_6.mat -------------------------------------------------------------------------------- /GenerateData/Data/NetworkFlows/TreatData.m: -------------------------------------------------------------------------------- 1 | % Treats the data for the Network Flow problem: 2 | % 3 | % minimize \sum_{(i,j) in edges} x_ij/(c_ij - x_ij) (1) 4 | % x = {x_ij} 5 | % subject to B*x = d 6 | % 0 <= x <= c, 7 | % 8 | % where B is the node-arc incidence matrix of the graph, c is the vector of 9 | % capacities, and d is the vector of flows. 10 | % 11 | % B, c, d, the network, and the solution of (1) were already computed with 12 | % the Sage script 13 | % 14 | % GenerateNetworkFlows.sage 15 | % 16 | % and the results are stored in the folder Results. 17 | % 18 | % Here, we just treat that data. 19 | 20 | % ========================================================================= 21 | % Filenames (NOTE: THE INPUT FILE WILL BE REWRITTEN) 22 | 23 | FILENAME_DATA_INPUT = 'Results/NFData_Barabasi_P_6.mat'; 24 | FILENAME_DATA_OUTPUT = FILENAME_DATA_INPUT; 25 | % ========================================================================= 26 | 27 | 28 | load(FILENAME_DATA_INPUT); 29 | 30 | capacities = double(capacities); 31 | flows = double(flows); 32 | incidence_matrix = sparse(double(incidence_matrix)); 33 | number_of_commodities = length(solution_mcfp); 34 | node_out_node_in_intensity = double(node_out_node_in_intensity); 35 | 36 | [num_nodes, num_edges] = size(incidence_matrix); 37 | 38 | 39 | save(FILENAME_DATA_OUTPUT, 'capacities', 'flows', 'incidence_matrix', ... 40 | 'num_nodes', 'num_edges', 'number_of_commodities', ... 41 | 'node_out_node_in_intensity', 'solution_mcfp', 'solution') -------------------------------------------------------------------------------- /GenerateData/FactorGraphs/CreateVarPartialConnected.m: -------------------------------------------------------------------------------- 1 | function [FactorGraph] = CreateVarPartialConnected(n, P, neighbors, depth) 2 | 3 | % [FactorGraph] = CreateVarPartialConnected(n, P, neighbors, depth) 4 | % 5 | % Creates a random instance of a problem with a partial connected variable. 6 | % Given a network with P nodes, it implements the following algorithm. For 7 | % each component xl, it chooses one node at random; then, it selects one of 8 | % the neighbors of this node, again, at random. Next, it selects one node 9 | % from the set of neighbors of the first and the second nodes. This is 10 | % performed a number 'depth' of times. The function at the nodes in the 11 | % resulting subgraph will depend on xl. This process is repeated for all 12 | % components. 13 | % 14 | % Different mode (n == P) 15 | % When n == P, the algorithm is slightly different. Namely, there are P 16 | % variables and P nodes. So, the pth variable is assigned to node p. The 17 | % nodes that will depend on xp will be determined by the neighbors and 18 | % depth in the same way described above. 19 | % 20 | % Inputs: 21 | % - n: dimension of the variable of the problem 22 | % - P: number of nodes in the network 23 | % - neighbors: Px1 cell. The pth entry has a vector with the neighbors of 24 | % node p. 25 | % - depth: a number between 2 and P-1. It is the number of nodes in each 26 | % subgraph. It can also be a vector of size n, where each entry 27 | % specifies the number of nodes in each subgraph (each subgraph 28 | % is generated n times). 29 | % 30 | % Output: Struct with the following fields: 31 | % - components: Px1 cell, where the pth entry contains a vector with the 32 | % indices of the components node p depends on. 33 | % - P: number of nodes in the network 34 | % - neighbors: Px1 cell. The pth entry has a vector with the neighbors of 35 | % node p. 36 | % - depth: same as in the input 37 | % - n: same as in the input 38 | % 39 | % ========================================================================= 40 | % NOTE: If at the end of the algorithm there are nodes which were not 41 | % assigned any variable, the algorithm is repeated. The number of 42 | % times the algorithm is repeated is defined in the variable REPEAT, 43 | % in the code. 44 | % ========================================================================= 45 | 46 | REPEAT = 30; % Maximum number of times the algorithm can be repeated 47 | 48 | 49 | % ========================================================================= 50 | % Check for errors in the input 51 | if isscalar(depth) 52 | depth = depth*ones(n,1); 53 | else 54 | if length(depth) ~= n 55 | error('Input vector depth should have n entries or be a scalar. Type ''help CreateVarPartialConnected''.'); 56 | end 57 | end 58 | if sum( (depth > (P-1)) + (depth < 2) ) > 0 59 | error('Input ''depth'' should be between 2 and P-1. Type ''help CreateVarPartialConnected''.') 60 | end 61 | % ========================================================================= 62 | 63 | % Determine the mode 64 | if n == P 65 | NORMAL_MODE = 0; 66 | else 67 | NORMAL_MODE = 1; 68 | end 69 | 70 | 71 | components = cell(P,1); 72 | 73 | 74 | % ========================================================================= 75 | % Algorithm 76 | 77 | for rep = 1 : REPEAT 78 | 79 | for p = 1 : P 80 | components{p} = []; 81 | end 82 | 83 | for l = 1 : n 84 | 85 | fringe = []; 86 | nodes_in_subgraph = zeros(P,1); % pth entry = 1 => node p is in the graph 87 | % = 0 => otherwise 88 | 89 | if NORMAL_MODE 90 | p = round((P-1)*rand) + 1; % node selected randomly 91 | else 92 | p = l; 93 | end 94 | 95 | components{p} = [components{p} ; l]; 96 | 97 | fringe = alterfringe(fringe, neighbors{p}, 'add'); 98 | 99 | nodes_in_subgraph(p) = 1; 100 | 101 | for dep = 1 : depth(l)-1 102 | 103 | len_fringe = length(fringe); 104 | k = round((len_fringe-1)*rand) + 1; % node selected randomly 105 | % from the fringe 106 | p = fringe(k); 107 | 108 | components{p} = [components{p} ; l]; 109 | 110 | nodes_in_subgraph(p) = 1; 111 | 112 | fringe = alterfringe(fringe, p, 'rem'); 113 | fringe = alterfringe(fringe, neighbors{p}, 'add'); 114 | fringe = alterfringe(fringe, find(nodes_in_subgraph), 'rem'); 115 | 116 | if sum(nodes_in_subgraph) == P-1 117 | fprintf('Warning: component %d contains P-1 nodes. Premature stop.\n', l); 118 | break; 119 | end 120 | end 121 | end 122 | 123 | 124 | % Check if there are nodes without any component 125 | node_without_comp = zeros(P,1); 126 | for p = 1 : P 127 | if isempty(components{p}) 128 | node_without_comp(p) = 1; 129 | end 130 | end 131 | num_nodes = sum(node_without_comp); 132 | if num_nodes > 0 133 | %fprintf('There are %d nodes without components. Repeating (repetition number = %d)\n', num_nodes, rep); 134 | else 135 | break; 136 | end 137 | 138 | end 139 | % ========================================================================= 140 | 141 | 142 | % ========================================================================= 143 | % Output 144 | 145 | if rep == REPEAT 146 | error('The generated problem had always at least one node with no assigned variables. Please increase depth or n next time.'); 147 | else 148 | fprintf('Number of repetitions: %d \n', rep); 149 | end 150 | 151 | FactorGraph = struct('components', {components}, ... 152 | 'P', {P}, ... 153 | 'neighbors', {neighbors}, ... 154 | 'depth', {depth}, ... 155 | 'n', {n} ... 156 | ); 157 | % ========================================================================= 158 | 159 | 160 | end 161 | 162 | 163 | 164 | 165 | function [fringe] = alterfringe(fringe, node, operation) 166 | 167 | % Receives the vector 'fringe' and adds or removes 'node', which is either 168 | % a vector of nodes or a scalar, according to the value of 'operation'. The 169 | % input operation is a string with 'add' if we want to add 'node' to the 170 | % 'fringe', or with 'rem'if we want to remove 'node' from the fringe. 171 | 172 | switch operation 173 | case 'add' 174 | 175 | for i = 1 : length(node) 176 | 177 | if sum(fringe == node(i)) == 0 % Only add the node if it is not in the fringe 178 | fringe = [fringe ; node(i)]; %#ok 179 | end 180 | 181 | end 182 | 183 | 184 | case 'rem' 185 | 186 | for i = 1 : length(node) 187 | 188 | index = (fringe == node(i)); 189 | fringe = fringe(not(index)); 190 | 191 | end 192 | 193 | 194 | otherwise 195 | error('Operation not recognized in alterfringe, file CreateVarPartialConnected.'); 196 | end 197 | 198 | 199 | end 200 | -------------------------------------------------------------------------------- /GenerateData/FactorGraphs/CreateVarScript.m: -------------------------------------------------------------------------------- 1 | function [] = CreateVarScript(num_nodes, n, depth) 2 | 3 | % Uses the function 'CreateVarPartialConnected.m' to create a factor graph 4 | % for each network with 'num_nodes'. The networks are located in the folder 5 | % /GlobalVar/GenerateData/Networks. 6 | % 7 | % For the inputs 'n' and 'depth' see the function 8 | % 'CreateVarPartialConnected.m' 9 | 10 | % ========================================================================= 11 | % Directories and filenames 12 | 13 | % path to networks 14 | dir_nets = '../../../../GlobalVar/GenerateData/Networks/Nets_'; 15 | 16 | % filename of networks file 17 | file_nets = [dir_nets, num2str(num_nodes), '_nodes.mat']; 18 | 19 | % Output filename 20 | filename_output = ['GeneratedFGs/FG_Nets_', num2str(num_nodes), '_nodes.mat']; 21 | % ========================================================================= 22 | 23 | 24 | % ========================================================================= 25 | % Code 26 | 27 | load(file_nets); 28 | 29 | Num_Nets = length(Networks); 30 | 31 | FactorGraphs = cell(Num_Nets,1); 32 | 33 | for i = 1 : Num_Nets 34 | 35 | P = Networks{i}.P; 36 | Neighbors = Networks{i}.Neighbors; 37 | 38 | FactorGraphs{i} = CreateVarPartialConnected(n, P, Neighbors, depth); 39 | end 40 | % ========================================================================= 41 | 42 | save(filename_output, 'FactorGraphs'); -------------------------------------------------------------------------------- /GenerateData/FactorGraphs/GeneratedFGs/FG_Nets_10_nodes.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/FactorGraphs/GeneratedFGs/FG_Nets_10_nodes.mat -------------------------------------------------------------------------------- /GenerateData/FactorGraphs/GeneratedFGs/FG_Nets_2000_nodes.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/FactorGraphs/GeneratedFGs/FG_Nets_2000_nodes.mat -------------------------------------------------------------------------------- /GenerateData/FactorGraphs/GeneratedFGs/FG_Nets_500_nodes.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/FactorGraphs/GeneratedFGs/FG_Nets_500_nodes.mat -------------------------------------------------------------------------------- /GenerateData/FactorGraphs/GeneratedFGs/FG_Nets_50_nodes.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/FactorGraphs/GeneratedFGs/FG_Nets_50_nodes.mat -------------------------------------------------------------------------------- /GenerateData/FactorGraphs/GeneratedFGs/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | FG_Nets_10_nodes.mat: Generated with 3 | 4 | >> CreateVarScript(10, 5, [4 3 4 3 3]) 5 | Number of repetitions: 1 6 | Number of repetitions: 2 7 | Number of repetitions: 3 8 | Number of repetitions: 8 9 | Number of repetitions: 2 10 | 11 | 12 | FG_Nets_50_nodes.mat: Generated with 13 | 14 | >> CreateVarScript(50, 30, 6) 15 | Number of repetitions: 1 16 | Number of repetitions: 5 17 | Number of repetitions: 3 18 | Number of repetitions: 4 19 | Number of repetitions: 5 20 | 21 | 22 | FG_Nets_2000_nodes.mat: Generated with 23 | 24 | >> CreateVarScript(2000, 700, 50) 25 | Number of repetitions: 3 26 | Number of repetitions: 1 27 | Number of repetitions: 5 28 | Number of repetitions: 1 29 | Number of repetitions: 1 30 | 31 | -------------------------------------------------------------------------------- /GenerateData/FactorGraphs/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | Contains functions for creating a connected factor graph. The networks used here 3 | can be found in the folder '/GlobalVar/GenerateData/Networks/'. 4 | 5 | The algorithm in the function 'CreateVarPartialConnected.m' works as follows. 6 | 7 | Given a network with P nodes and a variable with n components, 8 | 9 | For l = 1 : n 10 | 11 | select node p randomly, and node p will depend on x_l 12 | 13 | fringe = {neighbors_of_p} 14 | 15 | For dep = 1 : depth 16 | 17 | select one node j randomly in the fringe 18 | 19 | node j will depend on x_l 20 | 21 | add neighbors_of_j to the fringe, and remove j from the fringe 22 | 23 | EndFor 24 | 25 | EndFor 26 | 27 | If at the end of this algorithm there is at least one node that does not 28 | depend on any component, the algorithm is repeated. 29 | 30 | 31 | The files in this folder are 32 | 33 | CreateVarPartialConnected: implements the above algorithm 34 | 35 | CreateVarScript: calls CreateVarPartialConnected for the networks 36 | in /GlobalVar/GenerateData/Networks/ and puts them 37 | in the folder /GeneratedFGs. 38 | 39 | 40 | -------------------------------------------------------------------------------- /GenerateData/Networks/Bipartite/Bipartite_Nets.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Networks/Bipartite/Bipartite_Nets.mat -------------------------------------------------------------------------------- /GenerateData/Networks/Bipartite/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | We have the following files: 3 | 4 | generate_bipartite_erdos.py: Python script that creates random bipartite 5 | networks, using the Erdos-Renyi model 6 | (networkx) 7 | 8 | generate_series_bipartite.m: calls generate_bipartite_erdos.py for several 9 | network sizes. It also creates automatically 10 | the structure FactorGraphs. 11 | 12 | Bipartite_Nets.mat: contains bipartite networks in 'Networks' and the 13 | corresponding 'FactorGraphs': each central node 14 | is considered the center of a cluster. 15 | -------------------------------------------------------------------------------- /GenerateData/Networks/Bipartite/gen_bipartite_erdos.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # -*- coding: utf-8 -*- 4 | """ 5 | Created on Sat Oct 20 23:56:33 2012 6 | 7 | Creates random bipartite networks, using the Erdos-Renyi model (see 8 | the networkx documentation). 9 | 10 | This script should have 4 inputs: 11 | C: number of nodes in one group 12 | P: number of nodes in the other group 13 | prob: number between 0 and 1 14 | Filename: where the data is saved 15 | """ 16 | 17 | 18 | 19 | # main function 20 | def main(): 21 | 22 | import sys 23 | import networkx as nx 24 | from networkx.algorithms import bipartite 25 | 26 | if len(sys.argv) == 5: 27 | C_in = sys.argv[1] 28 | P_in = sys.argv[2] 29 | prob_in = sys.argv[3] 30 | Filename = sys.argv[4] 31 | else: 32 | print 'Error: there should be 3 input arguments in gen_bipartite_erdos' 33 | return 34 | 35 | # check for input errors 36 | #if 37 | #print 'C = ' + str(C) 38 | #print 'P = ' + str(P) 39 | #print 'par = ' + str(par) 40 | 41 | C = int(float(C_in)) 42 | P = int(float(P_in)) 43 | prob = float(prob_in) 44 | 45 | G = nx.generators.bipartite_random_graph(C,P,prob) 46 | Adj = nx.adj_matrix(G) 47 | if nx.is_connected(G): 48 | conn = 1 49 | # get a coloring scheme 50 | colors = bipartite.color(G) 51 | diameter = nx.diameter(G) 52 | else: 53 | conn = 0 54 | diameter = 0 55 | print 'Error: generated network was not connected. Try increasing prob' 56 | 57 | # get a coloring scheme 58 | colors = bipartite.color(G) 59 | 60 | number_of_nodes = C + P 61 | 62 | # write to file 63 | FILE=open(Filename, "w") 64 | FILE.write('conn = '+str(conn)+'\n') 65 | FILE.write('C = '+str(C)+'\n') 66 | FILE.write('P = '+str(P)+'\n') 67 | FILE.write('diameter = '+str(diameter)+'\n') 68 | FILE.write('Adj =\n') 69 | 70 | for node1 in range(number_of_nodes): 71 | for node2 in range(number_of_nodes): 72 | FILE.write(str(int(Adj[node1,node2]))+' ') 73 | FILE.write('\n') 74 | 75 | if conn == 1: 76 | FILE.write('colors = \n') 77 | for node1 in range(number_of_nodes): 78 | FILE.write(str(colors[node1])+' ') 79 | 80 | FILE.write('\n') 81 | FILE.close() 82 | 83 | # This is the standard boilerplate that calls the main() function. 84 | if __name__ == '__main__': 85 | main() 86 | -------------------------------------------------------------------------------- /GenerateData/Networks/Bipartite/generate_series_bipartite.m: -------------------------------------------------------------------------------- 1 | function [] = generate_series_bipartite() 2 | 3 | % ========================================================================= 4 | % Generates a series of bipartite networks and factor graphs 5 | 6 | % Number of nodes in each set 7 | C = [2 5 9 10 20 25 25 40]; 8 | P = [5 10 10 20 25 28 40 50]; 9 | 10 | FILENAME = 'Bipartite_Nets.mat'; % Where the networks will be stored 11 | 12 | prob = 0.25; % connection probability in Erdos-Renyi model 13 | 14 | MAX_TRIALS = 100; % Will try to generate a connected network up to 15 | % MAX_TRIALS 16 | 17 | python_filename = 'gen_bipartite_erdos.py'; % Python script that generates 18 | % network with Networkx 19 | % ========================================================================= 20 | 21 | filename_temp = 'single_netw_tmp.txt'; 22 | 23 | 24 | num_networks = length(C); 25 | 26 | if length(P) ~= num_networks 27 | error('C and P do not have the same number of elements'); 28 | end 29 | 30 | Networks = cell(num_networks,1); 31 | FactorGraphs = cell(num_networks,1); 32 | 33 | for net = 1 : num_networks 34 | 35 | for trial = 1 : MAX_TRIALS 36 | 37 | system(['./', python_filename, ' ', num2str(C(net)), ' ', ... 38 | num2str(P(net)), ' ', num2str(prob), ' ', filename_temp ]); 39 | 40 | [conn, Adj, Diameter, colors] = read_Adjacency_and_connectivity(filename_temp); 41 | system(['rm', ' ', filename_temp]); 42 | 43 | if conn == 1 44 | break; 45 | end 46 | end 47 | if conn == 0 48 | error('Was never able to generate a connected network for C x P = %d x %d', C(net),P(net)); 49 | end 50 | 51 | part1 = find(colors); 52 | part2 = find(~colors); 53 | 54 | % We make the central nodes always less than the peripheral nodes 55 | if length(part1) < length(part2) 56 | central_nodes = part1; 57 | periphe_nodes = part2; 58 | else 59 | central_nodes = part2; 60 | periphe_nodes = part1; 61 | end 62 | 63 | num_nodes = C(net) + P(net); 64 | 65 | % ==================================================================== 66 | % Compute network information 67 | 68 | Parameters = prob; 69 | Num_Colors = 2; 70 | Partition = {part1' , part2'}; 71 | Neighbors = cell(num_nodes,1); 72 | Degrees = zeros(num_nodes,1); 73 | for p = 1 : num_nodes 74 | Neighbors{p} = find(Adj(p,:)); 75 | Degrees(p) = length(Neighbors{p}); 76 | end 77 | Max_Degree = max(Degrees); 78 | 79 | Network = struct('P', {num_nodes}, ... 80 | 'central_nodes', {central_nodes}, ... 81 | 'periphe_nodes', {periphe_nodes}, ... 82 | 'Adj', {Adj}, ... 83 | 'Type', 'Erdos-Renyi_bipartite', ... 84 | 'Parameters', {Parameters}, ... 85 | 'Num_Colors', {Num_Colors}, ... 86 | 'Partition', {Partition}, ... 87 | 'Diameter', {Diameter}, ... 88 | 'Neighbors', {Neighbors}, ... 89 | 'Degrees', {Degrees}, ... 90 | 'Max_Degree', {Max_Degree} ... 91 | ); 92 | % ==================================================================== 93 | 94 | % ==================================================================== 95 | % Compute factor graph 96 | 97 | components = cell(num_nodes, 1); 98 | 99 | % Central nodes have only an associated variable component 100 | for ind_c = 1 : length(central_nodes) 101 | c = central_nodes(ind_c); 102 | components{c} = ind_c; 103 | end 104 | 105 | for ind_p = 1 : length(periphe_nodes) 106 | 107 | p = periphe_nodes(ind_p); 108 | neighbs_p = Neighbors{p}; % These should be central nodes 109 | Dp = Degrees(p); 110 | 111 | components_p = zeros(Dp,1); 112 | for i_Dp = 1 : Dp 113 | c = neighbs_p(i_Dp); 114 | components_p(i_Dp) = components{c}; 115 | end 116 | 117 | components{p} = components_p; 118 | end 119 | 120 | FactorGraph = struct('components', {components}, ... 121 | 'P', {num_nodes}, ... 122 | 'neighbors', {Neighbors} ... 123 | ); 124 | % ==================================================================== 125 | 126 | Networks{net} = Network; 127 | FactorGraphs{net} = FactorGraph; 128 | 129 | save(FILENAME, 'Networks', 'FactorGraphs'); 130 | end 131 | 132 | 133 | end 134 | 135 | 136 | 137 | 138 | function [conn, Adj, diameter, colors] = read_Adjacency_and_connectivity(filename) 139 | % [conn, Adj, diameter, colors] = read_Adjacency_and connectivity(filename) 140 | % 141 | % It reads values from a file with 'filename' with the following format: 142 | % 143 | % conn = val 144 | % C = val 145 | % P = val 146 | % diameter = val 147 | % Adj = 148 | % val val val ... val 149 | % val val val ... val 150 | % ... 151 | % val val val ... val 152 | % colors = 153 | % val val val ... val 154 | % 155 | % where val is a number. The size of Adj matrix is (C+P) x (C+P). 156 | 157 | 158 | 159 | fid = fopen(filename, 'r'); 160 | data = textscan(fid, '%s'); 161 | fclose(fid); 162 | 163 | conn = str2double(data{1}(3)); 164 | 165 | if conn == 0 166 | Adj = []; 167 | colors = []; 168 | diameter = []; 169 | return; 170 | end 171 | 172 | C = str2double(data{1}(6)); 173 | P = str2double(data{1}(9)); 174 | diameter = str2double(data{1}(12)); 175 | 176 | num_nodes = C + P; 177 | 178 | Adj = zeros(num_nodes,num_nodes); 179 | 180 | index = 14; 181 | 182 | for i = 1 : num_nodes 183 | for j = 1 : num_nodes 184 | Adj(i,j) = str2double(data{1}(index + num_nodes*(i-1) + j)); 185 | end 186 | end 187 | 188 | index = 14 + num_nodes^2 + 2; 189 | 190 | colors = zeros(num_nodes,1); 191 | 192 | for i = 1 : num_nodes 193 | colors(i) = str2double(data{1}(index + i)); 194 | end 195 | 196 | end 197 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_100.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_100.mat -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_100.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------- 2 | Network Statistics: 3 | 4 | 5 | 6 | Type: Barabasi 7 | Parameter: 2 8 | Random seed: 1234 9 | Number of nodes: 100 10 | Number of edges: 196 11 | Diameter: 6 12 | Number of colors: 3 13 | Maximum degree: 18 14 | Minimum degree: 2 15 | Average degree: 3.92 16 | -------------------------------------------------- 17 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_2000.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_2000.mat -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_2000.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------- 2 | Network Statistics: 3 | 4 | 5 | 6 | Type: Barabasi 7 | Parameter: 2 8 | Random seed: 1234 9 | Number of nodes: 2000 10 | Number of edges: 3996 11 | Diameter: 8 12 | Number of colors: 3 13 | Maximum degree: 90 14 | Minimum degree: 2 15 | Average degree: 3.996 16 | -------------------------------------------------- 17 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_6.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_6.mat -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/ProcessedNetwork/Barabasi_P_6.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------- 2 | Network Statistics: 3 | 4 | 5 | 6 | Type: Barabasi 7 | Parameter: 2 8 | Random seed: 1234 9 | Number of nodes: 6 10 | Number of edges: 8 11 | Diameter: 2 12 | Number of colors: 3 13 | Maximum degree: 4 14 | Minimum degree: 2 15 | Average degree: 2.66666666667 16 | -------------------------------------------------- 17 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/ProcessedNetwork/Network_PowerGrid.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/GenerateData/Networks/MPC/ProcessedNetwork/Network_PowerGrid.mat -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/ProcessedNetwork/Stats_PowerGrid.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------- 2 | Network Statistics: 3 | 4 | 5 | 6 | Number of nodes: 4941 7 | Number of edges: 6594 8 | Diameter: 46 9 | Number of colors: 6 10 | Maximum degree: 19 11 | Minimum degree: 1 12 | Average degree: 2.66909532483 13 | -------------------------------------------------- 14 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | This folder contains files for generating networks for the MPC problem in generic networks. 3 | 4 | RawNetwork: 5 | Contains the US power grid network with about 5000 nodes. 6 | 7 | 8 | Scripts: 9 | Contains scripts for either creating networks (in case of random networks) or processing networks 10 | (in case there are networks in the RawNetwork folder) 11 | 12 | READ_FROM_RAW.m: 13 | Main file; it is a Matlab script that executes the sage scripts in the Scripts folder 14 | and creates a Networks struct in Matlab. These structs and the network statistics are 15 | stored in the ProcessedNetwork folder 16 | 17 | processPowerGrid.sage: 18 | Reads the .gml file in the RawNetwork folder for the power grid and stores its information 19 | in a tmp.txt file (to be processed and deleted by READ_FROM_RAW.m) 20 | 21 | Barabasi.sage: 22 | Creates a Barabasi network with a given parameter and number of nodes 23 | 24 | 25 | ProcessedNetwork: 26 | Contains .mat files with Networks structs and respective statistics. 27 | 28 | 29 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/RawNetwork/date_retrieved.txt: -------------------------------------------------------------------------------- 1 | 2013-02-14 Qui 12:51 2 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/RawNetwork/power.txt: -------------------------------------------------------------------------------- 1 | Western States Power Grid 2 | 3 | Compiled by Duncan Watts and Steven Strogatz 4 | 5 | The file power.gml contains an undirected unweighted representation of the 6 | topology of the Western States Power Grid of the United States, compiled by 7 | Duncan Watts and Steven Strogatz. The data are from the web site of 8 | Prof. Duncan Watts at Columbia University, 9 | http://cdg.columbia.edu/cdg/datasets. Node IDs are the same as those used 10 | by Prof. Watts. 11 | 12 | These data can be cited as: 13 | 14 | D. J. Watts and S. H. Strogatz, "Collective dynamics of `small-world' 15 | networks", Nature 393, 440-442 (1998). 16 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/Scripts/Barabasi.py: -------------------------------------------------------------------------------- 1 | # This file was *autogenerated* from the file Barabasi.sage. 2 | from sage.all_cmdline import * # import sage library 3 | _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_6 = Integer(6); _sage_const_1234 = Integer(1234)#!/usr/lib/sagemath/sage -python 4 | 5 | 6 | import networkx as nx 7 | import numpy as np 8 | from scipy.sparse import csc_matrix # To make a matrix sparse 9 | from scipy.io import savemat # To save matrices to Matlab 10 | from sage.all import * 11 | 12 | # ================================================================== 13 | # Parameters 14 | 15 | TYPE = 'Barabasi' 16 | 17 | m = _sage_const_2 # Barabasi parameter 18 | 19 | num_nodes = _sage_const_6 #100 #2000 # Number of nodes 20 | 21 | # Name of the file to save the data 22 | FILENAME_OUTPUT = 'tmp.txt' 23 | 24 | # Will be used as seed for everything random 25 | random_seed = _sage_const_1234 26 | 27 | # Plot Active/Inactive 28 | _PLOT = False 29 | # ================================================================== 30 | 31 | # ================================================================== 32 | # Read the network into graph_sage 33 | graph_nx = nx.generators.barabasi_albert_graph(num_nodes, m, seed=random_seed) 34 | 35 | graph_sage = Graph(graph_nx) # convert to Sage graph 36 | # ================================================================== 37 | 38 | 39 | # ================================================================== 40 | # Get network information 41 | 42 | num_nodes_raw = graph_sage.num_verts() 43 | num_edges_raw = graph_sage.num_edges() 44 | 45 | Edges = graph_sage.edges() 46 | 47 | Diameter = graph_sage.diameter() 48 | 49 | colors = graph_sage.coloring(algorithm='MILP',verbose=_sage_const_1 ) # Use MILP, 50 | # otherwise it is slow 51 | numColors = len(colors) 52 | 53 | is_connected = graph_sage.is_connected() 54 | # ================================================================== 55 | 56 | #print 'Saving data to file ' + str(FILENAME_OUTPUT) + '\n' 57 | 58 | FILE = open(FILENAME_OUTPUT, "w") 59 | FILE.write('conn = ' + str(int(is_connected)) + '\n') 60 | FILE.write('num_nodes = ' + str(num_nodes_raw) + '\n') 61 | FILE.write('num_edges = ' + str(num_edges_raw) + '\n') 62 | FILE.write('diameter = ' + str(Diameter) + '\n') 63 | FILE.write('numColors = ' + str(numColors) + '\n') 64 | 65 | FILE.write('nodesPerColor = \n') 66 | for color in range(numColors): 67 | FILE.write(str(len(colors[color])) + '\n') 68 | 69 | FILE.write('colors = \n') 70 | 71 | for color in range(numColors): 72 | for node in range(len(colors[color])): 73 | FILE.write(str(colors[color][node]) + ' ') 74 | FILE.write('\n') 75 | 76 | FILE.write('Edges =\n') 77 | 78 | for edge in range(num_edges_raw): 79 | FILE.write(str(Edges[edge][_sage_const_0 ]) + ' ' + str(Edges[edge][_sage_const_1 ]) + '\n') 80 | 81 | FILE.close() 82 | 83 | #print 'Done \n\n' 84 | 85 | 86 | # ================================================================== 87 | # Print Network statistics 88 | 89 | Degrees = [graph_sage.degree(i) for i in range(num_nodes_raw)] 90 | 91 | Max_Degree = max(Degrees) 92 | Min_Degree = min(Degrees) 93 | Mean_Degree = float(mean(Degrees)) 94 | 95 | print '--------------------------------------------------' 96 | print 'Network Statistics:\n' 97 | print '\n' 98 | print 'Type: ' + TYPE 99 | print 'Parameter: ' + str(m) 100 | print 'Random seed: ' + str(random_seed) 101 | print 'Number of nodes: ' + str(num_nodes_raw) 102 | print 'Number of edges: ' + str(num_edges_raw) 103 | print 'Diameter: ' + str(Diameter) 104 | print 'Number of colors: ' + str(numColors) 105 | print 'Maximum degree: ' + str(Max_Degree) 106 | print 'Minimum degree: ' + str(Min_Degree) 107 | print 'Average degree: ' + str(Mean_Degree) 108 | print '--------------------------------------------------' 109 | # ================================================================== 110 | 111 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/Scripts/Barabasi.sage: -------------------------------------------------------------------------------- 1 | #!/usr/lib/sagemath/sage -python 2 | 3 | 4 | import networkx as nx 5 | import numpy as np 6 | from scipy.sparse import csc_matrix # To make a matrix sparse 7 | from scipy.io import savemat # To save matrices to Matlab 8 | from sage.all import * 9 | 10 | # ================================================================== 11 | # Parameters 12 | 13 | TYPE = 'Barabasi' 14 | 15 | m = 2 # Barabasi parameter 16 | 17 | num_nodes = 6 #100 #2000 # Number of nodes 18 | 19 | # Name of the file to save the data 20 | FILENAME_OUTPUT = 'tmp.txt' 21 | 22 | # Will be used as seed for everything random 23 | random_seed = 1234 24 | 25 | # Plot Active/Inactive 26 | _PLOT = False 27 | # ================================================================== 28 | 29 | # ================================================================== 30 | # Read the network into graph_sage 31 | graph_nx = nx.generators.barabasi_albert_graph(num_nodes, m, seed=random_seed) 32 | 33 | graph_sage = Graph(graph_nx) # convert to Sage graph 34 | # ================================================================== 35 | 36 | 37 | # ================================================================== 38 | # Get network information 39 | 40 | num_nodes_raw = graph_sage.num_verts() 41 | num_edges_raw = graph_sage.num_edges() 42 | 43 | Edges = graph_sage.edges() 44 | 45 | Diameter = graph_sage.diameter() 46 | 47 | colors = graph_sage.coloring(algorithm='MILP',verbose=1) # Use MILP, 48 | # otherwise it is slow 49 | numColors = len(colors) 50 | 51 | is_connected = graph_sage.is_connected() 52 | # ================================================================== 53 | 54 | #print 'Saving data to file ' + str(FILENAME_OUTPUT) + '\n' 55 | 56 | FILE = open(FILENAME_OUTPUT, "w") 57 | FILE.write('conn = ' + str(int(is_connected)) + '\n') 58 | FILE.write('num_nodes = ' + str(num_nodes_raw) + '\n') 59 | FILE.write('num_edges = ' + str(num_edges_raw) + '\n') 60 | FILE.write('diameter = ' + str(Diameter) + '\n') 61 | FILE.write('numColors = ' + str(numColors) + '\n') 62 | 63 | FILE.write('nodesPerColor = \n') 64 | for color in range(numColors): 65 | FILE.write(str(len(colors[color])) + '\n') 66 | 67 | FILE.write('colors = \n') 68 | 69 | for color in range(numColors): 70 | for node in range(len(colors[color])): 71 | FILE.write(str(colors[color][node]) + ' ') 72 | FILE.write('\n') 73 | 74 | FILE.write('Edges =\n') 75 | 76 | for edge in range(num_edges_raw): 77 | FILE.write(str(Edges[edge][0]) + ' ' + str(Edges[edge][1]) + '\n') 78 | 79 | FILE.close() 80 | 81 | #print 'Done \n\n' 82 | 83 | 84 | # ================================================================== 85 | # Print Network statistics 86 | 87 | Degrees = [graph_sage.degree(i) for i in range(num_nodes_raw)] 88 | 89 | Max_Degree = max(Degrees) 90 | Min_Degree = min(Degrees) 91 | Mean_Degree = float(mean(Degrees)) 92 | 93 | print '--------------------------------------------------' 94 | print 'Network Statistics:\n' 95 | print '\n' 96 | print 'Type: ' + TYPE 97 | print 'Parameter: ' + str(m) 98 | print 'Random seed: ' + str(random_seed) 99 | print 'Number of nodes: ' + str(num_nodes_raw) 100 | print 'Number of edges: ' + str(num_edges_raw) 101 | print 'Diameter: ' + str(Diameter) 102 | print 'Number of colors: ' + str(numColors) 103 | print 'Maximum degree: ' + str(Max_Degree) 104 | print 'Minimum degree: ' + str(Min_Degree) 105 | print 'Average degree: ' + str(Mean_Degree) 106 | print '--------------------------------------------------' 107 | # ================================================================== 108 | 109 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/Scripts/READ_FROM_RAW.m: -------------------------------------------------------------------------------- 1 | % Reads the power grid network and stores the .mat file in 2 | % 3 | % ../ProcessedNetwork/ 4 | % 5 | % It uses the .sage files to create a tmp file with the network 6 | 7 | 8 | % ========================================================================= 9 | % Filenames 10 | 11 | % Sage script that reads the network, colors it, and gets other stats 12 | SAGE_FILE = 'Barabasi.sage'; 13 | %SAGE_FILE = 'processPowerGrid.sage'; 14 | 15 | % Temporary file created by the Sage script; it will be erased aftewards 16 | TMP_FILE = 'tmp.txt'; 17 | 18 | % Where the final network will be stored (_node_num.mat will be added) 19 | FILENAME_OUTPUT = '../ProcessedNetwork/Barabasi'; 20 | %FILENAME_OUTPUT = '../ProcessedNetwork/Network_PowerGrid.mat'; 21 | % ========================================================================= 22 | 23 | 24 | % ========================================================================= 25 | % Execute Sage script 26 | 27 | % Name of temporary file for storing the statistics. It will be moved after 28 | % knowing what the number of nodes is 29 | STATS_TMP_FILE = 'stats_tmp.txt'; 30 | 31 | system(['sage ', SAGE_FILE, ' > ', STATS_TMP_FILE]); 32 | % ========================================================================= 33 | 34 | 35 | 36 | % ========================================================================= 37 | % Read TMP_FILE 38 | % 39 | % The file has the following format: 40 | % 41 | % conn = num 42 | % num_nodes = num 43 | % num_edges = num 44 | % diameter = num 45 | % numColors = num 46 | % nodePerColor = 47 | % num 48 | % num 49 | % ... 50 | % num 51 | % colors = 52 | % num num num num num num num num num num num num num num 53 | % num num num num 54 | % num num num num num num num num 55 | % Edges = 56 | % num num 57 | % num num 58 | % num num 59 | % ... 60 | 61 | fid = fopen(TMP_FILE, 'r'); 62 | data_aux = textscan(fid, '%s'); 63 | fclose(fid); 64 | 65 | data = data_aux{1}; 66 | 67 | % Delete TMP file 68 | system(['rm ', TMP_FILE]); 69 | 70 | conn = str2double(data(3)); 71 | 72 | if conn == 0 73 | error('Network is not connected.') 74 | end 75 | 76 | ind = 6; 77 | num_nodes = str2double(data(ind)); 78 | ind = ind + 3; 79 | num_edges = str2double(data(ind)); 80 | ind = ind + 3; 81 | diameter = str2double(data(ind)); 82 | ind = ind + 3; 83 | numColors = str2double(data(ind)); 84 | 85 | nodesPerColor = zeros(numColors,1); 86 | 87 | % Read nodesPerColor 88 | ind = ind + 3; 89 | for i = 1 : numColors 90 | nodesPerColor(i) = str2double(data(ind)); 91 | ind = ind +1; 92 | end 93 | 94 | % Read Colors 95 | Colors = cell(numColors,1); 96 | 97 | ind = ind + 2; 98 | for i = 1 : numColors 99 | vec_aux = zeros(1,nodesPerColor(i)); 100 | for nd = 1 : nodesPerColor(i) 101 | vec_aux(nd) = str2double(data(ind)) + 1; % In Python vectors start 102 | % in 0 103 | ind = ind + 1; 104 | end 105 | Colors{i} = vec_aux; 106 | end 107 | 108 | % Read Edges and build adjacency matrix 109 | Adj = sparse(zeros(num_nodes,num_nodes)); 110 | 111 | ind = ind + 2; 112 | for i = 1 : num_edges 113 | node1 = str2double(data(ind)) + 1; % In python nodes start in 0 114 | ind = ind + 1; 115 | node2 = str2double(data(ind)) + 1; 116 | ind = ind + 1; 117 | Adj(node1,node2) = 1; 118 | Adj(node2,node1) = 1; 119 | end 120 | % ========================================================================= 121 | 122 | 123 | % ========================================================================= 124 | % Store Network 125 | 126 | % First, get Neighbors, Degrees, and Max_Degree 127 | Neighbors = cell(num_nodes,1); 128 | Degrees = zeros(num_nodes,1); 129 | 130 | for p = 1 : num_nodes 131 | Neighbors{p} = find(Adj(p,:)); 132 | Degrees(p) = length(Neighbors{p}); 133 | end 134 | 135 | Max_Degree = max(Degrees); 136 | 137 | Network = struct('P', {num_nodes}, ... 138 | 'Adj', {Adj}, ... 139 | 'Type', 'Power Grid US', ... 140 | 'Num_Colors', {numColors}, ... 141 | 'Partition', {Colors}, ... 142 | 'Diameter', {diameter}, ... 143 | 'Neighbors', {Neighbors}, ... 144 | 'Degrees', {Degrees}, ... 145 | 'Max_Degree', {Max_Degree} ... 146 | ); 147 | 148 | 149 | % FILE_NAMES 150 | ending_filename = [FILENAME_OUTPUT, '_P_', num2str(num_nodes)]; 151 | 152 | filename_data = [ending_filename, '.mat']; 153 | filename_stat = [ending_filename, '.txt']; 154 | 155 | save(filename_data, 'Network'); 156 | system(['mv ' STATS_TMP_FILE, ' ', filename_stat]); 157 | % ========================================================================= 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/Scripts/processPowerGrid.py: -------------------------------------------------------------------------------- 1 | # This file was *autogenerated* from the file processPowerGrid.sage. 2 | from sage.all_cmdline import * # import sage library 3 | _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_1234 = Integer(1234)#!/usr/lib/sagemath/sage -python 4 | 5 | 6 | import networkx as nx 7 | import numpy as np 8 | from scipy.sparse import csc_matrix # To make a matrix sparse 9 | from scipy.io import savemat # To save matrices to Matlab 10 | from sage.all import * 11 | 12 | # ****************************************************************** 13 | # Parameters 14 | 15 | # Input File 16 | FILENAME_INPUT = '../RawNetwork/power.gml' 17 | 18 | # Name of the file to save the data 19 | FILENAME_OUTPUT = 'tmp.txt' 20 | 21 | # Will be used as seed for everything random 22 | random_seed = _sage_const_1234 23 | 24 | # Plot Active/Inactive 25 | _PLOT = False 26 | # ****************************************************************** 27 | 28 | 29 | # ****************************************************************** 30 | # Read the network into graph_sage 31 | #print ' ' 32 | #print 'Reading input file: ' + str(FILENAME_INPUT) + '...' 33 | graph_nx = nx.read_gml(FILENAME_INPUT) 34 | #print 'Finished reading.' 35 | 36 | graph_sage = Graph(graph_nx) # convert to Sage graph 37 | 38 | # ****************************************************************** 39 | 40 | 41 | # ================================================================== 42 | # Get network information 43 | 44 | num_nodes_raw = graph_sage.num_verts() 45 | num_edges_raw = graph_sage.num_edges() 46 | 47 | Edges = graph_sage.edges() 48 | 49 | Diameter = graph_sage.diameter() 50 | 51 | colors = graph_sage.coloring(algorithm='MILP',verbose=_sage_const_1 ) # Use MILP, 52 | # otherwise it is slow 53 | numColors = len(colors) 54 | 55 | is_connected = graph_sage.is_connected() 56 | # ================================================================== 57 | 58 | #print 'Saving data to file ' + str(FILENAME_OUTPUT) + '\n' 59 | 60 | FILE = open(FILENAME_OUTPUT, "w") 61 | FILE.write('conn = ' + str(int(is_connected)) + '\n') 62 | FILE.write('num_nodes = ' + str(num_nodes_raw) + '\n') 63 | FILE.write('num_edges = ' + str(num_edges_raw) + '\n') 64 | FILE.write('diameter = ' + str(Diameter) + '\n') 65 | FILE.write('numColors = ' + str(numColors) + '\n') 66 | 67 | FILE.write('nodesPerColor = \n') 68 | for color in range(numColors): 69 | FILE.write(str(len(colors[color])) + '\n') 70 | 71 | FILE.write('colors = \n') 72 | 73 | for color in range(numColors): 74 | for node in range(len(colors[color])): 75 | FILE.write(str(colors[color][node]) + ' ') 76 | FILE.write('\n') 77 | 78 | FILE.write('Edges =\n') 79 | 80 | for edge in range(num_edges_raw): 81 | FILE.write(str(Edges[edge][_sage_const_0 ]) + ' ' + str(Edges[edge][_sage_const_1 ]) + '\n') 82 | 83 | FILE.close() 84 | 85 | #print 'Done \n\n' 86 | 87 | 88 | # ================================================================== 89 | # Print Network statistics 90 | 91 | Degrees = [graph_sage.degree(i) for i in range(num_nodes_raw)] 92 | 93 | Max_Degree = max(Degrees) 94 | Min_Degree = min(Degrees) 95 | Mean_Degree = float(mean(Degrees)) 96 | 97 | print '--------------------------------------------------' 98 | print 'Network Statistics:\n' 99 | print '\n' 100 | print 'Number of nodes: ' + str(num_nodes_raw) 101 | print 'Number of edges: ' + str(num_edges_raw) 102 | print 'Diameter: ' + str(Diameter) 103 | print 'Number of colors: ' + str(numColors) 104 | print 'Maximum degree: ' + str(Max_Degree) 105 | print 'Minimum degree: ' + str(Min_Degree) 106 | print 'Average degree: ' + str(Mean_Degree) 107 | print '--------------------------------------------------' 108 | # ================================================================== 109 | 110 | -------------------------------------------------------------------------------- /GenerateData/Networks/MPC/Scripts/processPowerGrid.sage: -------------------------------------------------------------------------------- 1 | #!/usr/lib/sagemath/sage -python 2 | 3 | # Script that processes the power grid network and stores the list of 4 | # edges in a text file 5 | 6 | 7 | import networkx as nx 8 | import numpy as np 9 | from scipy.sparse import csc_matrix # To make a matrix sparse 10 | from scipy.io import savemat # To save matrices to Matlab 11 | from sage.all import * 12 | 13 | # ****************************************************************** 14 | # Parameters 15 | 16 | # Input File 17 | FILENAME_INPUT = '../RawNetwork/power.gml' 18 | 19 | # Name of the file to save the data 20 | FILENAME_OUTPUT = 'tmp.txt' 21 | 22 | # Will be used as seed for everything random 23 | random_seed = 1234 24 | 25 | # Plot Active/Inactive 26 | _PLOT = False 27 | # ****************************************************************** 28 | 29 | 30 | # ****************************************************************** 31 | # Read the network into graph_sage 32 | #print ' ' 33 | #print 'Reading input file: ' + str(FILENAME_INPUT) + '...' 34 | graph_nx = nx.read_gml(FILENAME_INPUT) 35 | #print 'Finished reading.' 36 | 37 | graph_sage = Graph(graph_nx) # convert to Sage graph 38 | 39 | # ****************************************************************** 40 | 41 | 42 | # ================================================================== 43 | # Get network information 44 | 45 | num_nodes_raw = graph_sage.num_verts() 46 | num_edges_raw = graph_sage.num_edges() 47 | 48 | Edges = graph_sage.edges() 49 | 50 | Diameter = graph_sage.diameter() 51 | 52 | colors = graph_sage.coloring(algorithm='MILP',verbose=1) # Use MILP, 53 | # otherwise it is slow 54 | numColors = len(colors) 55 | 56 | is_connected = graph_sage.is_connected() 57 | # ================================================================== 58 | 59 | #print 'Saving data to file ' + str(FILENAME_OUTPUT) + '\n' 60 | 61 | FILE = open(FILENAME_OUTPUT, "w") 62 | FILE.write('conn = ' + str(int(is_connected)) + '\n') 63 | FILE.write('num_nodes = ' + str(num_nodes_raw) + '\n') 64 | FILE.write('num_edges = ' + str(num_edges_raw) + '\n') 65 | FILE.write('diameter = ' + str(Diameter) + '\n') 66 | FILE.write('numColors = ' + str(numColors) + '\n') 67 | 68 | FILE.write('nodesPerColor = \n') 69 | for color in range(numColors): 70 | FILE.write(str(len(colors[color])) + '\n') 71 | 72 | FILE.write('colors = \n') 73 | 74 | for color in range(numColors): 75 | for node in range(len(colors[color])): 76 | FILE.write(str(colors[color][node]) + ' ') 77 | FILE.write('\n') 78 | 79 | FILE.write('Edges =\n') 80 | 81 | for edge in range(num_edges_raw): 82 | FILE.write(str(Edges[edge][0]) + ' ' + str(Edges[edge][1]) + '\n') 83 | 84 | FILE.close() 85 | 86 | #print 'Done \n\n' 87 | 88 | 89 | # ================================================================== 90 | # Print Network statistics 91 | 92 | Degrees = [graph_sage.degree(i) for i in range(num_nodes_raw)] 93 | 94 | Max_Degree = max(Degrees) 95 | Min_Degree = min(Degrees) 96 | Mean_Degree = float(mean(Degrees)) 97 | 98 | print '--------------------------------------------------' 99 | print 'Network Statistics:\n' 100 | print '\n' 101 | print 'Number of nodes: ' + str(num_nodes_raw) 102 | print 'Number of edges: ' + str(num_edges_raw) 103 | print 'Diameter: ' + str(Diameter) 104 | print 'Number of colors: ' + str(numColors) 105 | print 'Maximum degree: ' + str(Max_Degree) 106 | print 'Minimum degree: ' + str(Min_Degree) 107 | print 'Average degree: ' + str(Mean_Degree) 108 | print '--------------------------------------------------' 109 | # ================================================================== 110 | 111 | -------------------------------------------------------------------------------- /GenerateData/Networks/README.TXT: -------------------------------------------------------------------------------- 1 | All the networks used in the "partial variable" case that are non-bipartite are located in 2 | 3 | /GlobalVar/GenerateData/Networks 4 | -------------------------------------------------------------------------------- /GenerateData/README.txt: -------------------------------------------------------------------------------- 1 | This directory contains files for generating a factor graph associated to a 2 | network. 3 | 4 | The networks, i.e., the communication networks, were generated with 5 | the code provided in the package for DADMM: 6 | 7 | http://users.isr.ist.utl.pt/~jmota/DADMM/_static/MatlabCode/DADMM_paper_Code.zip 8 | 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Distributed Optimization With Local Domains: Applications in MPC and Network Flows 2 | 3 | Code to replicate the experiments in 4 | 5 | **[Distributed Optimization With Local Domains: Applications in MPC and Network 6 | Flows](http://dx.doi.org/10.1109/TAC.2014.2365686)**. 7 | J. F. C. Mota, J. M. F. Xavier, P. M. Q. Aguiar, M. Püschel. 8 | IEEE Transactions on Automatic Control, Vol. 60, No. 7, pp. 2004-2009, 2015. 9 | [link](http://dx.doi.org/10.1109/TAC.2014.2365686), 10 | [arXiv](http://arxiv.org/abs/1305.1885) 11 | 12 | The main algorithm is `DADMM_Partial.m`. 13 | 14 | All code is implemented in Matlab. Although all algorithms are 15 | distributed, the code is centralized and runs sequentially. The purpose is to 16 | simulate distributed algorithms. 17 | 18 | ## Organization 19 | 20 | * `DADMM_Partial.m`: 21 | solves the optimization problem 22 | 23 |

24 | 25 | where the optimization variable has components , and 26 | each set indexes the components of that node depends on. See the 27 | documentation in `DADMM_Partial`, and also the above paper [1] for terminology. 28 | 29 | * UsageExamples: simple examples illustrating how to use `DAMM_Partial.m`. 30 | 31 | * CompareAlgs: 32 | reproduces Figures 4 and 5 in the paper. 33 | 34 | 35 | * GenerateData: contains data used in the experiments and also contains code 36 | to generate other types of data. Some data is generated in Python/Sage. 37 | 38 | * KekatosADMM: our implementation of the algorithm in 39 | 40 | **[Distributed Robust Power System State Estimation]( 41 | https://doi.org/10.1109/TPWRS.2012.2219629)**. 42 | V. Kekatos, G. B. Giannakis. 43 | IEEE Transactions on Power Systems, Vol. 28, No. 2, 2013. 44 | [link](https://doi.org/10.1109/TPWRS.2012.2219629), 45 | [arXiv](https://arxiv.org/abs/1204.0991) 46 | 47 | Note that the algorithm proposed in this paper was designed to solve (1) with 48 | a star-shaped variable, but we generalized it to operate with any connected 49 | variable. 50 | 51 | 52 | * SpecialPurposeAlgs: 53 | our implementation of the algorithms in the references below, which solve (1) 54 | only in the case of a star-shaped variable. 55 | 56 | **[Distributed Optimization and Statistical Learning via the Alternating 57 | Direction Method of Multipliers]( 58 | https://www.nowpublishers.com/article/Details/MAL-016)**. 59 | S. Boyd, N. Parikh, E. Chu, B. Peleato, J. Eckstein. 60 | Foundations and Trends on Machine Learning, Vol. 3, No. 4, 2010. 61 | *(section 7.2)*. 62 | [link](https://www.nowpublishers.com/article/Details/MAL-016), 63 | [authors' version](https://web.stanford.edu/~boyd/papers/pdf/admm_distr_stats.pdf) 64 | 65 | **[Introductory Lectures on Convex Optimization: A Basic Course]( 66 | https://doi.org/10.1007/978-1-4419-8853-9)**. 67 | Y. Nesterov. 68 | Springer Science+Business Media New York, 2004. 69 | [link](https://doi.org/10.1007/978-1-4419-8853-9), 70 | [Google 71 | Books](https://books.google.co.uk/books?hl=en&lr=&id=2-ElBQAAQBAJ&oi=fnd&pg=PA1&dq=Introductory+Lectures+on+Convex+Optimization:+A+Basic+Course&ots=wlrO5qqckz&sig=2LOforFMisXArmF_2AxYg6LvXXA#v=onepage&q=Introductory%20Lectures%20on%20Convex%20Optimization%3A%20A%20Basic%20Course&f=false) 72 | 73 | --- 74 | 75 | License: [ GPLv3 ]( https://www.gnu.org/licenses/gpl-3.0.en.html ) 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /READOTHER.md: -------------------------------------------------------------------------------- 1 | # Distributed Optimization With Local Domains: Applications in MPC and Network Flows 2 | 3 | Code to replicate the experiments in 4 | 5 | **[Distributed Optimization With Local Domains: Applications in MPC and Network 6 | Flows](http://dx.doi.org/10.1109/TAC.2014.2365686)**. 7 | J. F. C. Mota, J. M. F. Xavier, P. M. Q. Aguiar, M. Püschel. 8 | IEEE Transactions on Automatic Control, Vol. 60, No. 7, pp. 2004-2009, 2015. 9 | [link](http://dx.doi.org/10.1109/TAC.2014.2365686), 10 | [arXiv](http://arxiv.org/abs/1305.1885) 11 | 12 | The main algorithm is `DADMM_Partial.m`. 13 | 14 | All code is implemented in Matlab. Although all algorithms are 15 | distributed, the code is centralized and runs sequentially. The purpose is to 16 | simulate distributed algorithms. 17 | 18 | ## Organization 19 | 20 | * `DADMM_Partial.m`: 21 | solves the optimization problem 22 | 23 | \begin{equation}\label{Eq:SeparableOptim} 24 | \underset{x \in \mathbb{R}^n}{\text{minimize}} \,\,\, f_1(x_{S_1}) + f_2(x_{S_2}) + \cdots + f_P(x_{S_P})\,, 25 | \end{equation} 26 | 27 | where the optimization variable has $n$ components $x = (x_1, x_2, ..., x_n)$, and 28 | each set $S_p$ indexes the components of $x$ that node $p$ depends on. See the 29 | documentation in `DADMM_Partial`, and also the above paper [1] for terminology. 30 | 31 | * UsageExamples: simple examples illustrating how to use `DAMM_Partial.m`. 32 | 33 | * CompareAlgs: 34 | reproduces Figures 4 and 5 in the paper. 35 | 36 | 37 | * GenerateData: contains data used in the experiments and also contains code 38 | to generate other types of data. Some data is generated in Python/Sage. 39 | 40 | * KekatosADMM: our implementation of the algorithm in 41 | 42 | **[Distributed Robust Power System State Estimation]( 43 | https://doi.org/10.1109/TPWRS.2012.2219629)**. 44 | V. Kekatos, G. B. Giannakis. 45 | IEEE Transactions on Power Systems, Vol. 28, No. 2, 2013. 46 | [link](https://doi.org/10.1109/TPWRS.2012.2219629), 47 | [arXiv](https://arxiv.org/abs/1204.0991) 48 | 49 | Note that the algorithm proposed in this paper was designed to solve (1) with 50 | a star-shaped variable, but we generalized it to operate with any connected 51 | variable. 52 | 53 | 54 | * SpecialPurposeAlgs: 55 | our implementation of the algorithms in the references below, which solve (1) 56 | only in the case of a star-shaped variable. 57 | 58 | **[Distributed Optimization and Statistical Learning via the Alternating 59 | Direction Method of Multipliers]( 60 | https://www.nowpublishers.com/article/Details/MAL-016)**. 61 | S. Boyd, N. Parikh, E. Chu, B. Peleato, J. Eckstein. 62 | Foundations and Trends on Machine Learning, Vol. 3, No. 4, 2010. 63 | *(section 7.2)*. 64 | [link](https://www.nowpublishers.com/article/Details/MAL-016), 65 | [authors' version](https://web.stanford.edu/~boyd/papers/pdf/admm_distr_stats.pdf) 66 | 67 | **[Introductory Lectures on Convex Optimization: A Basic Course]( 68 | https://doi.org/10.1007/978-1-4419-8853-9)**. 69 | Y. Nesterov. 70 | Springer Science+Business Media New York, 2004. 71 | [link](https://doi.org/10.1007/978-1-4419-8853-9), 72 | [Google 73 | Books](https://books.google.co.uk/books?hl=en&lr=&id=2-ElBQAAQBAJ&oi=fnd&pg=PA1&dq=Introductory+Lectures+on+Convex+Optimization:+A+Basic+Course&ots=wlrO5qqckz&sig=2LOforFMisXArmF_2AxYg6LvXXA#v=onepage&q=Introductory%20Lectures%20on%20Convex%20Optimization%3A%20A%20Basic%20Course&f=false) 74 | 75 | --- 76 | 77 | License: [ GPLv3 ]( https://www.gnu.org/licenses/gpl-3.0.en.html ) 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/BoydADMM/Documentation/BoydADMM.bib: -------------------------------------------------------------------------------- 1 | 2 | 3 | @ARTICLE{Boyd10-ADMM, 4 | AUTHOR = {{Boyd}, S. and {Parikh}, N. and {Chu}, E. and {Peleato}, B. and {Eckstein}, J.}, 5 | TITLE = {Distributed Optimization and Statistical Learning via the Alternating Method of Multipliers}, 6 | JOURNAL = {Found. Trends Mach. Learn.}, 7 | YEAR = {2010}, 8 | volume = {3}, 9 | number = {1}, 10 | } -------------------------------------------------------------------------------- /SpecialPurposeAlgs/BoydADMM/Documentation/BoydADMM.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/SpecialPurposeAlgs/BoydADMM/Documentation/BoydADMM.pdf -------------------------------------------------------------------------------- /SpecialPurposeAlgs/GradientMethod/Documentation/GradientMethod.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/SpecialPurposeAlgs/GradientMethod/Documentation/GradientMethod.pdf -------------------------------------------------------------------------------- /SpecialPurposeAlgs/GradientMethod/Documentation/GradientMethod.tex: -------------------------------------------------------------------------------- 1 | \documentclass[letter,10pt]{article} 2 | %\documentclass[journal,twocolumn]{IEEEtran} 3 | %\documentclass[onecolumn,journal,draftcls,11pt]{IEEEtran} 4 | 5 | %\usepackage{spconf} 6 | \usepackage[english]{babel} 7 | \usepackage[latin1]{inputenc} 8 | \usepackage[T1]{fontenc} 9 | \usepackage{url} 10 | \usepackage{graphicx} 11 | \usepackage{subfigure} 12 | \usepackage{color} 13 | \usepackage{amsmath,amsfonts,amssymb} 14 | \usepackage{colortbl} % Para tabelas com sombreados 15 | \usepackage{url} 16 | \usepackage{booktabs} 17 | \usepackage{epsfig} 18 | \usepackage{pstricks} 19 | \usepackage{pst-node} 20 | \usepackage{pst-grad} 21 | \usepackage{ifthen} 22 | \usepackage{algorithm} 23 | \usepackage{algpseudocode} 24 | \usepackage{setspace} 25 | \usepackage{pdflscape} 26 | \usepackage{multirow} 27 | \usepackage[framed]{ntheorem} 28 | \usepackage{framed} 29 | 30 | 31 | \setlength{\topmargin}{-10mm} \setlength{\textheight}{225mm} 32 | %\setlength{\topmargin}{0mm} 33 | \setlength{\headheight}{14pt} \setlength{\headsep}{10mm} 34 | \setlength{\textwidth}{150mm} \setlength{\footskip}{13mm} 35 | \setlength{\oddsidemargin}{5mm} \setlength{\evensidemargin}{5mm} 36 | 37 | %\usepackage{pst-plot} 38 | %\usepackage{psfrag} 39 | 40 | %\usepackage{hyperref} 41 | 42 | 43 | \theoremstyle{definition} 44 | \newtheorem{Algorithm}{Algorithm} 45 | \newtheorem*{Definition}{Definition} 46 | \shadecolor{black!10!white} 47 | \theorembodyfont{\rm\normalfont} 48 | \theoremindent0cm 49 | \newshadedtheorem{thm}{Theorem} 50 | 51 | \newshadedtheorem{lem}{Lemma} 52 | \newshadedtheorem{proposition}{Proposition} 53 | \newtheorem{Assumption}{Assumption} 54 | \newtheorem{Remark}{Remark} 55 | 56 | \theoremstyle{nonumberplain} 57 | \theoremindent0cm 58 | \newtheorem{proof}{Proof} 59 | 60 | %\theoremstyle{plain} 61 | %\newtheorem{Conjecture}{Conjecture} 62 | %\newtheorem{Lemma}{Lemma} 63 | %\newtheorem{Assumption}{Assumption} 64 | 65 | 66 | 67 | %\newcommand{\mypar}[1]{{\bf #1.}} 68 | 69 | \newcommand{\mypar}[1]{\bigskip\noindent {\bf #1.}} 70 | 71 | \newcommand\mynote[1]{\mbox{}\marginpar{\footnotesize\raggedright\hspace{0pt}\color{blue}\emph{#1}}} 72 | 73 | \newcommand{\answer}[1]{\medskip\noindent \textcolor[rgb]{0.00,0.00,1.00}{#1}\bigskip} 74 | 75 | \newcommand{\qed}{\hfill $\Box$} 76 | 77 | \definecolor{red}{RGB}{153,0,0} 78 | 79 | 80 | 81 | \begin{document} 82 | 83 | 84 | \section*{Description and Implementation of a Distributed Gradient Method for Distribution Optimization With a 85 | Partial Variable With Induced Subgraphs 86 | } 87 | 88 | This document describes the direct application of the gradient method to the problem 89 | \begin{equation}\label{Eq:PartialProb} 90 | \underset{x \in \mathbb{R}^n}{\text{minimize}} \,\,\, f_1(x_{S_1}) + f_2(x_{S_2}) + \cdots + f_P(x_{S_P})\,, 91 | \end{equation} 92 | where function~$f_p$ depends only on a subset~$S_p \subseteq \{1,\ldots,n\}$ of components of the variable~$x \in \mathbb{R}^n$. We will see, however, that this is efficient only in problems where each component~$x_l$ induces a star subgraph, for~$l=1,\ldots,n$. In other words, there is a connected network with~$P$ nodes, where the $p$th node knows only~$f_p$; in this network, the set of nodes that depends on~$x_l$ is a star. 93 | 94 | \mypar{Derivation} 95 | Let~$\mathcal{G} = (\mathcal{V},\mathcal{E})$ be the communication network where we want to solve~\eqref{Eq:PartialProb} in a distributed way. Let~$\mathcal{V}_l$ be the subgraph induced by~$x_l$, i.e., the set of nodes in~$\mathcal{V}$ whose function~$f_p$ depends on~$x_l$ ($l \in S_p$). We assume~$\mathcal{V}_l$ is a star. 96 | 97 | Denote the objective of~\eqref{Eq:PartialProb} by~$f(x)$. Its gradient w.r.t.\ $x_l$ is 98 | $$ 99 | \frac{\partial}{\partial\, x_l}f(x) 100 | = 101 | \sum_{p \in \mathcal{V}_l}\frac{\partial}{\partial\, x_l} f_p(x_{S_p})\,. 102 | $$ 103 | The gradient method assumes~$f(x)$ is convex, continuously differentiable, and its gradient~$\nabla f(x)$ is Lipschitz continuous with constant~$L$, i.e. $\|\nabla f(y) - \nabla f(x)\| \leq L\|y - x\|$, for any~$x,y$ in the domain of~$f$. Each component~$x_l$ is updated as 104 | \begin{equation}\label{Eq:UpdateComp} 105 | x_l^{k+1} = \Bigl[ x_l^k - \frac{1}{L} \sum_{p \in \mathcal{V}_l}\frac{\partial}{\partial\, x_l} f_p(x_{S_p}) \Bigr]^+_l\,, 106 | \end{equation} 107 | where~$[\cdot]^+_l$ is a projection operator for the component~$x_l$. This is imposed by the node that is the center of the star~$\mathcal{V}_l$, as explained next. In a distributed scenario, the update~\eqref{Eq:UpdateComp} has to take place at a given node. That node has to collect all the partial derivatives $\frac{\partial}{\partial\, x_l} f_p(x_{S_p})$, sum them, perform the update, and compute the projection. This is only efficient if the topology of~$\mathcal{V}_l$ is a star and these operations are all performed at the center of the star. This is illustrated in Algorithm~\ref{Alg:DistrGrad}. 108 | 109 | \begin{algorithm} 110 | \caption{Distributed Gradient Method} 111 | \algrenewcommand\algorithmicrequire{\textbf{Initialization:}} 112 | \label{Alg:DistrGrad} 113 | \begin{algorithmic}[1] 114 | \small 115 | \Require Each node that is a center for~$x_l$, sets~$x_l^1$ to an arbitrary value and sends in to the neighbors that depend on~$x_l$; set $k=1$ 116 | \Repeat 117 | \ForAll{$p=1,\ldots,P$ [in parallel]} 118 | \State Compute $g_l^k :=\frac{\partial}{\partial\, x_l} f_l(x_l^k)$ for all~$l \in S_p$ 119 | 120 | \State Send $g_l^k$ to all neighbors that depend on~$x_l$, i.e., $\mathcal{N}_p \cap \mathcal{V}_l$ 121 | \EndFor 122 | 123 | \ForAll{$p$ such that $p$ is the center of the star~$\mathcal{V}_l$ [in parallel]} 124 | \State Update $x_l$ as 125 | $$ 126 | x_l^{k+1} = \Bigl[ x_l^k - \frac{1}{L} \sum_{p \in \mathcal{V}_l}\frac{\partial}{\partial\, x_l} f_p(x_{S_p})\Bigr]^+_l 127 | $$ 128 | 129 | \State Send~$x_l^{k+1}$ to all neighbors that depend on~$x_l$, i.e., $\mathcal{N}_p \cap \mathcal{V}_l$ 130 | \EndFor 131 | 132 | \State $k \gets k+1$ 133 | 134 | \Until{some stopping criterion is met} 135 | \end{algorithmic} 136 | \end{algorithm} 137 | 138 | In each $k$-iteration of Algorithm~\ref{Alg:DistrGrad}, there is information flowing in each edge, both ways just once. Thus, each iteration of the algorithm requires on communication step. 139 | 140 | 141 | \end{document} 142 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/MPC/GradientsMPC.m: -------------------------------------------------------------------------------- 1 | function [grad, vars_prob] = GradientsMPC(p, x, vars_prob) 2 | 3 | % From vars_prob 4 | E_p = vars_prob.E_p{p}; 5 | w_p = vars_prob.w_p{p}; 6 | 7 | grad = 2*E_p*x + w_p; 8 | 9 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/MPC/RunMPC.m: -------------------------------------------------------------------------------- 1 | % Solves the MPC problem with NesterovMethod. Given a time-horizon T, it 2 | % solves 3 | % 4 | % minimize sum_{t=0}^{T-1} [x(t)'*Q*x(t) + u(t)'*R*u(t)] 5 | % + x(T)'*Q_f*x(T) 6 | % 7 | % subject to x_p(t+1) = A_pp x_p(t) + sum_{j \in Omega} B_pj*u_j[t], 8 | % p=1,...,P, 9 | % 10 | % where Q and R are diagonal matrices and each state has a dynamics that 11 | % only depends on its own state but it is controlled by the actuators to 12 | % which the sensor is connected. 13 | % 14 | % See the file '../../../GenerateData/Data/MPC/Readme/MPC.pdf' 15 | % for a more comprehensive explanation of the problem. 16 | % ------------------------------------------------------------------------- 17 | % Distributed Optimization With Local Domains: Applications in MPC and 18 | % Network Flows 19 | % Copyright (C) 2014 Joao Mota 20 | % 21 | % This program is free software: you can redistribute it and/or modify 22 | % it under the terms of the GNU General Public License as published by 23 | % the Free Software Foundation, either version 3 of the License, or 24 | % (at your option) any later version. 25 | % 26 | % This program is distributed in the hope that it will be useful, 27 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 28 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 | % GNU General Public License for more details. 30 | % 31 | % You should have received a copy of the GNU General Public License 32 | % along with this program. If not, see . 33 | % ------------------------------------------------------------------------- 34 | % 35 | % ========================================================================= 36 | % Please send any questions, comments, or bug reports to j.mota@ucl.ac.uk 37 | % ========================================================================= 38 | 39 | 40 | % ========================================================================= 41 | % Directories and filenames 42 | 43 | addpath('../../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 44 | addpath('../../../GenerateData/Data/MPC/Data/'); % Data 45 | addpath('../'); % Algorithm 46 | 47 | file_networks = 'Barabasi_P_100.mat'; 48 | file_data = 'Barab_P_100_STABLE.mat'; 49 | %file_networks = 'Barabasi_P_2000.mat'; 50 | %file_data = 'Barab_P_2000_STABLE.mat'; 51 | %file_networks = 'Network_PowerGrid.mat'; 52 | %file_data = 'MPCDataPowerGrid.mat'; 53 | % ========================================================================= 54 | 55 | 56 | % ========================================================================= 57 | % Parameters 58 | 59 | max_iter = 1000; % Maximum number of iterations 60 | eps_opt = 1e-3; % Tolerance 61 | % ========================================================================= 62 | 63 | 64 | % ========================================================================= 65 | % Extract data and networks from files 66 | 67 | % Load files 68 | load(file_networks); 69 | load(file_data); 70 | 71 | 72 | % Network data 73 | P = Network.P; 74 | Adj = Network.Adj; 75 | Num_Colors = Network.Num_Colors; 76 | Partition = Network.Partition; 77 | Neighbors = Network.Neighbors; 78 | Degrees = Network.Degrees; 79 | 80 | centers = kron(1:P,ones(1,T*m_p)); 81 | 82 | vars_prob = struct('gradients', {@GradientsMPC}, ... 83 | 'proj_constraints', {@projConsMPC}, ... 84 | 'components', {components}, ... 85 | 'centers', {centers}, ... 86 | 'E_p', {E_p}, ... 87 | 'w_p', {w_p} ... 88 | ); 89 | 90 | % Create struct with network information 91 | vars_network = struct('P', {P}, ... 92 | 'neighbors', {Neighbors} ... 93 | ); 94 | % ========================================================================= 95 | 96 | 97 | % ========================================================================= 98 | % Execute NesterovMethod 99 | 100 | % Optional input 101 | ops = struct('max_iter', {max_iter}, ... 102 | 'x_opt', {solution}, ... 103 | 'eps_opt', {eps_opt} ... 104 | ); 105 | 106 | [X, vars_prob, ops_out] = NesterovMethod(length(solution), Lipschitz, ... 107 | vars_prob, vars_network, ops); 108 | % ========================================================================= 109 | 110 | 111 | % ========================================================================= 112 | % Print results 113 | 114 | iterations = ops_out.iterations; 115 | stop_crit = ops_out.stop_crit; 116 | error_iterations = ops_out.error_iterations; 117 | iter_for_errors = ops_out.iter_for_errors; 118 | 119 | fprintf('Number of iterations = %d\n', iterations); 120 | fprintf('stop_crit = %s\n', stop_crit); 121 | fprintf('iter_for_errors = \n'); 122 | num_rows = size(iter_for_errors, 1); 123 | for i_g = 1 : num_rows 124 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 125 | end 126 | 127 | figure(1);clf; 128 | semilogy(1:iterations,error_iterations(1:iterations), 'b'); 129 | title('error\_{iterations}'); 130 | % ========================================================================= 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/MPC/projConsMPC.m: -------------------------------------------------------------------------------- 1 | function [proj_point, vars_prob] = projConsMPC(l, point, vars_prob) 2 | 3 | proj_point = point; 4 | 5 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/NetworkFlow/Documentation/NestNetFlow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/SpecialPurposeAlgs/NesterovMethod/NetworkFlow/Documentation/NestNetFlow.pdf -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/NetworkFlow/Documentation/NestNetFlow.tex: -------------------------------------------------------------------------------- 1 | \documentclass[letter,10pt]{article} 2 | 3 | \usepackage[english]{babel} 4 | \usepackage[latin1]{inputenc} 5 | \usepackage[T1]{fontenc} 6 | \usepackage{url} 7 | \usepackage{graphicx} 8 | \usepackage{subfigure} 9 | \usepackage{color} 10 | \usepackage{amsmath,amsfonts,amssymb} 11 | \usepackage{url} 12 | \usepackage{booktabs} 13 | \usepackage{epsfig} 14 | \usepackage{pstricks} 15 | \usepackage{pst-node} 16 | \usepackage{pst-grad} 17 | \usepackage{ifthen} 18 | \usepackage{algorithm} 19 | \usepackage{algpseudocode} 20 | \usepackage{setspace} 21 | \usepackage[framed]{ntheorem} 22 | \usepackage{framed} 23 | 24 | 25 | \setlength{\topmargin}{-10mm} \setlength{\textheight}{225mm} 26 | \setlength{\headheight}{14pt} \setlength{\headsep}{10mm} 27 | \setlength{\textwidth}{150mm} \setlength{\footskip}{13mm} 28 | \setlength{\oddsidemargin}{5mm} \setlength{\evensidemargin}{5mm} 29 | 30 | 31 | \theoremstyle{definition} 32 | \newtheorem{Algorithm}{Algorithm} 33 | \newtheorem*{Definition}{Definition} 34 | \shadecolor{black!10!white} 35 | \theorembodyfont{\rm\normalfont} 36 | \theoremindent0cm 37 | \newshadedtheorem{thm}{Theorem} 38 | 39 | \newshadedtheorem{lem}{Lemma} 40 | \newshadedtheorem{proposition}{Proposition} 41 | \newtheorem{Assumption}{Assumption} 42 | \newtheorem{Remark}{Remark} 43 | 44 | \theoremstyle{nonumberplain} 45 | \theoremindent0cm 46 | \newtheorem{proof}{Proof} 47 | 48 | 49 | \newcommand{\mypar}[1]{\bigskip\noindent {\bf #1.}} 50 | 51 | \newcommand\mynote[1]{\mbox{}\marginpar{\footnotesize\raggedright\hspace{0pt}\color{blue}\emph{#1}}} 52 | 53 | \newcommand{\answer}[1]{\medskip\noindent \textcolor[rgb]{0.00,0.00,1.00}{#1}\bigskip} 54 | 55 | \newcommand{\qed}{\hfill $\Box$} 56 | 57 | \definecolor{red}{RGB}{153,0,0} 58 | 59 | 60 | 61 | \begin{document} 62 | 63 | 64 | \section*{Gradient Methods on Network Flow Problems} 65 | 66 | The network flow problem we consider is 67 | \begin{equation}\label{Eq:NetFlow} 68 | \begin{array}{cl} 69 | \underset{x = \{x_{ij}\}_{(i,j) \in \mathcal{E}}}{\text{minimize}} & \sum_{(i,j) \in \mathcal{E}} \phi_{ij}(x_{ij}) \\ 70 | \text{subject to} & Bx = d \\ 71 | & 0 \leq x \leq c\,, 72 | \end{array} 73 | \end{equation} 74 | which is associated to a digraph with~$P$ nodes and $E$ edges (the set of edges is~$\mathcal{E}$). That digraph is represented with its node-arc incidence matrix~$B \in \mathbb{R}^{P \times E}$ and each edge $(i,j)$ in the network has capacity~$c_{ij}$. $d$ is the vector of flow inputs/outputs, and~$\phi_{ij}$ is the cost associated to edge~$(i,j)$. We assume that $(i,j) \in \mathcal{E}$ means a connection (arrow) from~$i$ to~$j$. Also, the $ij$th column of the node-arc incidence matrix has a~$-1$ in the $i$th entry and a $1$ in the $j$th entry. Consider the dual of~\eqref{Eq:NetFlow}: 75 | \begin{equation}\label{Eq:DualNetFlow} 76 | \begin{array}{cl} 77 | \underset{\lambda = (\lambda_1,\ldots,\lambda_P)}{\text{maximize}} & L(\lambda) \,, 78 | \end{array} 79 | \end{equation} 80 | where the dual function is 81 | \begin{align*} 82 | L(\lambda) 83 | &= 84 | \inf_{0\leq x \leq c}\,\, \sum_{(i,j) \in \mathcal{E}} \phi_{ij}(x_{ij}) + \bigl(B^\top \lambda\bigr)^\top x - d^\top \lambda 85 | \\ 86 | &= 87 | - d^\top \lambda + \sum_{(i,j) \in \mathcal{E}} \inf_{0 \leq x_{ij} \leq c_{ij}} \phi_{ij}(x_{ij}) + (\lambda_j - \lambda_i)x_{ij} 88 | \\ 89 | &= 90 | -d^\top \lambda + \sum_{(i,j) \in \mathcal{E}} \phi_{ij}(x_{ij}(\lambda_j - \lambda_i)) + (\lambda_j - \lambda_i)x_{ij}(\lambda_j - \lambda_i)\,, 91 | \end{align*} 92 | where 93 | \begin{equation}\label{Eq:xv} 94 | x_{ij}(v) := \inf_{0\leq x_{ij} \leq c_{ij}} \, \phi_{ij}(x_{ij}) + v \,x_{ij}\,, 95 | \end{equation} 96 | which is always well-defined. We will choose 97 | $$ 98 | \phi_{ij}(x_{ij}) = \frac{x_{ij}}{c_{ij} - x_{ij}}\,, 99 | $$ 100 | which is continuously differentiable and strictly convex in $0\leq x_{ij} < c_{ij}$. To find~\eqref{Eq:xv} for this choice, take the derivative of the objective of~\eqref{Eq:xv} and equate it to zero: 101 | \begin{align*} 102 | &\frac{c_{ij}}{(c_{ij} - x_{ij})^2} + v = 0 103 | \\ 104 | \Longleftrightarrow\quad 105 | & 106 | c_{ij} + v(c_{ij} - x_{ij})^2 = 0 107 | \\ 108 | \Longleftrightarrow\quad 109 | & 110 | v x_{ij}^2 - 2 v c_{ij} x_{ij} + c_{ij} + v c_{ij}^2 = 0 111 | \\ 112 | \Longleftrightarrow\quad 113 | & 114 | x_{ij}^2 - 2 c_{ij} x_{ij} + \frac{c_{ij} + v c_{ij}^2}{v} = 0\,, 115 | \end{align*} 116 | whose solutions, if they exist, are 117 | \begin{align*} 118 | x_{ij} 119 | &= 120 | \frac{2c_{ij} \pm \sqrt{4c_{ij}^2 - 4c_{ij}^2 - 4c_{ij}/v}}{2} 121 | \\ 122 | &= 123 | \frac{2c_{ij} \pm \sqrt{- 4c_{ij}/v}}{2} 124 | \\ 125 | &= 126 | c_{ij} - \sqrt{-c_{ij}/v}\,, 127 | \end{align*} 128 | where we selected the solution with $-$ because we need $x_{ij} \leq c_{ij}$. This quadratic form has a solution only if~$v < 0$. In fact, it can be seen graphically that if~$v \geq 0$, $x_{ij}(v) = 0$. Therefore, 129 | $$ 130 | x_{ij}(v) = 131 | \left\{ 132 | \begin{array}{ll} 133 | 0 & v\geq 0 \\ 134 | \Bigl[c_{ij} - \sqrt{-c_{ij}/v}\Bigr]_{[0,c_{ij}]} & v<0\,, 135 | \end{array} 136 | \right. 137 | $$ 138 | where~$[\cdot]_{[0,c_{ij}]}$ denotes the projection onto the set~$[0,c_{ij}]$. 139 | 140 | The gradient of~$L(\lambda)$ is given by~$\nabla L(\lambda) = B x(\lambda) - d$, whose $p$th component is 141 | $$ 142 | \frac{\partial}{\partial\, \lambda_p} L(\lambda) = -\sum_{j \in \mathcal{N}_p} x_{pj}(\lambda_j - \lambda_p) + \sum_{j \in \mathcal{N}_p} x_{jp}(\lambda_p - \lambda_j) - d_p\,. 143 | $$ 144 | Therefore, $\lambda_p$ can be updated at node~$p$ through 145 | $$ 146 | \lambda_p^{k+1} = \lambda_p^{k} + \alpha \Bigl(\sum_{j \in \mathcal{N}_p} x_{jp}(\lambda_p^k - \lambda_j^k) -\sum_{j \in \mathcal{N}_p} x_{pj}(\lambda_j^k - \lambda_p^k) - d_p \Bigr)\,, 147 | $$ 148 | where~$\alpha$ is the stepsize and the algorithm is the simple gradient method. The previous update is possible if both nodes $i$ and~$j$ know~$\phi_{ij}$ and all the nodes exchange their $\lambda^k$'s after updating them. Note that every computation involving $\phi_{ij}$ takes place at both nodes $i$ and~$j$. Note also that~$\nabla L(\lambda)$ is not Lipschitz continuous. 149 | 150 | 151 | \end{document} 152 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/NetworkFlow/Error_gradNetFlow.m: -------------------------------------------------------------------------------- 1 | function [error_p, vars_prob] = Error_gradNetFlow(X, x_opt, vars_prob) 2 | 3 | x_estimate = vars_prob.x_estimate; 4 | 5 | error_p = norm(x_estimate - x_opt, Inf)/norm(x_opt, Inf); 6 | 7 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/NetworkFlow/RunNetworkFlow.m: -------------------------------------------------------------------------------- 1 | % Solves a network flow problem with NesterovMethod. The problem is 2 | % 3 | % minimize sum_{(i,j) in E} phi_{ij}(x_{ij}) 4 | % {x_{ij}} 5 | % subject to B*x = d 6 | % 0 <= x <= c 7 | % 8 | % where the variable x_{ij} is defined over the edge ij of the network E, B 9 | % is the node-arc incidence matrix, and d is the vector of sources (sum(d) 10 | % = 0). phi_{ij} is a function associated to the edge ij and it only 11 | % depends on the flow on that edge, x_{ij}. 12 | % 13 | % We will use for each function 14 | % 15 | % phi_{ij}(x_{ij}) = x_{ij}/(c_{ij} - x_{ij}) , 16 | % 17 | % from a multi-commodity flow problem modeling delays at the links. 18 | % 19 | % ------------------------------------------------------------------------- 20 | % Distributed Optimization With Local Domains: Applications in MPC and 21 | % Network Flows 22 | % Copyright (C) 2014 Joao Mota 23 | % 24 | % This program is free software: you can redistribute it and/or modify 25 | % it under the terms of the GNU General Public License as published by 26 | % the Free Software Foundation, either version 3 of the License, or 27 | % (at your option) any later version. 28 | % 29 | % This program is distributed in the hope that it will be useful, 30 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 | % GNU General Public License for more details. 33 | % 34 | % You should have received a copy of the GNU General Public License 35 | % along with this program. If not, see . 36 | % ------------------------------------------------------------------------- 37 | % 38 | % ========================================================================= 39 | % Please send any questions, comments, or bug reports to j.mota@ucl.ac.uk 40 | % ========================================================================= 41 | 42 | 43 | % ========================================================================= 44 | % Directories and filenames 45 | 46 | addpath('../../../GenerateData/Networks/MPC/ProcessedNetwork/');% Networks 47 | addpath('../../../GenerateData/Data/NetworkFlows/Results/'); % Data 48 | addpath('../'); % Algorithm 49 | 50 | %file_networks = 'Barabasi_P_2000.mat'; 51 | %file_data = 'NFData_Barabasi_P_2000.mat'; 52 | file_networks = 'Barabasi_P_100.mat'; 53 | file_data = 'NFData_Barabasi_P_100.mat'; 54 | % ========================================================================= 55 | 56 | 57 | % ========================================================================= 58 | % Parameters 59 | Lipschitz = 15000; 60 | max_iter = 5000; % Maximum number of iterations 61 | eps_opt = 1e-4; % Tolerance 62 | % ========================================================================= 63 | 64 | 65 | % ========================================================================= 66 | % Extract data and networks from files 67 | 68 | % Load files 69 | load(file_networks); 70 | load(file_data); 71 | 72 | Adj = Network.Adj; % Adjacency matrix 73 | partition_colors = Network.Partition; % Color partition of network 74 | P = length(Adj); % Number of nodes 75 | neighbors = Network.Neighbors; 76 | Dp = Network.Degrees; 77 | 78 | % Create struct with network information 79 | vars_network = struct('P', {P}, ... 80 | 'neighbors', {neighbors} ... 81 | ); 82 | 83 | 84 | % Create vars_prob 85 | 86 | B = incidence_matrix; 87 | d = flows; 88 | 89 | num_edges = size(incidence_matrix,2); 90 | 91 | components = cell(P,1); 92 | 93 | for p = 1 : P 94 | components{p} = sort([neighbors{p}, p]); 95 | end 96 | 97 | centers = (1:P)'; 98 | 99 | x_estimate = zeros(num_edges,1); % Will have the current estimate for x 100 | 101 | vars_prob = struct('components', {components}, ... 102 | 'centers', {centers}, ... 103 | 'gradients', {@grads_NetFlowNest}, ... 104 | 'proj_constraints', {@proj_NetFlowNest}, ... 105 | 'B', {B}, ... 106 | 'd', {d}, ... 107 | 'capacities', {capacities}, ... 108 | 'x_estimate', {x_estimate} ... 109 | ); 110 | % ========================================================================= 111 | 112 | 113 | % ========================================================================= 114 | % Execute NesterovMethod 115 | 116 | % Optional input 117 | ops = struct('max_iter', {max_iter}, ... 118 | 'x_opt', {solution}, ... 119 | 'error_fun', {@Error_gradNetFlow}, ... 120 | 'eps_opt', {eps_opt} ... 121 | ); 122 | 123 | [X, vars_prob, ops_out] = NesterovMethod(P, Lipschitz, vars_prob, ... 124 | vars_network, ops); 125 | % ========================================================================= 126 | 127 | 128 | % ========================================================================= 129 | % Print results 130 | 131 | iterations = ops_out.iterations; 132 | stop_crit = ops_out.stop_crit; 133 | error_iterations = ops_out.error_iterations; 134 | iter_for_errors = ops_out.iter_for_errors; 135 | 136 | fprintf('Lipschitz = %d\n', Lipschitz); 137 | fprintf('Number of iterations = %d\n', iterations); 138 | fprintf('stop_crit = %s\n', stop_crit); 139 | fprintf('iter_for_errors = \n'); 140 | num_rows = size(iter_for_errors, 1); 141 | for i_g = 1 : num_rows 142 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 143 | end 144 | 145 | figure(1);clf; 146 | semilogy(1:iterations,error_iterations(1:iterations), 'b'); 147 | title('error\_{iterations}'); 148 | % ========================================================================= 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/NetworkFlow/grads_NetFlowNest.m: -------------------------------------------------------------------------------- 1 | function [grad, vars_prob] = grads_NetFlowNest(p, x, vars_prob) 2 | 3 | % ASSUMPTION: Between any pair of nodes i and j, there is only one link at 4 | % most, either from i to j, or from j to i 5 | 6 | 7 | % From vars_prob 8 | capacities = vars_prob.capacities; 9 | B = vars_prob.B; 10 | d = vars_prob.d; 11 | components = vars_prob.components; 12 | x_estimate = vars_prob.x_estimate; 13 | 14 | num_edges = length(capacities); 15 | 16 | comp_p = components{p}; 17 | 18 | 19 | % To avoid confusion with notation 20 | lambda = x; 21 | 22 | ind_lambda_p = find(comp_p == p); 23 | 24 | lambda_p = lambda(ind_lambda_p); 25 | 26 | n_p = length(lambda); 27 | 28 | 29 | grad = zeros(n_p,1); 30 | 31 | for i_n_p = 1 : n_p 32 | 33 | if i_n_p == ind_lambda_p % contribution to the gradient of itself 34 | grad(i_n_p) = d(p); 35 | else 36 | node = comp_p(i_n_p); % node for which we want to compute the 37 | % contribution of node p to its gradient 38 | lambda_j = lambda(i_n_p); 39 | 40 | % Find the index in B (and lambda) that corresponds to edge (p,node) 41 | for ed = 1 : num_edges 42 | if abs(B(p,ed)) == 1 && abs(B(node,ed)) == 1 43 | break; 44 | end 45 | end 46 | 47 | if ed == num_edges && abs(B(p,ed)) ~= 1 && abs(B(node,ed)) ~= 1 48 | error('Programming error') 49 | end 50 | 51 | if B(p,ed) == -1 % Link out node p 52 | grad(i_n_p) = -compute_x_our(lambda_j - lambda_p, capacities(ed)); 53 | x_estimate(ed) = -grad(i_n_p); 54 | else 55 | grad(i_n_p) = compute_x_our(lambda_p - lambda_j, capacities(ed)); 56 | end 57 | end 58 | end 59 | 60 | vars_prob.x_estimate = x_estimate; 61 | 62 | end 63 | 64 | 65 | function [x_our] = compute_x_our(v, capacity) 66 | 67 | if v >= 0 68 | x_our = 0; 69 | return; 70 | end 71 | 72 | x_our_quad = capacity - sqrt(-capacity/v); 73 | 74 | if x_our_quad < 0 75 | x_our = 0; 76 | elseif x_our_quad > capacity 77 | x_our = capacity; 78 | else 79 | x_our = x_our_quad; 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/NetworkFlow/proj_NetFlowNest.m: -------------------------------------------------------------------------------- 1 | function [proj_point, vars_prob] = proj_NetFlowNest(l, point, vars_prob) 2 | 3 | proj_point = point; 4 | 5 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/NesterovMethod/README.TXT: -------------------------------------------------------------------------------- 1 | See the documentation of GradientMethod in the file 2 | 3 | /../GradientMethod/Documentation/GradientMethod.pdf 4 | 5 | Nesterov's algorithm is just a variant of a gradient method, and the implementation is very similar, only with more variables. 6 | -------------------------------------------------------------------------------- /SpecialPurposeAlgs/README.TXT: -------------------------------------------------------------------------------- 1 | This folder contains algorithms that solve (efficiently) problems with a partial variable 2 | whose components induce subgraphs that are stars. 3 | -------------------------------------------------------------------------------- /UsageExamples/MPC_PowerGrid/RunMPC_PowerGrid.m: -------------------------------------------------------------------------------- 1 | % Solves an MPC problem with DADMM_Partial. Given time-horizon T, it solves 2 | % 3 | % minimize sum_{t=0}^{T-1} [x(t)'*Q*x(t) + u(t)'*R*u(t)] 4 | % + x(T)'*Q_f*x(T) 5 | % 6 | % subject to x_p(t+1) = A_pp x_p(t) + sum_{j \in Omega} B_pj*u_j[t], 7 | % p=1,...,P, 8 | % 9 | % where Q and R are diagonal matrices and each state has a dynamics that 10 | % only depends on its own state but it is controlled by the actuators to 11 | % which the sensor is connected. 12 | % 13 | % For a comprehensive explanation of the problem, see the paper 14 | % 15 | % [1] J. Mota, J. Xavier, P. Aguiar, M. Püschel, 16 | % Distributed Optimization With Local Domains: Applications in MPC 17 | % and Network Flows, to appear in IEEE Transactions on Automatic 18 | % Control, 2015 19 | % 20 | % and the file (in this package) in 21 | % 22 | % ../../GenerateData/Data/MPC/Readme/MPC.pdf 23 | % 24 | % ------------------------------------------------------------------------- 25 | % Distributed Optimization With Local Domains: Applications in MPC and 26 | % Network Flows 27 | % Copyright (C) 2014 Joao Mota 28 | % 29 | % This program is free software: you can redistribute it and/or modify 30 | % it under the terms of the GNU General Public License as published by 31 | % the Free Software Foundation, either version 3 of the License, or 32 | % (at your option) any later version. 33 | % 34 | % This program is distributed in the hope that it will be useful, 35 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 36 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 | % GNU General Public License for more details. 38 | % 39 | % You should have received a copy of the GNU General Public License 40 | % along with this program. If not, see . 41 | % ------------------------------------------------------------------------- 42 | % 43 | % ========================================================================= 44 | % Please send any questions, comments, or bug reports to j.mota@ucl.ac.uk 45 | % ========================================================================= 46 | 47 | 48 | % ========================================================================= 49 | % Directories and filenames 50 | 51 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 52 | addpath('../../GenerateData/Data/MPC/Data/'); % Data 53 | addpath('../../') % Algorithm 54 | 55 | file_networks = 'Barabasi_P_100.mat'; 56 | file_data = 'Barab_NonStar_P_100_UNSTABLE.mat'; % Non-Star 57 | % ========================================================================= 58 | 59 | % ========================================================================= 60 | % Parameters 61 | rho = 74; % Augmented Lagrangian parameter 62 | max_iter = 500; % Maximum number of iterations 63 | eps_opt = 1e-4; % Tolerance 64 | % ========================================================================= 65 | 66 | 67 | % ========================================================================= 68 | % Extract data and networks from files 69 | 70 | % Load files 71 | load(file_networks); 72 | load(file_data); 73 | 74 | % Network data 75 | P = Network.P; 76 | Adj = Network.Adj; 77 | Num_Colors = Network.Num_Colors; 78 | Partition = Network.Partition; 79 | Neighbors = Network.Neighbors; 80 | Degrees = Network.Degrees; 81 | 82 | vars_prob = struct('handler', {@SolverMPC}, ... 83 | 'components', {components}, ... 84 | 'E_p', {E_p}, ... 85 | 'w_p', {w_p} ... 86 | ); 87 | 88 | % Create struct with network information 89 | vars_network = struct('P', {P}, ... 90 | 'neighbors', {Neighbors}, ... 91 | 'partition_colors', {Partition} ... 92 | ); 93 | % ========================================================================= 94 | 95 | 96 | % ========================================================================= 97 | % Execute DADMM_Partial 98 | 99 | % Optional input 100 | ops = struct('rho', {rho}, ... 101 | 'max_iter', {max_iter}, ... 102 | 'x_opt', {solution}, ... 103 | 'eps_opt', {eps_opt} ... 104 | ); 105 | 106 | [X, vars_prob, ops_out] = DADMM_Partial(length(solution), vars_prob, ... 107 | vars_network, ops); 108 | % ========================================================================= 109 | 110 | 111 | % ========================================================================= 112 | % Print results 113 | 114 | iterations = ops_out.iterations; 115 | stop_crit = ops_out.stop_crit; 116 | error_iterations = ops_out.error_iterations; 117 | iter_for_errors = ops_out.iter_for_errors; 118 | 119 | fprintf('Number of iterations = %d\n', iterations); 120 | fprintf('stop_crit = %s\n', stop_crit); 121 | fprintf('iter_for_errors = \n'); 122 | num_rows = size(iter_for_errors, 1); 123 | for i_g = 1 : num_rows 124 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 125 | end 126 | 127 | figure(1);clf; 128 | semilogy(1:iterations,error_iterations(1:iterations), 'b'); 129 | title('error\_{iterations}'); 130 | % ========================================================================= 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /UsageExamples/MPC_PowerGrid/SolverMPC.m: -------------------------------------------------------------------------------- 1 | function [xp, vars_prob] = SolverMPC(p, v, c, X, vars_prob) 2 | 3 | % From vars_prob 4 | E_p = vars_prob.E_p{p}; 5 | w_p = vars_prob.w_p{p}; 6 | 7 | M = E_p + diag(c); 8 | vec = w_p + v; 9 | 10 | xp = -0.5*( M \ vec); 11 | 12 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/Delays_f.m: -------------------------------------------------------------------------------- 1 | function [f, vars_BB] = Delays_f(x, vars_BB) 2 | 3 | v = vars_BB.v; 4 | a = vars_BB.a; 5 | capacities = vars_BB.capacities; 6 | 7 | 8 | f = sum(x./(capacities - x)) + v'*x + a'*(x.^2); 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/Delays_grad.m: -------------------------------------------------------------------------------- 1 | function [g, vars_BB] = Delays_grad(x, vars_BB) 2 | 3 | v = vars_BB.v; 4 | a = vars_BB.a; 5 | capacities = vars_BB.capacities; 6 | 7 | % If there are entries =c_i, the derivative is infinity. To avoid it, 8 | ind_plus_c = (x == capacities); 9 | 10 | x(ind_plus_c) = capacities(ind_plus_c) - 1e-3; 11 | 12 | g = capacities./(capacities - x).^2 + v + 2*a.*x; 13 | 14 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/Delays_proj.m: -------------------------------------------------------------------------------- 1 | function [proj, vars_BB] = Delays_proj(x, vars_BB) 2 | 3 | const = vars_BB.const; 4 | d = vars_BB.d; 5 | capacities = vars_BB.capacities; 6 | NetFlowSolver_proj = vars_BB.NetFlowSolver_proj; 7 | 8 | proj = NetFlowSolver_proj(x, const, d, capacities); 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/Documentation/NetworkFlow.bib: -------------------------------------------------------------------------------- 1 | @BOOK{Ahuja93:NetworkFlows, 2 | AUTHOR = {{Ahuja}, R. and {Magnanti}, T. and {Orlin}, J.}, 3 | TITLE = {Network Flows: Theory, Algorithms, and Applications}, 4 | PUBLISHER = {Prentice Hall}, 5 | YEAR = {1993}, 6 | } 7 | 8 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/Documentation/NetworkFlow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaofcmota/DistributedOptimizationWithLocalDomains/f670f4153453022bbdad61107e861db967822ee3/UsageExamples/NetworkFlow/Documentation/NetworkFlow.pdf -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/NetFlowSolver.m: -------------------------------------------------------------------------------- 1 | function [xp, vars_prob] = NetFlowSolver(p, v, a, X, vars_prob) 2 | 3 | % Solver for Network Flow problems using DADMM_Partial. We use the 4 | % Barzilai-Borwein method (see function SPG_BB). 5 | 6 | % Problem variables 7 | B = vars_prob.B; 8 | d = vars_prob.d; 9 | Dp = vars_prob.Dp; 10 | capacities = vars_prob.capacities; 11 | 12 | Delays_f = vars_prob.function_eval; 13 | Delays_grad = vars_prob.gradient_eval; 14 | Delays_proj = vars_prob.projection; 15 | NetFlowSolver_proj = vars_prob.NetFlowSolver_proj; 16 | SPG_BB = vars_prob.spg_bb; 17 | 18 | 19 | dp = d(p); 20 | 21 | indices_of_x = (B(p,:) ~= 0); 22 | 23 | dim_var = sum(indices_of_x); 24 | 25 | if Dp(p) ~= dim_var 26 | error('Dp(p) ~= sum(indices_of_x) in function NetFlowSolver'); 27 | end 28 | 29 | 30 | % Solve the problem with SPG_BB 31 | 32 | const = B(p, indices_of_x)'; 33 | 34 | vars_BB = struct('f_val', {Delays_f}, ... 35 | 'grad', {Delays_grad}, ... 36 | 'proj', {Delays_proj}, ... 37 | 'NetFlowSolver_proj', {NetFlowSolver_proj}, ... 38 | 'v', {v}, ... 39 | 'a', {a}, ... 40 | 'capacities', {capacities(indices_of_x)}, ... 41 | 'const', {const}, ... 42 | 'd', {dp} ... 43 | ); 44 | 45 | 46 | [xp, vars_BB] = SPG_BB(dim_var, X{p}, vars_BB); 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/NetFlowSolver_proj.m: -------------------------------------------------------------------------------- 1 | function [proj] = NetFlowSolver_proj(y, a, b, c) 2 | 3 | % [proj] = NetFlowSolver_proj(y, a, b, c) 4 | % 5 | % Projects the point y onto the set {a : a'*x = b, 0 <= x <= c}. This boils 6 | % down to solving 7 | % 8 | % minimize 0.5*||x - y||^2 9 | % x 10 | % subject to a'*x = b 11 | % 0 <= x <= c 12 | % 13 | % The solution to this problem can be computed in a very simple way, 14 | % without requiring any iterative solver. 15 | 16 | % Check for input errors 17 | if size(a) ~= size(y) 18 | error('Vectors a and y in ''NetFlowSolver_proj'' do not have the same dimensions.'); 19 | end 20 | n = length(a); 21 | 22 | if sum(abs(a)) ~= n 23 | error('Vector a in ''NetFlowSolver_proj'' should contain only +1 or -1 in its entries.'); 24 | end 25 | 26 | ind_a_pos = (a >= 0); 27 | ind_a_neg = (a < 0); 28 | 29 | points_of_slop_change = [y(ind_a_pos) ; y(ind_a_pos) - c(ind_a_pos) ;... 30 | -y(ind_a_neg); c(ind_a_neg) - y(ind_a_neg)]; 31 | 32 | z = sort(points_of_slop_change); 33 | 34 | % Evaluate the function g(lambda) = a'*max( y - lambda*a , 0 ) for all 35 | % lambda = z(i), i = 1, ..., len_z 36 | 37 | len_z = length(z); 38 | g_z = zeros(len_z,1); 39 | 40 | for i = 1 : len_z 41 | g_z(i) = Evaluate_g(y, a, z(i), c); 42 | end 43 | 44 | % Note: g_z should contain decreasing values 45 | 46 | if b > g_z(1) || b < g_z(len_z) 47 | error('The projection problem passed to the function ''NetFlowSolver_proj'' is infeasible'); 48 | end 49 | 50 | indices = (g_z <= b); 51 | aux = find(indices); 52 | l = aux(1)-1; 53 | 54 | if l == 0 55 | lambda = z(1); 56 | else 57 | lambda = z(l) + (z(l+1) - z(l))*(b - g_z(l))/(g_z(l+1) - g_z(l)); 58 | end 59 | 60 | 61 | % Compute proj 62 | 63 | proj = y - lambda*a; 64 | 65 | for i = 1 : n 66 | if proj(i) < 0 67 | proj(i) = 0; 68 | elseif proj(i) > c(i) 69 | proj(i) = c(i); 70 | end 71 | end 72 | 73 | 74 | end 75 | 76 | 77 | function [g] = Evaluate_g(y, a, lambda, c) 78 | 79 | n = length(y); 80 | 81 | g = 0; 82 | 83 | for i = 1 : n 84 | 85 | point = y(i) - lambda*a(i); 86 | 87 | if point < 0 88 | point = 0; 89 | elseif point > c(i) 90 | point = c(i); 91 | end 92 | 93 | g = g + a(i)*point; 94 | end 95 | 96 | 97 | end 98 | 99 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/README.TXT: -------------------------------------------------------------------------------- 1 | Main file: RunNetworkFlow.m 2 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/RunNetworkFlow.m: -------------------------------------------------------------------------------- 1 | % Solves a network flow problem with DADMM_Partial. The problem is 2 | % 3 | % minimize sum_{(i,j) in E} phi_{ij}(x_{ij}) 4 | % {x_{ij}} 5 | % subject to B*x = d 6 | % 0 <= x <= c 7 | % 8 | % where the variable x_{ij} is defined over the edge ij of the network E, B 9 | % is the node-arc incidence matrix, and d is the vector of sources (sum(d) 10 | % = 0). phi_{ij} is a function associated to the edge ij and it only 11 | % depends on the flow on that edge, x_{ij}. 12 | % 13 | % We will use for each function 14 | % 15 | % phi_{ij}(x_{ij}) = x_{ij}/(c_{ij} - x_{ij}) , 16 | % 17 | % from a multi-commodity flow problem modeling delays at the links. 18 | % 19 | % For a comprehensive explanation of the problem see the paper 20 | % 21 | % [1] J. Mota, J. Xavier, P. Aguiar, M. Püschel, 22 | % Distributed Optimization With Local Domains: Applications in MPC 23 | % and Network Flows, to appear in IEEE Transactions on Automatic 24 | % Control, 2015 25 | % 26 | % and, for a detailed derivation of the algorithm, see the file 27 | % NetworkFlow.pdf in the folder Documentation. 28 | % 29 | % ------------------------------------------------------------------------- 30 | % Distributed Optimization With Local Domains: Applications in MPC and 31 | % Network Flows 32 | % Copyright (C) 2014 Joao Mota 33 | % 34 | % This program is free software: you can redistribute it and/or modify 35 | % it under the terms of the GNU General Public License as published by 36 | % the Free Software Foundation, either version 3 of the License, or 37 | % (at your option) any later version. 38 | % 39 | % This program is distributed in the hope that it will be useful, 40 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 41 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 42 | % GNU General Public License for more details. 43 | % 44 | % You should have received a copy of the GNU General Public License 45 | % along with this program. If not, see . 46 | % ------------------------------------------------------------------------- 47 | % 48 | % ========================================================================= 49 | % Please send any questions, comments, or bug reports to j.mota@ucl.ac.uk 50 | % ========================================================================= 51 | 52 | 53 | % ========================================================================= 54 | % Directories and filenames 55 | 56 | addpath('../../GenerateData/Networks/MPC/ProcessedNetwork/'); % Networks 57 | addpath('../../GenerateData/Data/NetworkFlows/Results/'); % Data 58 | addpath('../../'); % Algorithm 59 | 60 | %file_networks = 'Barabasi_P_2000.mat'; 61 | %file_data = 'NFData_Barabasi_P_2000.mat'; 62 | file_networks = 'Barabasi_P_100.mat'; 63 | file_data = 'NFData_Barabasi_P_100.mat'; 64 | 65 | % ========================================================================= 66 | 67 | % ========================================================================= 68 | % Parameters 69 | rho = 0.02; % Augmented Lagrangian parameter 70 | max_iter = 1000; % Maximum number of iterations 71 | eps_opt = 1e-4; % Tolerance 72 | % ========================================================================= 73 | 74 | 75 | % ========================================================================= 76 | % Extract data and networks from files 77 | 78 | % Load files 79 | load(file_networks); 80 | load(file_data); 81 | 82 | % Network data 83 | Adj = Network.Adj; % Adjacency matrix 84 | partition_colors = Network.Partition; % Color partition of network 85 | P = length(Adj); % Number of nodes 86 | neighbors = Network.Neighbors; 87 | Dp = Network.Degrees; 88 | 89 | 90 | % Create struct with network information 91 | vars_network = struct('P', {P}, ... 92 | 'neighbors', {neighbors}, ... 93 | 'partition_colors', {partition_colors} ... 94 | ); 95 | 96 | 97 | % Create vars_prob 98 | 99 | B = incidence_matrix; 100 | num_edges = size(incidence_matrix,2); 101 | d = flows; 102 | 103 | components = cell(P,1); 104 | 105 | for p = 1 : P 106 | components{p} = find(B(p,:) ~= 0); 107 | end 108 | 109 | vars_prob = struct('handler', {@NetFlowSolver}, ... 110 | 'function_eval' , {@Delays_f}, ... 111 | 'gradient_eval' , {@Delays_grad}, ... 112 | 'projection' , {@Delays_proj}, ... 113 | 'NetFlowSolver_proj', {@NetFlowSolver_proj}, ... 114 | 'spg_bb' , {@SPG_BB}, ... 115 | 'components', {components}, ... 116 | 'B', {B}, ... 117 | 'd', {d}, ... 118 | 'capacities', {capacities}, ... 119 | 'Dp', {Dp} ... 120 | ); 121 | % ========================================================================= 122 | 123 | 124 | % ========================================================================= 125 | % Execute DADMM_Partial 126 | 127 | % Optional input 128 | ops = struct('rho', {rho}, ... 129 | 'max_iter', {max_iter}, ... 130 | 'x_opt', {solution}, ... 131 | 'eps_opt', {eps_opt} ... 132 | ); 133 | 134 | [X, vars_prob, ops_out] = DADMM_Partial(num_edges, vars_prob, vars_network, ops); 135 | % ========================================================================= 136 | 137 | 138 | % ========================================================================= 139 | % Print results 140 | 141 | iterations = ops_out.iterations; 142 | stop_crit = ops_out.stop_crit; 143 | error_iterations = ops_out.error_iterations; 144 | iter_for_errors = ops_out.iter_for_errors; 145 | 146 | % Evaluate the relative error 147 | error = 0; 148 | 149 | for p = 1 : P 150 | error = error + norm(X{p} - solution(components{p})); 151 | end 152 | error = error/P; 153 | 154 | fprintf('rho = %d\n', rho); 155 | fprintf('Relative error = %E\n', error); 156 | fprintf('Number of iterations = %d\n', iterations); 157 | fprintf('stop_crit = %s\n', stop_crit); 158 | fprintf('iter_for_errors = \n'); 159 | num_rows = size(iter_for_errors, 1); 160 | for i_g = 1 : num_rows 161 | fprintf('%E %d\n', iter_for_errors(i_g,1), iter_for_errors(i_g,2)); 162 | end 163 | 164 | figure(1);clf; 165 | semilogy(1:iterations,error_iterations(1:iterations), 'b'); 166 | title('error\_{iterations}'); 167 | % ========================================================================= 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /UsageExamples/NetworkFlow/SPG_BB.m: -------------------------------------------------------------------------------- 1 | function [x_opt, vars_prob] = SPG_BB(n, x0, vars_prob) 2 | 3 | % [x_opt, vars_prob] = SPG_BB(n, x0, vars_prob) 4 | % 5 | % Implements a Spectral Projected Gradient (SPG) Method, using a technique 6 | % similar to that of Barzilai-Borwein. More specifically, it implements the 7 | % algorithm SPG1 from 8 | % 9 | % E. Birgin, J. Martinez, and M. Raydan, "Nonmonotone Spectral Projected 10 | % Gradient Methods on Convex Sets," SIAM J. Optim, Vol.10, No.4, 2000, pp. 11 | % 1196-1211 12 | % 13 | % SPG_BB solves 14 | % 15 | % minimize f(x) 16 | % subject to x in X 17 | % 18 | % where f(x) is a convex, continuously differentiable function, and X a 19 | % closed convex set. It is required from the user to provide three 20 | % functions in the struct vars_prob. In the field 'f_val' should be a 21 | % handler for 22 | % 23 | % [f, vars_prob] = function_name(x, vars_prob) 24 | % 25 | % where x is a vector of size n, and f is the value of the function f at x, 26 | % i.e., f(x). In the field 'grad' should be a handler for 27 | % 28 | % [g, vars_prob] = function_name(x, vars_prob) 29 | % 30 | % where x is a vector of size n, and g is the gradient of f at the point x. 31 | % In the field 'proj' should be a handler for 32 | % 33 | % [p, vars_prob] = function_name(x, vars_prob) 34 | % 35 | % where x is has size n, and p is the projection of x onto the set X, i.e., 36 | % p = argmin{ ||z-x|| : z in X}. 37 | % 38 | % The remaining fields of the struct vars_prob can be used by the user to 39 | % store information useful for the implementation of the above functions. 40 | % 41 | % The SPG_BB inputs and outputs are: 42 | % 43 | % Inputs: 44 | % 45 | % - n: size of the variable 46 | % 47 | % - x0: initialization vector n x 1. If empty ([]), the algorithm is 48 | % initialized with the vector of zeros 49 | % 50 | % - vars_prob: struct with the following compulsory fields (explained 51 | % above): 52 | % . f_val 53 | % . grad 54 | % . proj 55 | % The remaining struct can be used to optimize the 56 | % algorithm. 57 | % 58 | % Outputs: 59 | % 60 | % - x_opt: optimal value for the variable x 61 | % 62 | % - vars_prob: same struct as input 63 | % 64 | % ------------------------------------------------------------------------- 65 | % ------------------------------------------------------------------------- 66 | % Please send any questions, comments, or bug reports to joaomota@cmu.edu. 67 | % ------------------------------------------------------------------------- 68 | % ------------------------------------------------------------------------- 69 | 70 | 71 | % ========================================================================= 72 | % Check for input errors 73 | 74 | if ~isstruct(vars_prob) 75 | error('vars_prob (3rd argument of SPG_BB) should be a struct. Please type ''help SPG_BB''.'); 76 | end 77 | if ~isfield(vars_prob, 'f_val') 78 | error('vars_prob (3rd argument of SPG_BB) should contain the field ''f_val''. Please type ''help SPG_BB''.'); 79 | end 80 | if ~isfield(vars_prob, 'grad') 81 | error('vars_prob (3rd argument of SPG_BB) should contain the field ''grad''. Please type ''help SPG_BB''.'); 82 | end 83 | if ~isfield(vars_prob, 'proj') 84 | error('vars_prob (3rd argument of SPG_BB) should contain the field ''proj''. Please type ''help SPG_BB''.'); 85 | end 86 | 87 | if isempty(x0) 88 | x_init = zeros(n,1); 89 | else 90 | x_init = x0; 91 | if length(x_init) ~= n 92 | error('Input vector x0 is not of size n. Please type ''help SPG_BB''.'); 93 | end 94 | end 95 | % ========================================================================= 96 | 97 | 98 | % ========================================================================= 99 | % Parameters of the algorithm (we will use the ones suggested by the paper) 100 | 101 | MAX_ITER = 1e3; % Maximum number of iterations (warning if reached) 102 | 103 | MAX_ITER_IN = 1e3; % Maximum number of iterations for the inner loop 104 | 105 | epsilon = 1e-10; % Algorithm stops if ||P(x_k - g(x_k))-x_k||<= epsilon 106 | 107 | M = 30; % Memory of the nonmonotone algorithm 108 | 109 | gamma = 1e-4; % Sufficient decrease parameter 110 | 111 | alpha_min = 1e-6; % Maximum and minimum value for the stepsize 112 | alpha_max = 1e6; 113 | 114 | sigma_1 = 0.1; % Safeguarding parameters 115 | sigma_2 = 0.9; 116 | % ========================================================================= 117 | 118 | 119 | % ========================================================================= 120 | % Algorithm 121 | 122 | % Function handlers 123 | f = vars_prob.f_val; 124 | g = vars_prob.grad; 125 | proj = vars_prob.proj; 126 | 127 | % Vector with the value of f for the past M iterations 128 | past_f = Inf*ones(M,1); 129 | 130 | % Initializations 131 | x_k = x_init; 132 | [g_k, vars_prob] = g(x_k, vars_prob); 133 | [proj_xg, vars_prob] = proj(x_k - g_k, vars_prob); 134 | alpha = min(alpha_min, 1/max(abs(proj_xg - x_k))); % recommended by the paper's authors 135 | 136 | for iter = 1 : MAX_ITER 137 | 138 | lambda = alpha; 139 | 140 | for inner_iter = 1 : MAX_ITER_IN 141 | [x_new, vars_prob] = proj(x_k - lambda*g_k, vars_prob); 142 | 143 | gamma_inner_prod = gamma*(x_new - x_k)'*g_k; 144 | gamma_inner_prod_vec = ones(M,1)*gamma_inner_prod; 145 | 146 | max_val = max(past_f + gamma_inner_prod_vec); 147 | [f_new, vars_prob] = f(x_new, vars_prob); 148 | 149 | if f_new <= max_val 150 | x_prev = x_k; 151 | g_prev = g_k; 152 | x_k = x_new; 153 | s_k = x_k - x_prev; 154 | [g_k, vars_prob] = g(x_k, vars_prob); 155 | y_k = g_k - g_prev; 156 | break; 157 | else 158 | lambda_new = lambda/2; 159 | lambda_new = max(lambda_new, sigma_1*lambda); 160 | lambda = min(lambda_new, sigma_2*lambda); 161 | end 162 | end 163 | 164 | if inner_iter == MAX_ITER_IN 165 | fprintf('Warning: Maximum number of iterations reached in the inner loop of SPG_BB\n'); 166 | end 167 | 168 | % Store the value of f in past_f 169 | [f_k, vars_prob] = f(x_k, vars_prob); 170 | index = mod(iter, M) + 1; 171 | past_f(index) = f_k; 172 | 173 | b_k = s_k'*y_k; 174 | 175 | if b_k <= 0 176 | alpha = alpha_max; 177 | else 178 | a_k = norm(s_k)^2; 179 | alpha = min( alpha_max , max(alpha_min, a_k/b_k) ); 180 | end 181 | 182 | % Compute f and g at point x_k 183 | [g_k, vars_prob] = g(x_k, vars_prob); 184 | [proj_xg, vars_prob] = proj(x_k - g_k, vars_prob); 185 | 186 | % Stopping criterion 187 | if max(abs(proj_xg - x_k)) <= epsilon 188 | break; 189 | end 190 | end 191 | % ========================================================================= 192 | 193 | %iter 194 | if iter == MAX_ITER 195 | fprintf('Warning: Maximum number of iterations reached in SPG_BB\n'); 196 | end 197 | 198 | x_opt = x_k; 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /svgs/2da32a437e1e022c68095bcb359d92a2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /svgs/2ec6e630f199f589a2402fdf3e0289d5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /svgs/332cc365a4987aacce0ead01b8bdcc0b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /svgs/55a049b8f161ae7cfeb0197d75aff967.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /svgs/b7dec1314efeadd1815bf346b3472200.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | --------------------------------------------------------------------------------