00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <twod/jagged_dp_pq.hpp>
00038
00039 template<typename T, typename Pr>
00040 T twod::JagPQOptHor<T,Pr>::part(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00041 {
00042 using namespace util;
00043 int p;
00044
00045 if (P == 0)
00046 p = intfactor(procCount);
00047 else
00048 p = P;
00049
00050 int q = procCount / p;
00051
00052 return jagged_dp_pq_internal ( p, q, prefixSumArray, parts);
00053 }
00054
00055 template<typename T, typename Pr>
00056 T twod::JagPQOptHor<T,Pr>::jagged_dp_pq_internal(int P, int Q, const Pr& prefixSumArray, util::RectList<T,Pr> & parts)
00057 {
00058 using namespace oned;
00059 using namespace util;
00060 struct DP
00061 {
00062 const Pr& psa;
00063 Compact2D<T> dp_array;
00064 Compact2D<T> algo_1d_lazy;
00065 Compact2D<T> max_lazy;
00066
00067 int nbprocX;
00068 int nbprocY;
00069
00070 int nbfill;
00071
00072 T best;
00073 int nb_ub_1d_cut_useful;
00074 int nb_ub_2d_cut_useful;
00075
00076 DP(int P, int Q, const Pr& prefixSumArray)
00077 :psa(prefixSumArray),
00078 dp_array(prefixSumArray.prefixsizeX(), P+1),
00079 algo_1d_lazy(prefixSumArray.prefixsizeX(),prefixSumArray.prefixsizeX()),
00080 max_lazy(prefixSumArray.prefixsizeX(),prefixSumArray.prefixsizeX()),
00081 nbprocX(P),
00082 nbprocY(Q),
00083 nbfill(0),
00084 best(infinite()),
00085 nb_ub_1d_cut_useful(0),
00086 nb_ub_2d_cut_useful(0)
00087 {
00088 for (int i=0; i<prefixSumArray.prefixsizeX(); i++)
00089 for (int j=0; j<nbprocX+1; j++)
00090 dp_array[i][j] = -1;
00091
00092
00093 for (int i=0; i<prefixSumArray.prefixsizeX(); i++)
00094 for (int j=0; j<prefixSumArray.prefixsizeX(); j++)
00095 {
00096 algo_1d_lazy[i][j]=-1;
00097 max_lazy[i][j]=-1;
00098 }
00099
00100 }
00101
00102 T infinite() const
00103 {
00104 return psa[psa.prefixsizeX()-1][psa.prefixsizeY()-1]+1;
00105 }
00106
00107 T eval(int n, int m)
00108 {
00109 assert (n >= 0);
00110 assert (m >= 0);
00111
00112 assert (dp_array[n][m] <= infinite());
00113
00114 if (dp_array[n][m] < 0 )
00115 fill(n,m);
00116
00117 return dp_array[n][m];
00118 }
00119
00120
00121
00122 void algo_1d_fill(int x, int n, RectList<T,Pr> & parts)
00123 {
00124 const int m = nbprocY;
00125
00126 assert (m>0);
00127
00128 int *cuts = new int[m];
00129
00130 Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, x, n, 1, psa.prefixsizeY() - 1);
00131 NicolPlus<T, Aggreg2Dto1D<T, Pr, false> >::nicol_plus (m, ps1dx_row, psa.prefixsizeY(), cuts, max_lazy[x][n]);
00132
00133 rectangle r;
00134
00135 r.x_top_l = x;
00136 r.x_bot_r = n;
00137
00138
00139
00140 r.y_top_l = 1;
00141
00142
00143
00144 for(int j = 0; j < m; j++)
00145 {
00146 r.y_bot_r = (j == m - 1) ? psa.prefixsizeY() - 1 :cuts[j];
00147 if(r.valid_bound(psa))
00148 {
00149
00150 parts.add_rect(r);
00151
00152 r.y_top_l = r.y_bot_r + 1;
00153 }
00154 else
00155 {
00156 break;
00157 }
00158 }
00159
00160
00161
00162 delete[] cuts;
00163 }
00164
00165
00166
00167 T algo_1d(int x, int n)
00168 {
00169 const int m = nbprocY;
00170
00171 if (algo_1d_lazy[x][n] < 0 )
00172 {
00173 Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, x, n, 1, psa.prefixsizeY() - 1);
00174 algo_1d_lazy[x][n] = NicolPlus<T, Aggreg2Dto1D<T, Pr, false> >::nicol_plus (m, ps1dx_row, psa.prefixsizeY(), NULL, max_lazy[x][n]);
00175 assert (ps1dx_row[psa.prefixsizeY()-1 ] >= 0);
00176 assert (ps1dx_row[psa.prefixsizeY()-1 ] <= infinite());
00177 assert (algo_1d_lazy[x][n] >= 0);
00178 assert (algo_1d_lazy[x][n] <= infinite());
00179
00180 }
00181
00182 return algo_1d_lazy[x][n];
00183 }
00184
00185
00186
00187 T algo_1d_lb(int x, int n)
00188 {
00189 const int m = nbprocY;
00190 if (algo_1d_lazy[x][n] < 0 )
00191 {
00192 Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, x, n, 1, psa.prefixsizeY() - 1);
00193 return ps1dx_row[psa.prefixsizeY()-1]/m;
00194 }
00195 else
00196 return algo_1d_lazy[x][n];
00197 }
00198
00199
00200
00201 T algo_2d_lb(int n, int m)
00202 {
00203 if (n == 0) return 0;
00204 if (m == 0) return infinite();
00205
00206
00207 if (dp_array[n][m] < 0)
00208 {
00209 Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, 1, n, 1, psa.prefixsizeY() - 1);
00210 return ps1dx_row[psa.prefixsizeY()-1]/(m*nbprocY);
00211 }
00212 else
00213 return dp_array[n][m];
00214 }
00215
00216 T algo_2d_ub(int n, int m)
00217 {
00218 if (n == 0) return 0;
00219 if (m == 0) return infinite();
00220
00221
00222 if (dp_array[n][m] < 0)
00223 {
00224 Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, 1, n, 1, psa.prefixsizeY() - 1);
00225 return ps1dx_row[psa.prefixsizeY()-1];
00226 }
00227 else
00228 return dp_array[n][m];
00229 }
00230
00231
00232
00233
00234 T algo_1d_ub(int x, int n)
00235 {
00236 const int m = nbprocY;
00237 assert (m != 0);
00238
00239
00240 if (algo_1d_lazy[x][n] < 0 )
00241 {
00242
00243
00244 Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, x, n, 1, psa.prefixsizeY() - 1);
00245
00246 if (max_lazy[x][n] < 0)
00247 {
00248
00249 max_lazy[x][n] = 0;
00250 for (int i=1;i<psa.prefixsizeY();i++)
00251 max_lazy[x][n] = std::max(max_lazy[x][n], ps1dx_row[i]-ps1dx_row[i-1]);
00252
00253 }
00254
00255 return max_lazy[x][n] + ps1dx_row[psa.prefixsizeY()-1]/m;
00256 }
00257 else
00258 return algo_1d_lazy[x][n];
00259 }
00260
00261
00262
00263
00264 T compute(int n, int m)
00265 {
00266 if (n == 0) return 0;
00267 if (m == 0) return infinite();
00268 if (m == 1) return algo_1d (1,n);
00269
00270
00271 T minimum = infinite();
00272
00273 for (int x=1; x<= n; x++)
00274 {
00275
00276 int p = m-1;
00277 {
00278 if (algo_2d_lb(x-1,p) > best)
00279 {
00280 continue;
00281 }
00282
00283 if (algo_2d_lb(x-1,p) >= minimum)
00284 {
00285 continue;
00286 }
00287
00288 if (algo_1d_lb(x,n) >= minimum)
00289 {
00290
00291 continue;
00292 }
00293
00294 T e = 0;
00295 T a = 0;
00296
00297
00298 if (algo_1d_ub(x,n) <= e)
00299 {
00300 a = e;
00301 }
00302 else
00303 a = algo_1d(x,n);
00304
00305 if (a > best)
00306 {
00307
00308 continue;
00309 }
00310
00311 if (a >= minimum)
00312 {
00313
00314 continue;
00315 }
00316
00317
00318 if (algo_2d_ub(x-1,p) < a)
00319 {
00320 e = a;
00321 }
00322 else
00323 {
00324 e = eval(x-1,p);
00325 }
00326
00327 if (e > best)
00328 {
00329 continue;
00330 }
00331 if (e >= minimum)
00332 {
00333 continue;
00334 }
00335
00336
00337
00338 T maximum = std::max (e, a);
00339 minimum = std::min ( minimum, maximum );
00340
00341 if (n == psa.prefixsizeX()-1 && m == nbprocX)
00342 if (minimum < best)
00343 best = minimum;
00344 }
00345 }
00346
00347 return minimum;
00348 }
00349
00350 void fill (int n, int m)
00351 {
00352 dp_array[n][m] = compute(n,m);
00353 }
00354
00355 void fill()
00356 {
00357 for (int i=0; i<=psa.prefixsizeX()-1; i++)
00358 {
00359 for (int p=0; p<=nbprocX; p++)
00360 fill(i,p);
00361 }
00362 }
00363
00364 void backtrack(int n, int m, RectList<T,Pr> & parts)
00365 {
00366 if (m == 0) return;
00367 if (n == 0) return;
00368
00369 T minimum = eval(n,m);
00370
00371 for (int x=1; x<= n; x++)
00372 {
00373
00374 int p = m-1;
00375 {
00376 if (algo_2d_lb(x-1,p) > minimum)
00377 continue;
00378 if (algo_1d_lb(x,n) > minimum)
00379 continue;
00380
00381 T a = algo_1d(x,n);
00382 if (a > minimum)
00383 break;
00384
00385 T e = eval(x-1,p);
00386 if (e > minimum)
00387 continue;
00388
00389
00390
00391 T maximum = std::max (e, a);
00392
00393 if (maximum == minimum)
00394 {
00395 algo_1d_fill(x,n,parts);
00396
00397 backtrack(x-1,p,parts);
00398 return;
00399 }
00400 }
00401 }
00402 }
00403
00404 void backtrack(RectList<T,Pr> & parts)
00405 {
00406 backtrack(psa.prefixsizeX()-1,nbprocX, parts);
00407 }
00408
00409 T opt()
00410 {
00411 T ret = eval(psa.prefixsizeX()-1, nbprocX);
00412 return ret;
00413 }
00414
00415
00416 void setBest(T b)
00417 {
00418 best = b;
00419 }
00420 };
00421
00422
00423
00424 DP data (P, Q, prefixSumArray);
00425
00426
00427
00428
00429
00430 {
00431 util::RectList<T,Pr> trash(prefixSumArray);
00432
00433 twod::JagPQHeurHor<T, Pr > foo;
00434 foo.setP(P);
00435 data.setBest( foo.part(P*Q, prefixSumArray, trash) );
00436 }
00437
00438
00439
00440
00441 T opt = data.opt();
00442 data.backtrack(parts);
00443
00444 return opt;
00445 }
00446
00447
00448 template <typename T, typename Pr>
00449 T twod::JagPQOptVer<T, Pr>::part(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00450 {
00451 JagPQOptHor <T, util::TransposePrefix2D<T, Pr > > foo;
00452
00453 foo.setP(P);
00454
00455 util::TransposePrefix2D<T, Pr> tpr (prefixSumArray);
00456
00457 util::RectList<T, util::TransposePrefix2D<T, Pr> > intermediate (tpr);
00458
00459 T val = foo.part(procCount,tpr,intermediate);
00460
00461 util::TransposePrefix2D<T, Pr>::convertRectList(intermediate, parts);
00462
00463 return val;
00464 }
00465
00466
00467 template <typename T, typename Pr>
00468 T twod::JagPQOptBest<T, Pr>::part(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00469 {
00470 using namespace util;
00471 RectList<T,Pr > partsv(prefixSumArray);
00472 RectList<T,Pr > partsh(prefixSumArray);
00473 JagPQOptVer<T,Pr> foov;
00474 JagPQOptHor<T,Pr> fooh;
00475 T ort1 = foov.part(procCount, prefixSumArray, partsv);
00476 T ort2 = fooh.part(procCount, prefixSumArray, partsh);
00477 if(ort1 > ort2)
00478 {
00479 parts.copy_into(partsh);
00480 return ort2;
00481 }
00482 else
00483 {
00484 parts.copy_into(partsv);
00485 return ort1;
00486 }
00487 }