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.hpp>
00038 #include <twod/m_way_jag_2d.hpp>
00039
00040 template<typename T, typename Pr>
00041 T twod::JagMOptHor<T,Pr>::part(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00042 {
00043 return jagged_dp_internal ( procCount, prefixSumArray, parts);
00044 }
00045
00046
00047
00048 template<typename T, typename Pr>
00049 T twod::JagMOptHor<T,Pr>::jagged_dp_internal(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> & parts)
00050 {
00051 using namespace oned;
00052 using namespace util;
00053 struct DP
00054 {
00055 const Pr& psa;
00056 util::Compact2D<T> dp_array;
00057 util::Compact3D<T> algo_1d_lazy;
00058 util::Compact2D<T> max_lazy;
00059
00060 int nbproc;
00061
00062 int nbfill;
00063
00064 T best;
00065 int nb_ub_1d_cut_useful;
00066 int nb_ub_2d_cut_useful;
00067
00068 DP(int procCount, const Pr& prefixSumArray)
00069 :psa(prefixSumArray),
00070 dp_array(prefixSumArray.prefixsizeX(), procCount+1),
00071 algo_1d_lazy(prefixSumArray.prefixsizeX(),prefixSumArray.prefixsizeX(),procCount+1),
00072 max_lazy(prefixSumArray.prefixsizeX(),prefixSumArray.prefixsizeX()),
00073 nbproc(procCount),
00074 nbfill(0),
00075 best(infinite()),
00076 nb_ub_1d_cut_useful(0),
00077 nb_ub_2d_cut_useful(0)
00078 {
00079 for (int i=0; i<prefixSumArray.prefixsizeX(); i++)
00080 for (int j=0; j<procCount+1; j++)
00081 dp_array[i][j] = -1;
00082
00083
00084 for (int i=0; i<prefixSumArray.prefixsizeX(); i++)
00085 for (int j=0; j<prefixSumArray.prefixsizeX(); j++)
00086 for (int k=0; k<procCount+1; k++)
00087 {
00088 algo_1d_lazy(i,j,k)=-1;
00089 max_lazy[i][j]=-1;
00090 }
00091
00092 }
00093
00094 T infinite() const
00095 {
00096 return psa[psa.prefixsizeX()-1][psa.prefixsizeY()-1]+1;
00097 }
00098
00099 T eval(int n, int m)
00100 {
00101 assert (n >= 0);
00102 assert (m >= 0);
00103
00104 assert (dp_array[n][m] <= infinite());
00105
00106 if (dp_array[n][m] < 0 )
00107 fill(n,m);
00108
00109 return dp_array[n][m];
00110 }
00111
00124 void algo_1d_fill(int x, int n, int m, util::RectList<T,Pr> & parts)
00125 {
00126 assert (m>0);
00127
00128 int *cuts = new int[m];
00129
00130 util::Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, x, n, 1, psa.prefixsizeY() - 1);
00131 oned::NicolPlus<T, util::Aggreg2Dto1D<T, Pr, false> >::nicol_plus (m, ps1dx_row, psa.prefixsizeY(), cuts, max_lazy[x][n]);
00132
00133 util::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
00177 T algo_1d(int x, int n, int m)
00178 {
00179 if (algo_1d_lazy(x,n,m) < 0 )
00180 {
00181
00182 util::Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, x, n, 1, psa.prefixsizeY() - 1);
00183 algo_1d_lazy(x,n,m) = NicolPlus<T, util::Aggreg2Dto1D<T, Pr, false> >::nicol_plus (m, ps1dx_row, psa.prefixsizeY(), NULL, max_lazy[x][n]);
00184 }
00185
00186 return algo_1d_lazy(x,n,m);
00187 }
00188
00202 T algo_1d_lb(int x, int n, int m)
00203 {
00204 if (algo_1d_lazy(x,n,m) < 0 )
00205 {
00206 util::Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, x, n, 1, psa.prefixsizeY() - 1);
00207 return ps1dx_row[psa.prefixsizeY()-1]/m;
00208 }
00209 else
00210 return algo_1d_lazy(x,n,m);
00211 }
00212
00217 T algo_2d_lb(int n, int m)
00218 {
00219 if (n == 0) return 0;
00220 if (m == 0) return infinite();
00221
00222
00223 if (dp_array[n][m] < 0)
00224 {
00225 util::Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, 1, n, 1, psa.prefixsizeY() - 1);
00226 return ps1dx_row[psa.prefixsizeY()-1]/m;
00227 }
00228 else
00229 return dp_array[n][m];
00230 }
00231
00236 T algo_2d_ub(int n, int m)
00237 {
00238 if (n == 0) return 0;
00239 if (m == 0) return infinite();
00240
00241
00242 if (dp_array[n][m] < 0)
00243 {
00244 util::Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, 1, n, 1, psa.prefixsizeY() - 1);
00245 return ps1dx_row[psa.prefixsizeY()-1];
00246 }
00247 else
00248 return dp_array[n][m];
00249 }
00250
00264 T algo_1d_ub(int x, int n, int m)
00265 {
00266 assert (m != 0);
00267 if (algo_1d_lazy(x,n,m) < 0 )
00268 {
00269 util::Aggreg2Dto1D<T, Pr, false> ps1dx_row(psa, x, n, 1, psa.prefixsizeY() - 1);
00270
00271 if (max_lazy[x][n] < 0)
00272 {
00273
00274 max_lazy[x][n] = 0;
00275 for (int i=1;i<psa.prefixsizeY();i++)
00276 max_lazy[x][n] = std::max(max_lazy[x][n], ps1dx_row[i]-ps1dx_row[i-1]);
00277
00278 }
00279
00280 return max_lazy[x][n] + ps1dx_row[psa.prefixsizeY()-1]/m;
00281 }
00282 else
00283 return algo_1d_lazy(x,n,m);
00284 }
00285
00286
00287
00288
00289 T compute(int n, int m)
00290 {
00291 if (n == 0) return 0;
00292 if (m == 0) return infinite();
00293
00294 T minimum = infinite();
00295
00296 for (int x=1; x<= n; x++)
00297 {
00298
00299 for (int p=0; p<=m-1; p++)
00300 {
00301
00302 if (algo_2d_lb(x-1,p) > best)
00303 {
00304 continue;
00305 }
00306
00307 if (algo_2d_lb(x-1,p) >= minimum)
00308 {
00309 continue;
00310 }
00311
00312 if (algo_1d_lb(x,n,m-p) >= minimum)
00313 {
00314
00315 break;
00316 }
00317
00318 T e = 0;
00319 T a = 0;
00320
00321
00322 if (algo_1d_ub(x,n,m-p) <= e)
00323 {
00324 a = e;
00325 }
00326 else
00327 a = algo_1d(x,n,m-p);
00328
00329 if (a > best)
00330 {
00331
00332 break;
00333 }
00334
00335 if (a >= minimum)
00336 {
00337 break;
00338 }
00339
00340
00341 if (algo_2d_ub(x-1,p) < a)
00342 {
00343 e = a;
00344 }
00345 else
00346 {
00347 e = eval(x-1,p);
00348 }
00349
00350 if (e > best)
00351 {
00352 continue;
00353 }
00354 if (e >= minimum)
00355 {
00356 continue;
00357 }
00358
00359 T maximum = std::max (e, a);
00360
00361 assert (maximum >= algo_2d_lb(x-1,p));
00362 assert (maximum >= algo_1d_lb(x,n,m-p));
00363 assert (maximum >= e);
00364 assert (maximum >= a);
00365
00366 if (minimum > maximum)
00367 {
00368 minimum = maximum;
00369 }
00370
00371 if (n == psa.prefixsizeX()-1 && m == nbproc)
00372 if (minimum < best)
00373 best = minimum;
00374 }
00375 }
00376
00377 return minimum;
00378 }
00379
00385 void fill (int n, int m)
00386 {
00387 dp_array[n][m] = compute(n,m);
00388 }
00389
00394 void fill()
00395 {
00396 for (int i=0; i<=psa.prefixsizeX()-1; i++)
00397 {
00398 for (int p=0; p<=nbproc; p++)
00399 fill(i,p);
00400 }
00401 }
00402
00403 void backtrack(int n, int m, util::RectList<T,Pr> & parts)
00404 {
00405
00406 if (n == 0) return;
00407 if (m == 0) { return;}
00408
00409 T minimum = eval(n,m);
00410
00411 for (int x=1; x <= n; x++)
00412 {
00413 for (int p=0; p<=m-1; p++)
00414 {
00415 if (algo_2d_lb(x-1,p) > minimum)
00416 {
00417 continue;
00418 }
00419 if (algo_1d_lb(x,n,m-p) > minimum)
00420 {
00421 continue;
00422 }
00423
00424 T a = algo_1d(x,n,m-p);
00425 if (a > minimum)
00426 {
00427 break;
00428 }
00429
00430 T e = eval(x-1,p);
00431 if (e > minimum)
00432 {
00433 continue;
00434 }
00435
00436 T maximum = std::max (e, a);
00437
00438 if (maximum == minimum)
00439 {
00440 algo_1d_fill(x,n,m-p,parts);
00441
00442 backtrack(x-1,p,parts);
00443 return;
00444 }
00445 }
00446 }
00447
00448 }
00449
00457 void backtrack(util::RectList<T,Pr> & parts)
00458 {
00459 backtrack(psa.prefixsizeX()-1,nbproc, parts);
00460 }
00461
00466 T opt()
00467 {
00468 T ret = eval(psa.prefixsizeX()-1, nbproc);
00469 return ret;
00470 }
00471
00479 void setBest(T b)
00480 {
00481 best = b;
00482 }
00483 };
00484
00485 DP data (procCount, prefixSumArray);
00486 {
00487 util::RectList<T,Pr> trash(prefixSumArray);
00488
00489 twod::JagMHeurHor<T, Pr > foo;
00490 data.setBest( foo.part(procCount, prefixSumArray, trash) );
00491 }
00492
00493
00494 T opt = data.opt();
00495 data.backtrack(parts);
00496
00497 return opt;
00498 }
00499
00500
00501 template <typename T, typename Pr>
00502 T twod::JagMOptVer<T, Pr>::part(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00503 {
00504 JagMOptHor <T, util::TransposePrefix2D<T, Pr > > foo;
00505
00506 util::TransposePrefix2D<T, Pr> tpr (prefixSumArray);
00507
00508 util::RectList<T, util::TransposePrefix2D<T, Pr> > intermediate (tpr);
00509
00510 T val = foo.part(procCount,tpr,intermediate);
00511
00512 util::TransposePrefix2D<T, Pr>::convertRectList(intermediate, parts);
00513
00514 return val;
00515 }
00516
00517
00518 template <typename T, typename Pr>
00519 T twod::JagMOptBest<T, Pr>::part(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00520 {
00521 using namespace util;
00522 RectList<T,Pr > partsv(prefixSumArray);
00523 RectList<T,Pr > partsh(prefixSumArray);
00524 JagMOptVer<T,Pr> foov;
00525 JagMOptHor<T,Pr> fooh;
00526 T ort1 = foov.part(procCount, prefixSumArray, partsv);
00527 T ort2 = fooh.part(procCount, prefixSumArray, partsh);
00528 if(ort1 > ort2)
00529 {
00530 parts.copy_into(partsh);
00531 return ort2;
00532 }
00533 else
00534 {
00535 parts.copy_into(partsv);
00536 return ort1;
00537 }
00538 }