00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include "dp_config.h"
00004 #include "eg_mempool.h"
00005 #include "eg_dptighten.h"
00006 #define DPT_ENABLE 1
00007 #if DPT_ENABLE
00008 #include "eg_ugraph.h"
00009 #include "eg_bit.h"
00010 #include "eg_util.h"
00011 #include "eg_bbtree.h"
00012
00013
00014 #define DPT_MAX_DOM 512U
00015 #define DPT_MAX_DOM_LOG 9U
00016 #define DPT_MAX_NODE 131072U
00017 #define DPT_MAX_NODE_LOG 17U
00018 #define DPT_MAX_DEPTH 1U
00019
00020
00021
00022
00023
00025 typedef struct
00026 {
00027 unsigned int n_id:DPT_MAX_NODE_LOG;
00029 unsigned int move_id:5;
00030 unsigned int dom;
00031 }
00032 DPTMove_t;
00033
00034
00036 typedef struct
00037 {
00038 DPTMove_t move[DPT_MAX_DEPTH];
00039 double val;
00040 unsigned int depth;
00041 }
00042 DPTFullMove_t;
00043
00044
00046 typedef struct
00047 {
00048 unsigned int n_H[2];
00049 unsigned int n_dominos:DPT_MAX_DOM_LOG;
00050 unsigned int n_nodes:DPT_MAX_NODE_LOG;
00051 unsigned int n_A[DPT_MAX_DOM];
00052 unsigned int n_B[DPT_MAX_DOM];
00053 unsigned int n_Tc[DPT_MAX_DOM];
00054 }
00055 DPTGdata_t;
00056
00057
00059 typedef struct
00060 {
00061 unsigned int n_AtoB:DPT_MAX_DOM_LOG;
00063 unsigned int n_dT:DPT_MAX_DOM_LOG;
00065 unsigned int in_F:1;
00066 }
00067 DPTEdata_t;
00068
00069
00071 struct DPTNdata_t
00072 {
00073
00074
00075
00076 EGbbtreeNode_t *tree_cn;
00078
00079
00080
00081 EGbitset_t Ia[DPT_MAX_DOM >> __EGBIT_SHIFT__];
00084 EGbitset_t Ib[DPT_MAX_DOM >> __EGBIT_SHIFT__];
00087 EGbitset_t added[DPT_MAX_DOM >> __EGBIT_SHIFT__];
00090 EGbitset_t flipA[DPT_MAX_DOM >> __EGBIT_SHIFT__];
00093 EGbitset_t flipB[DPT_MAX_DOM >> __EGBIT_SHIFT__];
00096 unsigned int n_in_A:DPT_MAX_DOM_LOG;
00098 unsigned int n_in_T:DPT_MAX_DOM_LOG;
00100 unsigned int in_H:1;
00101 unsigned int added_H:1;
00102
00103
00104
00105 DPTFullMove_t full_move;
00106 };
00107 typedef struct DPTNdata_t DPTNdata_t;
00108
00109
00110
00111
00112 static DPTNdata_t *nodeData = 0;
00113 static DPTEdata_t *edgeData = 0;
00114 static DPTGdata_t graphData;
00115 static EGuGraph_t *G = 0;
00116 static EGuGraphNode_t **all_nodes;
00117 static EGuGraphEdge_t **all_edges;
00118 static double const *weight;
00119 static EGbbtree_t *tree;
00120 static EGbitset_t node_update[DPT_MAX_NODE >> __EGBIT_SHIFT__];
00121
00122
00123
00124
00125
00126
00127 #define DPTMinImprovement (-1e-6)
00128
00129
00130 enum move
00131 {
00132 DPT_Tc_A,
00133 DPT_Tc_B,
00134 DPT_Hc_H,
00135 DPT_A_B,
00136 DPT_B_A,
00137 DPT_B_A_flipH,
00138 DPT_A_B_flipH,
00139 DPT_A_Tc,
00140 DPT_B_Tc,
00141 DPT_H_Hc,
00142 DPT_no_move
00143 };
00144
00145
00146 static const char move_name[11][20] = {[DPT_no_move] = "DPT_no_move",
00147 [DPT_A_Tc] = "DPT_A_Tc",
00148 [DPT_B_Tc] = "DPT_B_Tc",
00149 [DPT_A_B] = "DPT_A_B",
00150 [DPT_H_Hc] = "DPT_H_Hc",
00151 [DPT_Tc_A] = "DPT_Tc_A",
00152 [DPT_Tc_B] = "DPT_Tc_B",
00153 [DPT_B_A] = "DPT_B_A",
00154 [DPT_Hc_H] = "DPT_Hc_H",
00155 [DPT_A_B_flipH] = "DPT_A_B_flipH",
00156 [DPT_B_A_flipH] = "DPT_B_A_flipH"
00157 };
00158
00159 static unsigned char DPT_inv_move[11] = {[DPT_no_move] = DPT_no_move,
00160 [DPT_A_Tc] = DPT_Tc_A,
00161 [DPT_B_Tc] = DPT_Tc_B,
00162 [DPT_A_B] = DPT_B_A,
00163 [DPT_H_Hc] = DPT_Hc_H,
00164 [DPT_Tc_A] = DPT_A_Tc,
00165 [DPT_Tc_B] = DPT_B_Tc,
00166 [DPT_B_A] = DPT_A_B,
00167 [DPT_Hc_H] = DPT_H_Hc,
00168 [DPT_A_B_flipH] = DPT_B_A_flipH,
00169 [DPT_B_A_flipH] = DPT_A_B_flipH
00170 };
00171
00172
00173
00174 #define DPTgetEdge(__e_it) ((EGuGraphEdge_t*)(__e_it->this))
00175 #define DPTgetOtherEndId(__n_id,__e_it) (__n_id == DPTgetEdge(__e_it)->head->id ? DPTgetEdge(__e_it)->tail->id : DPTgetEdge(__e_it)->head->id)
00176 #define DPTgetEdgeId(__e_it) (DPTgetEdge(__e_it)->id)
00177 #define DPTNdata(__this) ((DPTNdata_t*)(__this))
00178
00179
00180
00181
00182
00183 #if DPT_VRB <= DEBUG || DPT_DBG < DEBUG || DPT_EDBG < DEBUG
00184
00185
00186
00187 static inline void DPdisplaySingleMove (const DPTMove_t * const move)
00188 {
00189
00190 EGlistNode_t *e_it;
00191 unsigned no_id,
00192 e_id,
00193 dom = move->dom;
00194
00195 fprintf (stderr, "\tNode %u:%s:%u", move->n_id, move_name[move->move_id],
00196 dom);
00197 switch (move->move_id)
00198 {
00199 case DPT_A_Tc:
00200 case DPT_Tc_A:
00201 fprintf (stderr, ":%u(%u,%u,%u):%s", dom, graphData.n_A[dom],
00202 graphData.n_B[dom], graphData.n_Tc[dom],
00203 EGbitTest (nodeData[move->n_id].Ia, dom) ? "A" :
00204 EGbitTest (nodeData[move->n_id].Ib, dom) ? "B" : "T^c");
00205
00206 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
00207 {
00208 no_id = DPTgetOtherEndId (move->n_id, e_it);
00209 e_id = DPTgetEdgeId (e_it);
00210 fprintf (stderr, "\n\t\te=(%u:%s,%u:%s)[%8.6lf]F[%u]",
00211 move->n_id, EGbitTest (nodeData[move->n_id].Ia, dom) ? "A" :
00212 EGbitTest (nodeData[move->n_id].Ib, dom) ? "B" : "T^c",
00213 no_id, EGbitTest (nodeData[no_id].Ia, dom) ? "A" :
00214 EGbitTest (nodeData[no_id].Ib, dom) ? "B" : "T^c",
00215 weight[e_id], edgeData[e_id].in_F);
00216 }
00217 break;
00218 case DPT_B_Tc:
00219 case DPT_Tc_B:
00220 fprintf (stderr, ":%u(%u,%u,%u):%s", dom, graphData.n_B[dom],
00221 graphData.n_A[dom], graphData.n_Tc[dom],
00222 EGbitTest (nodeData[move->n_id].Ia, dom) ? "A" :
00223 EGbitTest (nodeData[move->n_id].Ib, dom) ? "B" : "T^c");
00224
00225 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
00226 {
00227 no_id = DPTgetOtherEndId (move->n_id, e_it);
00228 e_id = DPTgetEdgeId (e_it);
00229 fprintf (stderr, "\n\t\te=(%u:%s,%u:%s)[%8.6lf]F[%u]",
00230 move->n_id,
00231 EGbitTest (nodeData[move->n_id].Ia, dom) ? "A" :
00232 EGbitTest (nodeData[move->n_id].Ib, dom) ? "B" : "T^c",
00233 no_id, EGbitTest (nodeData[no_id].Ia, dom) ? "A" :
00234 EGbitTest (nodeData[no_id].Ib, dom) ? "B" : "T^c",
00235 weight[e_id], edgeData[e_id].in_F);
00236 }
00237 break;
00238 case DPT_A_B_flipH:
00239 case DPT_B_A_flipH:
00240 case DPT_A_B:
00241 case DPT_B_A:
00242 fprintf (stderr, ":%u(%u,%u,%u):%s", dom, graphData.n_A[dom],
00243 graphData.n_B[dom], graphData.n_Tc[dom],
00244 EGbitTest (nodeData[move->n_id].Ia, dom) ? "A" : "B");
00245
00246 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
00247 {
00248 no_id = DPTgetOtherEndId (move->n_id, e_it);
00249 e_id = DPTgetEdgeId (e_it);
00250 fprintf (stderr, "\n\t\te=(%u:%s,%u:%s)[%8.6lf]F[%u]",
00251 move->n_id, EGbitTest (nodeData[move->n_id].Ia, dom) ? "A" :
00252 EGbitTest (nodeData[move->n_id].Ib, dom) ? "B" : "T^c",
00253 no_id, EGbitTest (nodeData[no_id].Ia, dom) ? "A" :
00254 EGbitTest (nodeData[no_id].Ib, dom) ? "B" : "T^c",
00255 weight[e_id], edgeData[e_id].in_F);
00256 }
00257 break;
00258 case DPT_Hc_H:
00259 case DPT_H_Hc:
00260 fprintf (stderr, "(%u,%u):%s", graphData.n_H[1], graphData.n_H[0],
00261 (nodeData[move->n_id].in_H & 1U) ? "H" : "H^c");
00262
00263 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
00264 {
00265 no_id = DPTgetOtherEndId (move->n_id, e_it);
00266 e_id = DPTgetEdgeId (e_it);
00267 fprintf (stderr, "\n\t\te=(%u,%u)[%8.6lf]F[%u]",
00268 move->n_id, no_id, weight[e_id], edgeData[e_id].in_F);
00269 }
00270 break;
00271 }
00272 fprintf (stderr, "\n");
00273 }
00274
00275
00276
00277
00278 static inline int DPdisplayMove (unsigned int const nc_id)
00279 {
00280 unsigned depth = nodeData[nc_id].full_move.depth;
00281 fprintf (stderr, "Move Stored for node %u:%u\n", nc_id,
00282 nodeData[nc_id].full_move.depth);
00283 while (depth--)
00284 DPdisplaySingleMove (nodeData[nc_id].full_move.move + depth);
00285 fprintf (stderr, "\tValue %lf\n", nodeData[nc_id].full_move.val);
00286 fprintf (stderr, "\t");
00287 __EG_PRINTLOC2__;
00288 return 1;
00289 }
00290 #endif
00291
00292
00293
00294
00295 static inline void DPTpriceConstraint (double *l_violation)
00296 {
00297 register unsigned int i;
00298
00299 for (i = G->nedges; i--;)
00300 {
00301 (*l_violation) += (edgeData[i].in_F + edgeData[i].n_AtoB +
00302 edgeData[i].n_dT) * weight[i];
00303 }
00304 return;
00305 }
00306
00307 #if (DPT_VRB <= DEBUG-1) || (DPT_EDBG <= DEBUG)
00308
00310
00311 static inline int DPTDisplayEdges (void)
00312 {
00313 register unsigned int i;
00314 register unsigned j;
00315 unsigned h_id,
00316 t_id;
00317
00318 for (i = G->nedges; i--;)
00319 {
00320 h_id = all_edges[i]->head->id;
00321 t_id = all_edges[i]->tail->id;
00322 if (weight[i] > 1e-3)
00323 {
00324 fprintf (stderr, "e(%u)[%u,%u][%8.6lf] bellongs to: ", i,
00325 h_id, t_id, weight[i]);
00326 for (j = graphData.n_dominos; j--;)
00327 {
00328 if (EGbitTest (nodeData[h_id].Ia, j) !=
00329 EGbitTest (nodeData[t_id].Ia, j))
00330 fprintf (stderr, "delta(A_%u) ", j);
00331 if (EGbitTest (nodeData[h_id].Ib, j) !=
00332 EGbitTest (nodeData[t_id].Ib, j))
00333 fprintf (stderr, "delta(B_%u) ", j);
00334 }
00335 if (nodeData[h_id].in_H != nodeData[t_id].in_H)
00336 fprintf (stderr, "delta(H) ");
00337 if (edgeData[i].in_F)
00338 fprintf (stderr, "F ");
00339 fprintf (stderr, "\n");
00340 }
00341 }
00342 return 1;
00343 }
00344 #endif
00345
00346
00348
00349 static int EGdpTightNdataCompare (const void *N1,
00350 const void *N2)
00351 {
00352
00353
00354 if ((fabs (((const DPTNdata_t *) N1)->full_move.val) <
00355 fabs (DPTMinImprovement))
00356 && (fabs (((const DPTNdata_t *) N2)->full_move.val) <
00357 fabs (DPTMinImprovement)))
00358 {
00359
00360 if (((const DPTNdata_t *) N1)->full_move.move[0].move_id <
00361 ((const DPTNdata_t *) N2)->full_move.move[0].move_id)
00362 return -1;
00363 if (((const DPTNdata_t *) N1)->full_move.move[0].move_id >
00364 ((const DPTNdata_t *) N2)->full_move.move[0].move_id)
00365 return 1;
00366
00367 if (((const DPTNdata_t *) N1)->full_move.depth <
00368 ((const DPTNdata_t *) N2)->full_move.depth)
00369 return -1;
00370 if (((const DPTNdata_t *) N1)->full_move.depth >
00371 ((const DPTNdata_t *) N2)->full_move.depth)
00372 return 1;
00373 if( N1 < N2) return -1;
00374 if( N1 > N2) return 1;
00375 return 0;
00376 }
00377
00378 if (((const DPTNdata_t *) N1)->full_move.val <
00379 ((const DPTNdata_t *) N2)->full_move.val)
00380 return -1;
00381 if (((const DPTNdata_t *) N1)->full_move.val >
00382 ((const DPTNdata_t *) N2)->full_move.val)
00383 return 1;
00384 if( N1 < N2) return -1;
00385 if( N1 > N2) return 1;
00386 return 0;
00387 }
00388
00389
00391
00392 #if DPT_EDBG < DEBUG
00393 #define DPTupdateMove(__cmove,__bmove) __DPTupdateMove(__cmove,__bmove,__FILE__,__LINE__,__func__)
00394 #else
00395 #define DPTupdateMove(__cmove,__bmove) __DPTupdateMove(__cmove,__bmove)
00396 #endif
00397 static inline int __DPTupdateMove (const DPTFullMove_t * const cur_move,
00398 DPTFullMove_t * const best_move
00399 #if DPT_EDBG < DEBUG
00400 ,
00401 const char *file,
00402 const int line,
00403 const char *function
00404 #endif
00405 )
00406 {
00407 if ((cur_move->val + fabs (DPTMinImprovement) < best_move->val) ||
00408 (cur_move->move[0].move_id < best_move->move[0].move_id &&
00409 (fabs (cur_move->val - best_move->val) < fabs (DPTMinImprovement))))
00410 {
00411 #if DPT_VRB+1900<DEBUG
00412 fprintf (stderr, "Storing Move for node %u\n", cur_move->move[0].n_id);
00413 {
00414 unsigned l_depth = cur_move->depth + 1;
00415 while (l_depth--)
00416 DPdisplaySingleMove (cur_move->move + l_depth);
00417 fprintf (stderr, "\tValue %lf\n", cur_move->val);
00418 }
00419 #endif
00420 #if DPT_EDBG < DEBUG
00421 {
00422 unsigned int l_depth = cur_move->depth;
00423 while (l_depth--)
00424 EXIT (cur_move->move[l_depth].move_id == DPT_no_move,
00425 "Storing DPT_no_move for depth %u, called from %s at %s:%d",
00426 l_depth, function, file, line);
00427 }
00428 #endif
00429 memcpy (best_move, cur_move, sizeof (DPTFullMove_t));
00430 }
00431 return 0;
00432 }
00433
00434
00436
00437 static inline int DPTpriceTcA (const DPTMove_t * const cur_move,
00438 double *const move_val)
00439 {
00440
00441 EGlistNode_t *e_it = all_nodes[cur_move->n_id]->edges->begin;
00442 unsigned e_id,
00443 no_id,
00444 pos;
00445
00446
00447 for (; e_it; e_it = e_it->next)
00448 {
00449 e_id = DPTgetEdgeId (e_it);
00450 no_id = DPTgetOtherEndId (cur_move->n_id, e_it);
00451 pos = (EGbitTest (nodeData[no_id].Ia, cur_move->dom) ? 2U : 0U) |
00452 (EGbitTest (nodeData[no_id].Ib, cur_move->dom) ? 1U : 0U);
00453 switch (pos)
00454 {
00455 case 0U:
00456
00457
00458 (*move_val) += weight[e_id];
00459 break;
00460
00461
00462 case 1U:
00463 if (edgeData[e_id].in_F)
00464 (*move_val) -= weight[e_id];
00465 else
00466 (*move_val) += weight[e_id];
00467 break;
00468
00469 case 2U:
00470 (*move_val) -= weight[e_id];
00471 break;
00472 default:
00473 EXIT (1, "This should not happen");
00474 }
00475 }
00476 return 0;
00477 }
00478
00479
00481
00482 static inline int DPTpriceTcB (const DPTMove_t * const cur_move,
00483 double *const move_val)
00484 {
00485
00486 EGlistNode_t *e_it = all_nodes[cur_move->n_id]->edges->begin;
00487 unsigned e_id,
00488 no_id,
00489 pos;
00490
00491
00492 for (; e_it; e_it = e_it->next)
00493 {
00494 e_id = DPTgetEdgeId (e_it);
00495 no_id = DPTgetOtherEndId (cur_move->n_id, e_it);
00496 pos = (EGbitTest (nodeData[no_id].Ia, cur_move->dom) ? 2U : 0U) |
00497 (EGbitTest (nodeData[no_id].Ib, cur_move->dom) ? 1U : 0U);
00498 switch (pos)
00499 {
00500 case 0U:
00501
00502
00503 (*move_val) += weight[e_id];
00504 break;
00505
00506
00507 case 2U:
00508 if (edgeData[e_id].in_F)
00509 (*move_val) -= weight[e_id];
00510 else
00511 (*move_val) += weight[e_id];
00512 break;
00513
00514 case 1U:
00515 (*move_val) -= weight[e_id];
00516 break;
00517 default:
00518 EXIT (1, "This should not happen");
00519 }
00520 }
00521 return 0;
00522 }
00523
00524
00526
00527 static inline int DPTpriceAB (const DPTMove_t * const cur_move,
00528 double *const move_val)
00529 {
00530
00531 EGlistNode_t *e_it = all_nodes[cur_move->n_id]->edges->begin;
00532 unsigned e_id,
00533 no_id,
00534 pos;
00535
00536
00537 for (; e_it; e_it = e_it->next)
00538 {
00539 e_id = DPTgetEdgeId (e_it);
00540 no_id = DPTgetOtherEndId (cur_move->n_id, e_it);
00541 pos = (EGbitTest (nodeData[no_id].Ia, cur_move->dom) ? 2U : 0U) |
00542 (EGbitTest (nodeData[no_id].Ib, cur_move->dom) ? 1U : 0U);
00543 switch (pos)
00544 {
00545 case 0U:
00546
00547 break;
00548
00549 case 1U:
00550 if (edgeData[e_id].in_F)
00551 (*move_val) -= 2 * weight[e_id];
00552 break;
00553
00554 case 2U:
00555 if (!edgeData[e_id].in_F)
00556 (*move_val) += 2 * weight[e_id];
00557 break;
00558 default:
00559 EXIT (1, "This should not happen");
00560 }
00561 }
00562 return 0;
00563 }
00564
00565
00568
00569 static inline int DPTpriceABflipH (DPTMove_t const *const cur_move,
00570 double *const move_val)
00571 {
00572
00573 EGlistNode_t *e_it;
00574 unsigned e_id,
00575 no_id,
00576 pos;
00577
00578
00579 for (e_it = all_nodes[cur_move->n_id]->edges->begin; e_it; e_it = e_it->next)
00580 {
00581 e_id = DPTgetEdgeId (e_it);
00582 no_id = DPTgetOtherEndId (cur_move->n_id, e_it);
00583 pos = (EGbitTest (nodeData[no_id].Ia, cur_move->dom) ? 2U : 0U) |
00584 (EGbitTest (nodeData[no_id].Ib, cur_move->dom) ? 1U : 0U);
00585 switch (pos)
00586 {
00587 case 0U:
00588
00589 if (edgeData[e_id].in_F)
00590 (*move_val) -= weight[e_id];
00591 else
00592 (*move_val) += weight[e_id];
00593 break;
00594
00595 case 1U:
00596 (*move_val) -= weight[e_id];
00597 break;
00598
00599 case 2U:
00600 (*move_val) += weight[e_id];
00601 break;
00602 default:
00603 EXIT (1, "This should not happen");
00604 }
00605 }
00606 return 0;
00607 }
00608
00609
00611
00612 static inline int DPTpriceBA (DPTMove_t const *const cur_move,
00613 double *const move_val)
00614 {
00615
00616 EGlistNode_t *e_it;
00617 unsigned e_id,
00618 no_id,
00619 pos;
00620
00621
00622 for (e_it = all_nodes[cur_move->n_id]->edges->begin; e_it; e_it = e_it->next)
00623 {
00624 e_id = DPTgetEdgeId (e_it);
00625 no_id = DPTgetOtherEndId (cur_move->n_id, e_it);
00626 pos = (EGbitTest (nodeData[no_id].Ia, cur_move->dom) ? 2U : 0U) |
00627 (EGbitTest (nodeData[no_id].Ib, cur_move->dom) ? 1U : 0U);
00628 switch (pos)
00629 {
00630 case 0U:
00631
00632 break;
00633
00634 case 2U:
00635 if (edgeData[e_id].in_F)
00636 (*move_val) -= 2 * weight[e_id];
00637 break;
00638
00639 case 1U:
00640 if (!edgeData[e_id].in_F)
00641 (*move_val) += 2 * weight[e_id];
00642 break;
00643 default:
00644 EXIT (1, "This should not happen");
00645 }
00646 }
00647 return 0;
00648 }
00649
00650
00653
00654 static inline int DPTpriceBAflipH (DPTMove_t const *const cur_move,
00655 double *const move_val)
00656 {
00657
00658 EGlistNode_t *e_it;
00659 unsigned e_id,
00660 no_id,
00661 pos;
00662
00663
00664 for (e_it = all_nodes[cur_move->n_id]->edges->begin; e_it; e_it = e_it->next)
00665 {
00666 e_id = DPTgetEdgeId (e_it);
00667 no_id = DPTgetOtherEndId (cur_move->n_id, e_it);
00668 pos = (EGbitTest (nodeData[no_id].Ia, cur_move->dom) ? 2U : 0U) |
00669 (EGbitTest (nodeData[no_id].Ib, cur_move->dom) ? 1U : 0U);
00670 switch (pos)
00671 {
00672 case 0U:
00673
00674 if (edgeData[e_id].in_F)
00675 (*move_val) -= weight[e_id];
00676 else
00677 (*move_val) += weight[e_id];
00678 break;
00679
00680 case 2U:
00681 (*move_val) -= weight[e_id];
00682 break;
00683
00684 case 1U:
00685 (*move_val) += weight[e_id];
00686 break;
00687 default:
00688 EXIT (1, "This should not happen");
00689 }
00690 }
00691 return 0;
00692 }
00693
00694
00696
00697 static inline int DPTpriceHHc (DPTMove_t const *const cur_move,
00698 double *const move_val)
00699 {
00700
00701 EGlistNode_t *e_it;
00702 unsigned e_id;
00703
00704
00705 for (e_it = all_nodes[cur_move->n_id]->edges->begin; e_it; e_it = e_it->next)
00706 {
00707 e_id = DPTgetEdgeId (e_it);
00708 if (edgeData[e_id].in_F)
00709 (*move_val) -= weight[e_id];
00710 else
00711 (*move_val) += weight[e_id];
00712 }
00713 return 0;
00714 }
00715
00716
00718
00719 #define DPTpriceHcH(__id,__val) DPTpriceHHc(__id,__val)
00720
00721
00723
00724 static inline int DPTpriceBTc (DPTMove_t const *const cur_move,
00725 double *const move_val)
00726 {
00727
00728 EGlistNode_t *e_it;
00729 unsigned e_id,
00730 no_id,
00731 pos;
00732
00733
00734 for (e_it = all_nodes[cur_move->n_id]->edges->begin; e_it; e_it = e_it->next)
00735 {
00736 e_id = DPTgetEdgeId (e_it);
00737 no_id = DPTgetOtherEndId (cur_move->n_id, e_it);
00738 pos = (EGbitTest (nodeData[no_id].Ia, cur_move->dom) ? 2U : 0U) |
00739 (EGbitTest (nodeData[no_id].Ib, cur_move->dom) ? 1U : 0U);
00740 switch (pos)
00741 {
00742
00743 case 0U:
00744 (*move_val) -= weight[e_id];
00745 break;
00746
00747 case 2U:
00748 if (edgeData[e_id].in_F)
00749 (*move_val) -= weight[e_id];
00750 else
00751 (*move_val) += weight[e_id];
00752 break;
00753
00754 case 1U:
00755 (*move_val) += weight[e_id];
00756 break;
00757 default:
00758 EXIT (1, "This should not happen");
00759 }
00760 }
00761 return 0;
00762 }
00763
00764
00766
00767 static inline int DPTpriceATc (DPTMove_t const *const cur_move,
00768 double *const move_val)
00769 {
00770
00771 EGlistNode_t *e_it;
00772 unsigned e_id,
00773 no_id,
00774 pos;
00775
00776
00777 for (e_it = all_nodes[cur_move->n_id]->edges->begin; e_it; e_it = e_it->next)
00778 {
00779 e_id = DPTgetEdgeId (e_it);
00780 no_id = DPTgetOtherEndId (cur_move->n_id, e_it);
00781 pos = (EGbitTest (nodeData[no_id].Ia, cur_move->dom) ? 2U : 0U) |
00782 (EGbitTest (nodeData[no_id].Ib, cur_move->dom) ? 1U : 0U);
00783 switch (pos)
00784 {
00785
00786 case 0U:
00787 (*move_val) -= weight[e_id];
00788 break;
00789
00790 case 1U:
00791 if (edgeData[e_id].in_F)
00792 (*move_val) -= weight[e_id];
00793 else
00794 (*move_val) += weight[e_id];
00795 break;
00796
00797 case 2U:
00798 (*move_val) += weight[e_id];
00799 break;
00800 default:
00801 EXIT (1, "This should not happen");
00802 }
00803 }
00804 return 0;
00805 }
00806
00807
00809
00810 static inline int DPTmakeMoveTcA (DPTMove_t const *const move,
00811 const unsigned int update_flags)
00812 {
00813
00814 EGlistNode_t *e_it;
00815 unsigned e_id,
00816 no_id,
00817 pos;
00818
00819
00820 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
00821 {
00822 e_id = DPTgetEdgeId (e_it);
00823 no_id = DPTgetOtherEndId (move->n_id, e_it);
00824 pos = (EGbitTest (nodeData[no_id].Ia, move->dom) ? 2U : 0U) |
00825 (EGbitTest (nodeData[no_id].Ib, move->dom) ? 1U : 0U);
00826 switch (pos)
00827 {
00828 case 0U:
00829
00830
00831 edgeData[e_id].n_dT++;
00832 break;
00833
00834
00835 case 1U:
00836 edgeData[e_id].n_dT--;
00837 edgeData[e_id].n_AtoB++;
00838 edgeData[e_id].in_F++;
00839 break;
00840
00841 case 2U:
00842 edgeData[e_id].n_dT--;
00843 break;
00844 default:
00845 EXIT (1, "This should not happen");
00846 }
00847 }
00848
00849
00850 graphData.n_Tc[move->dom]--;
00851 graphData.n_A[move->dom]++;
00852 EGbitSet (nodeData[move->n_id].Ia, move->dom);
00853 nodeData[move->n_id].n_in_A++;
00854 nodeData[move->n_id].n_in_T++;
00855 if (update_flags)
00856 EGbitSet (nodeData[move->n_id].added, move->dom);
00857
00858 return 0;
00859 }
00860
00861
00863
00864 static inline int DPTmakeMoveTcB (DPTMove_t const *const move,
00865 const unsigned int update_flags)
00866 {
00867
00868 EGlistNode_t *e_it;
00869 unsigned e_id,
00870 no_id,
00871 pos;
00872
00873
00874 graphData.n_Tc[move->dom]--;
00875 graphData.n_B[move->dom]++;
00876 EGbitSet (nodeData[move->n_id].Ib, move->dom);
00877 nodeData[move->n_id].n_in_T++;
00878 if (update_flags)
00879 EGbitSet (nodeData[move->n_id].added, move->dom);
00880
00881
00882 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
00883 {
00884 e_id = DPTgetEdgeId (e_it);
00885 no_id = DPTgetOtherEndId (move->n_id, e_it);
00886 pos = (EGbitTest (nodeData[no_id].Ia, move->dom) ? 2U : 0U) |
00887 (EGbitTest (nodeData[no_id].Ib, move->dom) ? 1U : 0U);
00888 switch (pos)
00889 {
00890 case 0U:
00891
00892
00893 edgeData[e_id].n_dT++;
00894 break;
00895
00896
00897 case 2U:
00898 edgeData[e_id].n_dT--;
00899 edgeData[e_id].n_AtoB++;
00900 edgeData[e_id].in_F++;
00901 break;
00902
00903 case 1U:
00904 edgeData[e_id].n_dT--;
00905 break;
00906 default:
00907 EXIT (1, "This should not happen");
00908 }
00909 }
00910 return 0;
00911 }
00912
00913
00915
00916 static inline int DPTmakeMoveAB (DPTMove_t const *const move,
00917 const unsigned int update_flags)
00918 {
00919
00920 EGlistNode_t *e_it;
00921 unsigned e_id,
00922 no_id,
00923 pos;
00924
00925
00926 graphData.n_A[move->dom]--;
00927 graphData.n_B[move->dom]++;
00928 EGbitUnset (nodeData[move->n_id].Ia, move->dom);
00929 EGbitSet (nodeData[move->n_id].Ib, move->dom);
00930 nodeData[move->n_id].n_in_A--;
00931 if (update_flags)
00932 EGbitSet (nodeData[move->n_id].flipA, move->dom);
00933
00934
00935 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
00936 {
00937 e_id = DPTgetEdgeId (e_it);
00938 no_id = DPTgetOtherEndId (move->n_id, e_it);
00939 pos = (EGbitTest (nodeData[no_id].Ia, move->dom) ? 2U : 0U) |
00940 (EGbitTest (nodeData[no_id].Ib, move->dom) ? 1U : 0U);
00941 switch (pos)
00942 {
00943 case 0U:
00944
00945 break;
00946
00947 case 1U:
00948 edgeData[e_id].in_F++;
00949 edgeData[e_id].n_AtoB--;
00950 break;
00951
00952 case 2U:
00953 edgeData[e_id].in_F++;
00954 edgeData[e_id].n_AtoB++;
00955 break;
00956 default:
00957 EXIT (1, "This should not happen");
00958 }
00959 }
00960 return 0;
00961 }
00962
00963
00965
00966 static inline int DPTmakeMoveBA (DPTMove_t const *const move,
00967 const unsigned int update_flags)
00968 {
00969
00970 EGlistNode_t *e_it;
00971 unsigned e_id,
00972 no_id,
00973 pos;
00974
00975
00976 graphData.n_B[move->dom]--;
00977 graphData.n_A[move->dom]++;
00978 EGbitUnset (nodeData[move->n_id].Ib, move->dom);
00979 EGbitSet (nodeData[move->n_id].Ia, move->dom);
00980 nodeData[move->n_id].n_in_A++;
00981 if (update_flags)
00982 EGbitSet (nodeData[move->n_id].flipB, move->dom);
00983
00984
00985 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
00986 {
00987 e_id = DPTgetEdgeId (e_it);
00988 no_id = DPTgetOtherEndId (move->n_id, e_it);
00989 pos = (EGbitTest (nodeData[no_id].Ia, move->dom) ? 2U : 0U) |
00990 (EGbitTest (nodeData[no_id].Ib, move->dom) ? 1U : 0U);
00991 switch (pos)
00992 {
00993 case 0U:
00994
00995 break;
00996
00997 case 2U:
00998 edgeData[e_id].in_F++;
00999 edgeData[e_id].n_AtoB--;
01000 break;
01001
01002 case 1U:
01003 edgeData[e_id].in_F++;
01004 edgeData[e_id].n_AtoB++;
01005 break;
01006 default:
01007 EXIT (1, "This should not happen");
01008 }
01009 }
01010 return 0;
01011 }
01012
01013
01015
01016 static inline int DPTmakeMoveBAflipH (DPTMove_t const *const move,
01017 const unsigned int update_flags)
01018 {
01019
01020 EGlistNode_t *e_it;
01021 unsigned e_id,
01022 no_id,
01023 pos;
01024
01025
01026 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
01027 {
01028 e_id = DPTgetEdgeId (e_it);
01029 no_id = DPTgetOtherEndId (move->n_id, e_it);
01030 pos = (EGbitTest (nodeData[no_id].Ia, move->dom) ? 2U : 0U) |
01031 (EGbitTest (nodeData[no_id].Ib, move->dom) ? 1U : 0U);
01032 switch (pos)
01033 {
01034 case 0U:
01035
01036 edgeData[e_id].in_F++;
01037 break;
01038
01039 case 2U:
01040 edgeData[e_id].n_AtoB--;
01041 break;
01042
01043 case 1U:
01044 edgeData[e_id].n_AtoB++;
01045 break;
01046 default:
01047 EXIT (1, "This should not happen");
01048 }
01049 }
01050
01051
01052 if (update_flags)
01053 {
01054 EGbitSet (nodeData[move->n_id].flipB, move->dom);
01055 }
01056
01057 graphData.n_H[nodeData[move->n_id].in_H]--;
01058 nodeData[move->n_id].in_H++;
01059 graphData.n_H[nodeData[move->n_id].in_H]++;
01060
01061 graphData.n_B[move->dom]--;
01062 graphData.n_A[move->dom]++;
01063 EGbitUnset (nodeData[move->n_id].Ib, move->dom);
01064 EGbitSet (nodeData[move->n_id].Ia, move->dom);
01065 nodeData[move->n_id].n_in_A++;
01066
01067 return 0;
01068 }
01069
01070
01072
01073 static inline int DPTmakeMoveABflipH (DPTMove_t const *const move,
01074 const unsigned int update_flags)
01075 {
01076
01077 EGlistNode_t *e_it;
01078 unsigned e_id,
01079 no_id,
01080 pos;
01081
01082
01083 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
01084 {
01085 e_id = DPTgetEdgeId (e_it);
01086 no_id = DPTgetOtherEndId (move->n_id, e_it);
01087 pos = (EGbitTest (nodeData[no_id].Ia, move->dom) ? 2U : 0U) |
01088 (EGbitTest (nodeData[no_id].Ib, move->dom) ? 1U : 0U);
01089 switch (pos)
01090 {
01091 case 0U:
01092
01093 edgeData[e_id].in_F++;
01094 break;
01095
01096 case 1U:
01097 edgeData[e_id].n_AtoB--;
01098 break;
01099
01100 case 2U:
01101 edgeData[e_id].n_AtoB++;
01102 break;
01103 default:
01104 EXIT (1, "This should not happen");
01105 }
01106 }
01107
01108 if (update_flags)
01109 {
01110 EGbitSet (nodeData[move->n_id].flipA, move->dom);
01111 }
01112
01113 graphData.n_H[nodeData[move->n_id].in_H]--;
01114 nodeData[move->n_id].in_H++;
01115 graphData.n_H[nodeData[move->n_id].in_H]++;
01116
01117 graphData.n_A[move->dom]--;
01118 graphData.n_B[move->dom]++;
01119 EGbitUnset (nodeData[move->n_id].Ia, move->dom);
01120 EGbitSet (nodeData[move->n_id].Ib, move->dom);
01121 nodeData[move->n_id].n_in_A--;
01122
01123 return 0;
01124 }
01125
01126
01128
01129 static inline int DPTmakeMoveHHc (DPTMove_t const *const move,
01130 const unsigned int update_flags)
01131 {
01132
01133 EGlistNode_t *e_it;
01134
01135
01136 if (update_flags)
01137 if (nodeData[move->n_id].in_H)
01138 nodeData[move->n_id].added_H = 1U;
01139
01140 graphData.n_H[nodeData[move->n_id].in_H]--;
01141 nodeData[move->n_id].in_H++;
01142 graphData.n_H[nodeData[move->n_id].in_H]++;
01143
01144
01145 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
01146 edgeData[DPTgetEdgeId (e_it)].in_F++;
01147 return 0;
01148 }
01149
01150
01152
01153 #define DPTmakeMoveHcH(__move,__flags) DPTmakeMoveHHc(__move,__flags)
01154
01155
01157
01158 static inline int DPTmakeMoveBTc (DPTMove_t const *const move)
01159 {
01160
01161 EGlistNode_t *e_it;
01162 unsigned e_id,
01163 no_id,
01164 pos;
01165
01166
01167 graphData.n_B[move->dom]--;
01168 graphData.n_Tc[move->dom]++;
01169 EGbitUnset (nodeData[move->n_id].Ib, move->dom);
01170 nodeData[move->n_id].n_in_T--;
01171
01172
01173 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
01174 {
01175 e_id = DPTgetEdgeId (e_it);
01176 no_id = DPTgetOtherEndId (move->n_id, e_it);
01177 pos = (EGbitTest (nodeData[no_id].Ia, move->dom) ? 2U : 0U) |
01178 (EGbitTest (nodeData[no_id].Ib, move->dom) ? 1U : 0U);
01179 switch (pos)
01180 {
01181
01182 case 0U:
01183 edgeData[e_id].n_dT--;
01184 break;
01185
01186 case 2U:
01187 edgeData[e_id].in_F++;
01188 edgeData[e_id].n_AtoB--;
01189 edgeData[e_id].n_dT++;
01190 break;
01191
01192 case 1U:
01193 edgeData[e_id].n_dT++;
01194 break;
01195 default:
01196 EXIT (1, "This should not happen");
01197 }
01198 }
01199 return 0;
01200 }
01201
01202
01205
01206 static inline int DPTTestEdges (void)
01207 {
01208
01209 register unsigned int i = G->nedges,
01210 j;
01211 unsigned int n_AtoB,
01212 n_dT,
01213 N1_id,
01214 N2_id,
01215 N1_inA,
01216 N1_inB,
01217 N1_inTc,
01218 N2_inA,
01219 N2_inB,
01220 N2_inTc,
01221 in_F,
01222 pos;
01223 while (i--)
01224 {
01225 N1_id = all_edges[i]->head->id;
01226 N2_id = all_edges[i]->tail->id;
01227 n_AtoB = n_dT = in_F = 0;
01228 for (j = graphData.n_dominos; j--;)
01229 {
01230 N1_inA = EGbitTest (nodeData[N1_id].Ia, j);
01231 N1_inB = EGbitTest (nodeData[N1_id].Ib, j);
01232 N2_inA = EGbitTest (nodeData[N2_id].Ia, j);
01233 N2_inB = EGbitTest (nodeData[N2_id].Ib, j);
01234 N1_inTc = !(N1_inA || N1_inB);
01235 N2_inTc = !(N2_inA || N2_inB);
01236 if ((!N1_inTc && N2_inTc) || (N1_inTc && !N2_inTc))
01237 n_dT++;
01238 if ((N1_inA && N2_inB) || (N1_inB && N2_inA))
01239 n_AtoB++;
01240 }
01241 pos =
01242 1U & ((nodeData[N1_id].in_H ^ nodeData[N2_id].in_H) ^ edgeData[i].n_AtoB);
01243 if (pos)
01244 in_F = 1U;
01245 TEST (in_F != edgeData[i].in_F || n_dT != edgeData[i].n_dT ||
01246 n_AtoB != edgeData[i].n_AtoB, "in_F(%u,%u) n_dT(%u,%u) n_AtoB(%u,%u)"
01247 " don't match for edge %u", in_F, edgeData[i].in_F, n_dT,
01248 edgeData[i].n_dT, n_AtoB, edgeData[i].n_AtoB, i);
01249 }
01250 return 0;
01251 }
01252
01253
01255
01256 static inline int DPTmakeMoveATc (DPTMove_t const *const move)
01257 {
01258
01259 EGlistNode_t *e_it;
01260 unsigned e_id,
01261 no_id,
01262 pos;
01263
01264
01265 graphData.n_A[move->dom]--;
01266 graphData.n_Tc[move->dom]++;
01267 EGbitUnset (nodeData[move->n_id].Ia, move->dom);
01268 nodeData[move->n_id].n_in_T--;
01269 nodeData[move->n_id].n_in_A--;
01270
01271
01272 for (e_it = all_nodes[move->n_id]->edges->begin; e_it; e_it = e_it->next)
01273 {
01274 e_id = DPTgetEdgeId (e_it);
01275 no_id = DPTgetOtherEndId (move->n_id, e_it);
01276 pos = (EGbitTest (nodeData[no_id].Ia, move->dom) ? 2U : 0U) |
01277 (EGbitTest (nodeData[no_id].Ib, move->dom) ? 1U : 0U);
01278 switch (pos)
01279 {
01280
01281 case 0U:
01282 edgeData[e_id].n_dT--;
01283 break;
01284
01285 case 1U:
01286 edgeData[e_id].in_F++;
01287 edgeData[e_id].n_AtoB--;
01288 edgeData[e_id].n_dT++;
01289 break;
01290
01291 case 2U:
01292 edgeData[e_id].n_dT++;
01293 break;
01294 default:
01295 EXIT (1, "This should not happen");
01296 }
01297 }
01298 return 0;
01299 }
01300
01301
01303
01304 #define DPTmakeMove(__move,__flags) __DPTmakeMove(__move,__flags,__LINE__,__FILE__,__func__)
01305 static int __DPTmakeMove (DPTMove_t const *const move,
01306 const unsigned int update_flags,
01307 const int line,
01308 const char *file,
01309 const char *function)
01310 {
01311
01312 MESSAGE (DPT_VRB + 19, "doing move %s for node %u from %s at %s:%d",
01313 move_name[move->move_id], move->n_id, function, file, line);
01314 switch (move->move_id)
01315 {
01316 case DPT_A_Tc:
01317 DPTmakeMoveATc (move);
01318 break;
01319 case DPT_B_Tc:
01320 DPTmakeMoveBTc (move);
01321 break;
01322 case DPT_H_Hc:
01323 DPTmakeMoveHHc (move, update_flags);
01324 break;
01325 case DPT_Hc_H:
01326 DPTmakeMoveHcH (move, update_flags);
01327 break;
01328 case DPT_A_B:
01329 DPTmakeMoveAB (move, update_flags);
01330 break;
01331 case DPT_B_A:
01332 DPTmakeMoveBA (move, update_flags);
01333 break;
01334 case DPT_A_B_flipH:
01335 DPTmakeMoveABflipH (move, update_flags);
01336 break;
01337 case DPT_B_A_flipH:
01338 DPTmakeMoveBAflipH (move, update_flags);
01339 break;
01340 case DPT_Tc_A:
01341 DPTmakeMoveTcA (move, update_flags);
01342 break;
01343 case DPT_Tc_B:
01344 DPTmakeMoveTcB (move, update_flags);
01345 break;
01346 case DPT_no_move:
01347 break;
01348 default:
01349 EXIT (1, "unknown move %d", move->move_id);
01350 }
01351
01352
01353
01354
01355 return 0;
01356 }
01357
01358
01360
01361 static int DPTmakeInvMove (DPTMove_t const *const move,
01362 const unsigned int update_flags)
01363 {
01364
01365 MESSAGE (DPT_VRB + 19, "doing inv move %s for node %u",
01366 move_name[move->move_id], move->n_id);
01367 switch (DPT_inv_move[move->move_id])
01368 {
01369 case DPT_A_Tc:
01370 DPTmakeMoveATc (move);
01371 break;
01372 case DPT_B_Tc:
01373 DPTmakeMoveBTc (move);
01374 break;
01375 case DPT_H_Hc:
01376 DPTmakeMoveHHc (move, update_flags);
01377 break;
01378 case DPT_Hc_H:
01379 DPTmakeMoveHcH (move, update_flags);
01380 break;
01381 case DPT_A_B:
01382 DPTmakeMoveAB (move, update_flags);
01383 break;
01384 case DPT_B_A:
01385 DPTmakeMoveBA (move, update_flags);
01386 break;
01387 case DPT_A_B_flipH:
01388 DPTmakeMoveABflipH (move, update_flags);
01389 break;
01390 case DPT_B_A_flipH:
01391 DPTmakeMoveBAflipH (move, update_flags);
01392 break;
01393 case DPT_Tc_A:
01394 DPTmakeMoveTcA (move, update_flags);
01395 break;
01396 case DPT_Tc_B:
01397 DPTmakeMoveTcB (move, update_flags);
01398 break;
01399 case DPT_no_move:
01400 break;
01401 default:
01402 EXIT (1, "unknown move %d", move->move_id);
01403 }
01404
01405
01406
01407
01408 return 0;
01409 }
01410
01411
01413
01414 static inline int DPTmakeFullMove (DPTFullMove_t const *const full_move)
01415 {
01416 unsigned int depth = 0;
01417 for (; depth < full_move->depth; depth++)
01418 DPTmakeMove (full_move->move + depth, 1);
01419 return 0;
01420 }
01421
01422
01424
01425 #define DPTgoDeeper(__depth) if(__depth+1<DPT_MAX_DEPTH){\
01426 \
01427 DPTmakeMove(base_move->move+__depth,0);\
01428 for( e_it = all_nodes[nc_id]->edges->begin; e_it ; e_it=e_it->next){\
01429 \
01430 DPTSetBestMove( DPTgetOtherEndId( nc_id, e_it), best_move, \
01431 base_move, __depth + 1);}\
01432 \
01433 DPTmakeInvMove(base_move->move+__depth,0);\
01434 }
01435
01436
01437
01444
01445 static int DPTSetBestMove (const unsigned int nc_id,
01446 DPTFullMove_t * const best_move,
01447 DPTFullMove_t * const base_move,
01448 const unsigned int depth)
01449 {
01450
01451 unsigned nc_inA,
01452 nc_inB,
01453 nc_inTc;
01454 const double move_val = base_move->val;
01455 EGlistNode_t *e_it;
01456 MESSAGE (DPT_VRB + 19, "entering depth %u", depth);
01457
01458 if (depth >= DPT_MAX_DEPTH)
01459 return 0;
01460
01461 base_move->move[depth].n_id = nc_id;
01462 base_move->move[depth].move_id = DPT_no_move;
01463 base_move->depth = depth + 1;
01464
01465 base_move->move[depth].dom = graphData.n_dominos;
01466 for (; base_move->move[depth].dom--;)
01467 {
01468 nc_inA = EGbitTest (nodeData[nc_id].Ia, base_move->move[depth].dom);
01469 nc_inB = EGbitTest (nodeData[nc_id].Ib, base_move->move[depth].dom);
01470 nc_inTc = !(nc_inA || nc_inB);
01471
01472 if (nc_inTc &&
01473 !EGbitTest (nodeData[nc_id].added, base_move->move[depth].dom) &&
01474 (graphData.n_Tc[base_move->move[depth].dom] > 1))
01475 {
01476
01477
01478 base_move->val = move_val;
01479 base_move->move[depth].move_id = DPT_Tc_A;
01480 DPTpriceTcA (base_move->move + depth, &(base_move->val));
01481 DPTupdateMove (base_move, best_move);
01482
01483 DPTgoDeeper (depth);
01484
01485
01486 base_move->val = move_val;
01487 base_move->move[depth].move_id = DPT_Tc_B;
01488 DPTpriceTcB (base_move->move + depth, &(base_move->val));
01489 DPTupdateMove (base_move, best_move);
01490
01491 DPTgoDeeper (depth);
01492
01493 }
01494 }
01495
01496 if (!nodeData[nc_id].in_H && !nodeData[nc_id].added_H
01497 && (graphData.n_H[0] > 1))
01498 {
01499
01500
01501 base_move->val = move_val;
01502 base_move->move[depth].move_id = DPT_Hc_H;
01503 DPTpriceHcH (base_move->move + depth, &(base_move->val));
01504 DPTupdateMove (base_move, best_move);
01505
01506 DPTgoDeeper (depth);
01507
01508 }
01509
01510 base_move->move[depth].dom = graphData.n_dominos;
01511 for (; base_move->move[depth].dom--;)
01512 {
01513 nc_inA = EGbitTest (nodeData[nc_id].Ia, base_move->move[depth].dom);
01514 nc_inB = EGbitTest (nodeData[nc_id].Ib, base_move->move[depth].dom);
01515 nc_inTc = !(nc_inA || nc_inB);
01516
01517
01518 if (nc_inA && (graphData.n_A[base_move->move[depth].dom] > 1) &&
01519 !EGbitTest (nodeData[nc_id].flipA, base_move->move[depth].dom))
01520 {
01521 base_move->val = move_val;
01522 base_move->move[depth].move_id = DPT_A_B;
01523 DPTpriceAB (base_move->move + depth, &(base_move->val));
01524 DPTupdateMove (base_move, best_move);
01525
01526 DPTgoDeeper (depth);
01527
01528
01529 if (graphData.n_H[nodeData[nc_id].in_H] > 1)
01530 {
01531 base_move->val = move_val;
01532 base_move->move[depth].move_id = DPT_A_B_flipH;
01533 DPTpriceABflipH (base_move->move + depth, &(base_move->val));
01534 DPTupdateMove (base_move, best_move);
01535
01536 DPTgoDeeper (depth);
01537 }
01538 }
01539
01540
01541 else if (nc_inB && (graphData.n_B[base_move->move[depth].dom] > 1) &&
01542 !EGbitTest (nodeData[nc_id].flipB, base_move->move[depth].dom))
01543 {
01544 base_move->val = move_val;
01545 base_move->move[depth].move_id = DPT_B_A;
01546 DPTpriceBA (base_move->move + depth, &(base_move->val));
01547 DPTupdateMove (base_move, best_move);
01548
01549 DPTgoDeeper (depth);
01550
01551
01552 if (graphData.n_H[nodeData[nc_id].in_H] > 1)
01553 {
01554 base_move->val = move_val;
01555 base_move->move[depth].move_id = DPT_B_A_flipH;
01556 DPTpriceBAflipH (base_move->move + depth, &(base_move->val));
01557 DPTupdateMove (base_move, best_move);
01558
01559 DPTgoDeeper (depth);
01560 }
01561 }
01562
01563 }
01564
01565 base_move->move[depth].dom = graphData.n_dominos;
01566 for (; base_move->move[depth].dom--;)
01567 {
01568 nc_inA = EGbitTest (nodeData[nc_id].Ia, base_move->move[depth].dom);
01569 nc_inB = EGbitTest (nodeData[nc_id].Ib, base_move->move[depth].dom);
01570 nc_inTc = !(nc_inA || nc_inB);
01571
01572
01573 if (nc_inA && (graphData.n_A[base_move->move[depth].dom] > 1))
01574 {
01575 base_move->val = move_val;
01576 base_move->move[depth].move_id = DPT_A_Tc;
01577 DPTpriceATc (base_move->move + depth, &(base_move->val));
01578 DPTupdateMove (base_move, best_move);
01579
01580 DPTgoDeeper (depth);
01581 }
01582
01583
01584 else if (nc_inB && (graphData.n_B[base_move->move[depth].dom] > 1))
01585 {
01586 base_move->val = move_val;
01587 base_move->move[depth].move_id = DPT_B_Tc;
01588 DPTpriceBTc (base_move->move + depth, &(base_move->val));
01589 DPTupdateMove (base_move, best_move);
01590
01591 DPTgoDeeper (depth);
01592 }
01593
01594 }
01595
01596 if (nodeData[nc_id].in_H && (graphData.n_H[1] > 1))
01597 {
01598
01599
01600 base_move->val = move_val;
01601 base_move->move[depth].move_id = DPT_H_Hc;
01602 DPTpriceHHc (base_move->move + depth, &(base_move->val));
01603 DPTupdateMove (base_move, best_move);
01604
01605 DPTgoDeeper (depth);
01606 }
01607
01608 base_move->val = move_val;
01609 base_move->depth = depth;
01610 MESSAGE (DPT_VRB + 19, "done");
01611 return 0;
01612 }
01613
01614
01617
01618 static inline int DPTisMoveFeasible (DPTMove_t const *const move,
01619 const unsigned int update_flags)
01620 {
01621 int rval = 0;
01622
01623 switch (move->move_id)
01624 {
01625 case DPT_A_Tc:
01626 rval = (EGbitTest (nodeData[move->n_id].Ia, move->dom) &&
01627 graphData.n_A[move->dom] > 1);
01628 break;
01629 case DPT_B_Tc:
01630 rval = (EGbitTest (nodeData[move->n_id].Ib, move->dom) &&
01631 graphData.n_B[move->dom] > 1);
01632 break;
01633 case DPT_H_Hc:
01634 rval = (nodeData[move->n_id].in_H && graphData.n_H[1] > 1);
01635 break;
01636 case DPT_Hc_H:
01637 rval = (!nodeData[move->n_id].in_H && graphData.n_H[0] > 1 &&
01638 (!update_flags || !nodeData[move->n_id].added_H));
01639 break;
01640 case DPT_A_B:
01641 rval = (EGbitTest (nodeData[move->n_id].Ia, move->dom) &&
01642 graphData.n_A[move->dom] > 1 &&
01643 (!update_flags
01644 || !EGbitTest (nodeData[move->n_id].flipA, move->dom)));
01645 break;
01646 case DPT_B_A:
01647 rval = (EGbitTest (nodeData[move->n_id].Ib, move->dom) &&
01648 graphData.n_B[move->dom] > 1 &&
01649 (!update_flags
01650 || !EGbitTest (nodeData[move->n_id].flipB, move->dom)));
01651 break;
01652 case DPT_A_B_flipH:
01653 rval = (EGbitTest (nodeData[move->n_id].Ia, move->dom) &&
01654 graphData.n_A[move->dom] > 1 &&
01655 graphData.n_H[nodeData[move->n_id].in_H] > 1 &&
01656 (!update_flags
01657 || (!EGbitTest (nodeData[move->n_id].flipA, move->dom))));
01658 break;
01659 case DPT_B_A_flipH:
01660 rval = (EGbitTest (nodeData[move->n_id].Ib, move->dom) &&
01661 graphData.n_B[move->dom] > 1 &&
01662 graphData.n_H[nodeData[move->n_id].in_H] > 1 &&
01663 (!update_flags
01664 || (!EGbitTest (nodeData[move->n_id].flipB, move->dom))));
01665 break;
01666 case DPT_Tc_A:
01667 rval = (!EGbitTest (nodeData[move->n_id].Ia, move->dom) &&
01668 !EGbitTest (nodeData[move->n_id].Ib, move->dom) &&
01669 graphData.n_Tc[move->dom] > 1 &&
01670 (!update_flags
01671 || !EGbitTest (nodeData[move->n_id].added, move->dom)));
01672 break;
01673 case DPT_Tc_B:
01674 rval = (!EGbitTest (nodeData[move->n_id].Ia, move->dom) &&
01675 !EGbitTest (nodeData[move->n_id].Ib, move->dom) &&
01676 graphData.n_Tc[move->dom] > 1 &&
01677 (!update_flags
01678 || !EGbitTest (nodeData[move->n_id].added, move->dom)));
01679 break;
01680 case DPT_no_move:
01681 rval = 1;
01682 break;
01683 default:
01684 EXIT (1, "unknown move %d", move->move_id);
01685 }
01686
01687 return rval;
01688 }
01689
01690
01692 static inline int DPTisFullMoveFeasible (DPTFullMove_t const *const full_move)
01693 {
01694 int rval = 1;
01695 unsigned int depth = 0;
01696 MESSAGE (DPT_VRB + 19, "entering");
01697
01698 for (; depth + 1 < full_move->depth &&
01699 (rval = DPTisMoveFeasible (full_move->move + depth, 1)); depth++)
01700 DPTmakeMove (full_move->move + depth, 0);
01701 WARNINGL (DPT_VRB + 19, !rval, "move level %u is infeasible", depth);
01702 if (rval)
01703 rval = DPTisMoveFeasible (full_move->move + depth, 1);
01704 WARNINGL (DPT_VRB + 19, !rval, "move level %u is infeasible", depth);
01705
01706 while (depth--)
01707 {
01708 DPTmakeInvMove (full_move->move + depth, 0);
01709 }
01710 MESSAGE (DPT_VRB + 19, "done, return %d", rval);
01711 return rval;
01712 }
01713
01714
01717
01718 static inline int DPTresetFlags (void)
01719 {
01720
01721 register unsigned int i = G->nodes->size;
01722
01723 while (i--)
01724 {
01725 memset (nodeData[i].added, 0, DPT_MAX_DOM >> 3);
01726 memset (nodeData[i].flipA, 0, DPT_MAX_DOM >> 3);
01727 memset (nodeData[i].flipB, 0, DPT_MAX_DOM >> 3);
01728 nodeData[i].added_H = 0;
01729 }
01730 return 0;
01731 }
01732
01733
01735
01736 static inline int DPTStoreFullMove (const unsigned int nc_id,
01737 DPTFullMove_t const *const full_move)
01738 {
01739 unsigned int l_depth = full_move->depth;
01740 memcpy (&(nodeData[nc_id].full_move), full_move, sizeof (DPTFullMove_t));
01741 while (l_depth--)
01742 {
01743 #if DPT_EDBG < DEBUG
01744 EXIT (full_move->move[l_depth].move_id == DPT_no_move, "Storing "
01745 "DPT_no_move for node %u, depth %u", nc_id, l_depth);
01746 #endif
01747 }
01748 EGbbtreeRemove (tree, nodeData[nc_id].tree_cn);
01749 nodeData[nc_id].tree_cn = EGbbtreeAdd (tree, nodeData + nc_id);
01750 return 0;
01751 }
01752
01753
01755
01756 static inline int DPTResetMove (DPTFullMove_t * move)
01757 {
01758 memset (move, 0, sizeof (DPTFullMove_t));
01759 return 0;
01760 }
01761
01762
01764
01765 static inline int DPTupdateNeighMove (DPTFullMove_t * full_move)
01766 {
01767 unsigned int const max_depth = full_move->depth + DPT_MAX_DEPTH;
01768 unsigned int no_id[2 * DPT_MAX_DEPTH + 1],
01769 n_depth = 0;
01770 EGlistNode_t *e_it[DPT_MAX_DEPTH * 2];
01771 DPTFullMove_t base_move,
01772 cur_move;
01773 memset (&base_move, 0, sizeof (base_move));
01774 memset (&cur_move, 0, sizeof (base_move));
01775 DPTResetMove (&cur_move);
01776 cur_move.val = DBL_MAX;
01777 base_move.val = 0;
01778 no_id[0] = full_move->move[0].n_id;
01779 DPTSetBestMove (no_id[0], &cur_move, &base_move, 0);
01780 DPTStoreFullMove (no_id[0], &cur_move);
01781 EGbitSet (node_update, no_id[0]);
01782 #if DPT_VRB+19<DEBUG
01783 DPdisplayMove (no_id);
01784 #endif
01785 e_it[0] = all_nodes[no_id[0]]->edges->begin;
01786 n_depth = 0;
01787
01788
01789 while (e_it[0])
01790 {
01791 no_id[n_depth + 1] = DPTgetOtherEndId (no_id[n_depth], e_it[n_depth]);
01792 if (!EGbitTest (node_update, no_id[n_depth + 1]))
01793 {
01794 DPTResetMove (&cur_move);
01795 cur_move.val = DBL_MAX;
01796 base_move.val = 0;
01797 DPTSetBestMove (no_id[n_depth + 1], &cur_move, &base_move, 0);
01798 DPTStoreFullMove (no_id[n_depth + 1], &cur_move);
01799 #if DPT_VRB+19<DEBUG
01800 DPdisplayMove (no_id);
01801 #endif
01802 EGbitSet (node_update, no_id[n_depth + 1]);
01803 }
01804
01805
01806 if (n_depth + 1 < max_depth)
01807 {
01808 n_depth++;
01809 e_it[n_depth] = all_nodes[no_id[n_depth]]->edges->begin;
01810 }
01811
01812 else
01813 {
01814 e_it[n_depth] = e_it[n_depth]->next;
01815
01816
01817 while (n_depth && !e_it[n_depth])
01818 {
01819 n_depth--;
01820 e_it[n_depth] = e_it[n_depth]->next;
01821 }
01822 }
01823 }
01824
01825
01826
01827
01828
01829
01830
01831
01832 memset (node_update, 0, sizeof (node_update));
01833 return 0;
01834 }
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847 int DPtighten (
01848 int n_nodes,
01849 int n_edges,
01850 int *edges,
01851 double const *const external_weight,
01852
01853 int n_dominos,
01854 int *n_aset,
01855 int *n_bset,
01856 int n_handle,
01857 int **aset,
01858 int **bset,
01859 int *handle,
01860
01861 int **new_n_aset,
01862 int **new_n_bset,
01863 int *new_n_handle,
01864 int ***new_aset,
01865 int ***new_bset,
01866 int **new_handle,
01867 double *violation)
01868 {
01869
01870
01871 EGmemPool_t *mem;
01872 int rval = 0;
01873 unsigned pos,
01874 max_iter = n_nodes * 5,
01875 in_H = 0,
01876 N1_inA,
01877 N1_inB,
01878 N2_inA,
01879 N2_inB,
01880 N1_id,
01881 N2_id,
01882 N1_inTc,
01883 N2_inTc;
01884 double cost_tmp,
01885 l_violation,
01886 o_violation;
01887 register unsigned int i,
01888 j;
01889 DPTNdata_t *nc_data = 0,
01890 *n_data;
01891 DPTFullMove_t cur_move,
01892 base_move;
01893
01894
01895
01896 MESSAGE (DPT_VRB + 19, "Entering with n_nodes %d n_edges %d n_dominos %d",
01897 n_nodes, n_edges, n_dominos);
01898 EXIT ((unsigned) n_dominos > DPT_MAX_DOM,
01899 "n_dominos (%d) exced max_n_dom (%u)"
01900 "change the value of DPT_MAX_NODE to an apropiate value", n_dominos,
01901 DPT_MAX_DOM);
01902 EXIT ((unsigned) n_nodes > DPT_MAX_NODE,
01903 "n_nodes (%d) exced max_n_nodes (%u)"
01904 "change the value of DPT_MAX_NODE to an apropiate value", n_nodes,
01905 DPT_MAX_NODE);
01906 TEST (!n_nodes, "graph has no nodes");
01907 TEST (!n_edges, "graph has no edges");
01908 TEST (!n_dominos, "inequality has no dominos");
01909 TEST (!n_handle, "inequality has handle");
01910 TEST (!edges, "edges is NULL");
01911 TEST (!external_weight, "weight is NULL");
01912 TEST (!n_aset, "n_aset is NULL");
01913 TEST (!n_bset, "n_bset is NULL");
01914 TEST (!aset, "aset is NULL");
01915 TEST (!bset, "bset is NULL");
01916 TEST (!handle, "handle is NULL");
01917 TEST (!new_n_aset, "new_n_aset is NULL");
01918 TEST (!new_n_bset, "new_n_bset is NULL");
01919 TEST (!new_n_handle, "new_n_handle is NULL");
01920 TEST (!new_aset, "new_aset is NULL");
01921 TEST (!new_bset, "new_bset is NULL");
01922 TEST (!new_handle, "new_handle is NULL");
01923 TEST (!violation, "violation is NULL");
01924 #if LOG_MODE
01925
01926 saveGraph ("graph_tighten.x", n_nodes, n_edges, edges, external_weight);
01927 #endif
01928
01929 ADVTESTL (DPT_DBG, (n_nodes < 2) || (n_edges < 1) || !(n_dominos & 1) ||
01930 (n_handle < 1) || (n_nodes - n_handle < 1),
01931 1, "either n_nodes (%d), n_edges (%d), n_dominos (%d) or n_handle"
01932 " (%d) has wrong value", n_nodes, n_edges, n_dominos, n_handle);
01933 for (i = n_dominos; i--;)
01934 ADVTESTL (DPT_EDBG, (n_aset[i] < 1) || (n_bset[i] < 1) ||
01935 (n_nodes - n_aset[i] - n_bset[i] < 1), 1, "either "
01936 "n_aset[%d] (%d) or n_bset[%d] (%d) or n_Tc[%d] (%d) is < 1",
01937 i, n_aset[i], i, n_bset[i], i, n_nodes - n_aset[i]);
01938
01939
01940
01941 weight = external_weight;
01942 memset (node_update, 0, sizeof (node_update));
01943 mem = EGnewMemPool (512, EGmemPoolNewSize, 4096);
01944 tree = EGnewBbtree (mem, EGdpTightNdataCompare);
01945 nodeData = EGsMalloc (DPTNdata_t, n_nodes);
01946 edgeData = EGsMalloc (DPTEdata_t, n_edges);
01947 all_nodes = EGsMalloc (EGuGraphNode_t *, n_nodes);
01948 all_edges = EGsMalloc (EGuGraphEdge_t *, n_edges);
01949 memset (all_nodes, 0, sizeof (EGuGraphNode_t *) * n_nodes);
01950 memset (nodeData, 0, sizeof (DPTNdata_t) * n_nodes);
01951 memset (edgeData, 0, sizeof (DPTEdata_t) * n_edges);
01952 memset (all_edges, 0, sizeof (EGuGraphEdge_t *) * n_nodes);
01953 memset (&cur_move, 0, sizeof (DPTFullMove_t));
01954 memset (&base_move, 0, sizeof (DPTFullMove_t));
01955 l_violation = ((3 * n_dominos + 1));
01956 (*new_n_aset) = 0;
01957 (*new_n_bset) = 0;
01958 (*new_n_handle) = 0;
01959 (*new_aset) = 0;
01960 (*new_bset) = 0;
01961 (*new_handle) = 0;
01962
01963
01964 memset (&graphData, 0, sizeof (DPTGdata_t));
01965 graphData.n_dominos = n_dominos;
01966 graphData.n_nodes = n_nodes;
01967 G = EGnewUGraph (mem);
01968 G->data = &graphData;
01969
01970
01971 MESSAGE (DPT_VRB + 19, "Initializing");
01972
01973 for (i = 0; i < (unsigned) n_nodes; i++)
01974 {
01975 nodeData[i].full_move.val = DBL_MAX;
01976 all_nodes[i] = EGuGraphAddNode (G, nodeData + i);
01977 nodeData[i].tree_cn = EGbbtreeAdd (tree, nodeData + i);
01978 }
01979
01980 for (i = 0; i < (unsigned) n_edges; i++)
01981 {
01982 all_edges[i] = EGuGraphAddEdge (G, edgeData + i,
01983 all_nodes[edges[i << 1]],
01984 all_nodes[edges[(i << 1) | 1]]);
01985 }
01986
01987 for (i = n_handle; i--;)
01988 {
01989 nodeData[handle[i]].in_H = 1U;
01990 graphData.n_H[1]++;
01991 }
01992 graphData.n_H[0] = n_nodes - graphData.n_H[1];
01993
01994 for (i = n_dominos; i--;)
01995 {
01996 graphData.n_A[i] = n_aset[i];
01997 graphData.n_B[i] = n_bset[i];
01998 graphData.n_Tc[i] = n_nodes - n_aset[i] - n_bset[i];
01999 for (j = n_aset[i]; j--;)
02000 {
02001 pos = aset[i][j];
02002 EGbitSet (nodeData[pos].Ia, i);
02003 nodeData[pos].n_in_A++;
02004 nodeData[pos].n_in_T++;
02005 }
02006 for (j = n_bset[i]; j--;)
02007 {
02008 pos = bset[i][j];
02009 ADVTESTL (DPT_EDBG, EGbitTest (nodeData[pos].Ia, i), 1, "a node (%d)"
02010 "is in A_%d and B_%d at the same time", pos, i, i);
02011 EGbitSet (nodeData[pos].Ib, i);
02012 nodeData[pos].n_in_T++;
02013 }
02014 }
02015
02016 for (i = n_edges; i--;)
02017 {
02018 N1_id = all_edges[i]->head->id;
02019 N2_id = all_edges[i]->tail->id;
02020 for (j = n_dominos; j--;)
02021 {
02022 N1_inA = EGbitTest (nodeData[N1_id].Ia, j);
02023 N1_inB = EGbitTest (nodeData[N1_id].Ib, j);
02024 N2_inA = EGbitTest (nodeData[N2_id].Ia, j);
02025 N2_inB = EGbitTest (nodeData[N2_id].Ib, j);
02026 N1_inTc = !(N1_inA || N1_inB);
02027 N2_inTc = !(N2_inA || N2_inB);
02028 if ((!N1_inTc && N2_inTc) || (N1_inTc && !N2_inTc))
02029 edgeData[i].n_dT++;
02030 if ((N1_inA && N2_inB) || (N1_inB && N2_inA))
02031 edgeData[i].n_AtoB++;
02032 }
02033 pos =
02034 1U & ((nodeData[N1_id].in_H ^ nodeData[N2_id].in_H) ^ edgeData[i].n_AtoB);
02035 if (pos)
02036 edgeData[i].in_F = 1U;
02037 }
02038 #if DPT_VRB <= DEBUG-1
02039
02040 #endif
02041
02042
02043 MESSAGE (DPT_VRB + 19, "Setting up best move for all nodes");
02044
02045
02046 for (i = n_edges; i--;)
02047 {
02048
02049
02050 if (edgeData[i].n_dT || edgeData[i].n_AtoB || edgeData[i].in_F)
02051 {
02052 if (!EGbitTest (node_update, all_edges[i]->tail->id))
02053 {
02054 DPTResetMove (&cur_move);
02055 cur_move.val = DBL_MAX;
02056 base_move.val = 0;
02057 DPTSetBestMove (all_edges[i]->tail->id, &cur_move, &base_move, 0);
02058 DPTStoreFullMove (all_edges[i]->tail->id, &cur_move);
02059 EGbitSet (node_update, all_edges[i]->tail->id);
02060 #if DPT_VRB+19<DEBUG
02061 DPdisplayMove (all_edges[i]->tail->id);
02062 #endif
02063 }
02064 if (!EGbitTest (node_update, all_edges[i]->head->id))
02065 {
02066 DPTResetMove (&cur_move);
02067 cur_move.val = DBL_MAX;
02068 base_move.val = 0;
02069 DPTSetBestMove (all_edges[i]->head->id, &cur_move, &base_move, 0);
02070 DPTStoreFullMove (all_edges[i]->head->id, &cur_move);
02071 EGbitSet (node_update, all_edges[i]->head->id);
02072 #if DPT_VRB+19<DEBUG
02073 DPdisplayMove (all_edges[i]->head->id);
02074 #endif
02075 }
02076 }
02077 }
02078
02079 memset (node_update, 0, sizeof (node_update));
02080 #if 0
02081 for (i = n_nodes; i--;)
02082 {
02083 DPTResetMove (&cur_move);
02084 cur_move.val = DBL_MAX;
02085 base_move.val = 0;
02086 DPTSetBestMove (i, &cur_move, &base_move, 0);
02087 DPTStoreFullMove (i, &cur_move);
02088 #if DPT_VRB+19<DEBUG
02089 DPdisplayMove (i);
02090 #endif
02091 }
02092 #endif
02093 MESSAGE (DPT_VRB + 19, "Best move set for all nodes");
02094
02095
02096
02097 o_violation = -(3 * n_dominos + 1);
02098 DPTpriceConstraint (&o_violation);
02099 MESSAGE (DPT_VRB + 19, "Computing Original violation %lg", o_violation);
02100 l_violation = o_violation;
02101
02102
02103
02104
02105 while (((cost_tmp = (nc_data =
02106 DPTNdata (EGbbtreeMin (tree)->this))->full_move.val)
02107 < -DPTMinImprovement) && max_iter--)
02108 {
02109 MESSAGE (DPT_VRB + 19, "Try to find best move (current best %8.6lf)",
02110 cost_tmp);
02111 memcpy (&cur_move, &(nc_data->full_move), sizeof (DPTFullMove_t));
02112 #if DPT_VRB+19<DEBUG
02113 DPdisplayMove (cur_move.move[0].n_id);
02114 #endif
02115
02116
02117 if (!DPTisFullMoveFeasible (&cur_move))
02118 {
02119 i = cur_move.move[0].n_id;
02120 #if DPT_VRB+0<DEBUG
02121 DPdisplayMove (i);
02122 #endif
02123 MESSAGE (DPT_VRB + 1, "Move for node %u dom %u infeasible", i,
02124 cur_move.move[0].dom);
02125 DPTResetMove (&cur_move);
02126 cur_move.val = DBL_MAX;
02127 base_move.val = 0;
02128 DPTSetBestMove (i, &cur_move, &base_move, 0);
02129 DPTStoreFullMove (i, &cur_move);
02130 #if DPT_VRB+0<DEBUG
02131 DPdisplayMove (i);
02132 #endif
02133 continue;
02134 }
02135
02136 if (cost_tmp < DPTMinImprovement)
02137 DPTresetFlags ();
02138
02139
02140
02141
02142
02143 MESSAGE (DPT_VRB + 19, "Imp: %8.6lf Tot: %8.6lf node %u move %s depth %u",
02144 cost_tmp, l_violation, cur_move.move[0].n_id,
02145 move_name[cur_move.move[0].move_id], nc_data->full_move.depth);
02146 DPTmakeFullMove (&cur_move);
02147 l_violation += cost_tmp;
02148
02149 #if DPT_EDBG <= DEBUG
02150 EXITRVAL (DPTTestEdges ());
02151 cost_tmp = -(3 * n_dominos + 1);
02152 DPTpriceConstraint (&cost_tmp);
02153 EXIT ((fabs (cost_tmp - l_violation) > 1e-3) &&
02154 DPdisplayMove (cur_move.move[0].n_id), "Error computing violation"
02155 ", predicted %8.6lf computed %8.6lf diference %8.6lf",
02156 l_violation, cost_tmp, l_violation - cost_tmp);
02157 #endif
02158
02159
02160 DPTupdateNeighMove (&cur_move);
02161 }
02162
02163 cost_tmp = ((DPTNdata_t *) (EGbbtreeMin (tree)->this))->full_move.val;
02164 MESSAGE (DPT_VRB + 19, "No good moves left (current best %8.6lf)",
02165 (cost_tmp));
02166
02167
02168 if (o_violation > l_violation + 1e-4)
02169
02170
02171 {
02172 MESSAGE (DPT_VRB - 1, "Original: %8.6lf New: %8.6lf Diff: %lg", o_violation,
02173 l_violation, fabs (o_violation - l_violation));
02174
02175 (*new_n_aset) = EGsMalloc (int,
02176 n_dominos);
02177 (*new_n_bset) = EGsMalloc (int,
02178 n_dominos);
02179 (*new_aset) = EGsMalloc (int *,
02180 n_dominos);
02181 (*new_bset) = EGsMalloc (int *,
02182 n_dominos);
02183 (*new_n_handle) = 0;
02184 in_H = graphData.n_H[1] < graphData.n_H[0] ? 1 : 0;
02185 TESTL (DPT_EDBG, !(graphData.n_H[in_H]), "handle is empty!");
02186 (*new_handle) = EGsMalloc (int,
02187 graphData.n_H[in_H]);
02188 for (i = n_dominos; i--;)
02189 {
02190 TESTL (DPT_EDBG, !(graphData.n_A[i]) || !(graphData.n_B[i]) ||
02191 !(graphData.n_Tc[i]),
02192 "domino(%u) with empty component A=%u, B=%u, " "T^c=%u", i,
02193 graphData.n_A[i], graphData.n_B[i], graphData.n_Tc[i]);
02194 (*new_aset)[i] = EGsMalloc (int,
02195 graphData.n_A[i]);
02196 (*new_bset)[i] = EGsMalloc (int,
02197 graphData.n_B[i]);
02198 (*new_n_aset)[i] = 0;
02199 (*new_n_bset)[i] = 0;
02200 }
02201
02202
02203 for (i = n_nodes; i--;)
02204 {
02205 n_data = nodeData + i;
02206 if ((n_data->in_H & 1U) == in_H)
02207 (*new_handle)[(*new_n_handle)++] = i;
02208
02209 for (j = n_dominos; j--;)
02210 {
02211 if (EGbitTest (n_data->Ia, j))
02212 (*new_aset)[j][(*new_n_aset)[j]++] = i;
02213 if (EGbitTest (n_data->Ib, j))
02214 (*new_bset)[j][(*new_n_bset)[j]++] = i;
02215 }
02216 }
02217
02218 TESTL (DPT_EDBG, (in_H ? ((*new_n_handle) != (signed) graphData.n_H[1]) :
02219 ((*new_n_handle) != (signed) graphData.n_H[0])),
02220 "handle size " "doesn't agree with what we have found");
02221 for (i = n_dominos; i--;)
02222 {
02223 TESTL (DPT_EDBG, (*new_n_aset)[i] != (signed) graphData.n_A[i],
02224 "size of A_[%u] doesn't match", i);
02225 TESTL (DPT_EDBG, (*new_n_bset)[i] != (signed) graphData.n_B[i],
02226 "size of B_[%u] doesn't match", i);
02227 }
02228 }
02229
02230
02231 MESSAGE (DPT_VRB + 19, "Clearing graph");
02232 EGuGraphClearMP (G, nullFreeMP, nullFreeMP, nullFreeMP, mem, mem, mem);
02233 MESSAGE (DPT_VRB + 19, "Freing graph");
02234 EGfreeUGraph (G);
02235 MESSAGE (DPT_VRB + 19, "Freing all_nodes");
02236 EGfree (all_nodes);
02237 MESSAGE (DPT_VRB + 19, "Freing all_edges");
02238 EGfree (all_edges);
02239 MESSAGE (DPT_VRB + 19, "Freing tree");
02240 EGfreeBbtree (tree);
02241 MESSAGE (DPT_VRB + 19, "Freing nodeData");
02242 EGfree (nodeData);
02243 MESSAGE (DPT_VRB + 19, "Freing edgeData");
02244 EGfree (edgeData);
02245 MESSAGE (DPT_VRB + 19, "Freing mempool");
02246 EGfreeMemPool (mem);
02247 *violation = l_violation;
02248 MESSAGE (DPT_VRB + 19, "Ending with violation %8.6lf", *violation);
02249 return rval;
02250 }
02251 #else
02252 int DPtighten (
02253 int n_nodes,
02254 int n_edges,
02255 int *edges,
02256 double *weight,
02257
02258 int n_dominos,
02259 int *n_aset,
02260 int *n_bset,
02261 int n_handle,
02262 int **aset,
02263 int **bset,
02264 int *handle,
02265
02266 int **new_n_aset,
02267 int **new_n_bset,
02268 int *new_n_handle,
02269 int ***new_aset,
02270 int ***new_bset,
02271 int **new_handle,
02272 double *violation)
02273 {
02274 register int i;
02275 *new_n_aset = EGsMalloc (int,
02276 n_dominos);
02277 *new_n_bset = EGsMalloc (int,
02278 n_dominos);
02279 *new_aset = EGsMalloc (int *,
02280 n_dominos);
02281 *new_bset = EGsMalloc (int *,
02282 n_dominos);
02283 *new_n_handle = n_handle;
02284 *new_handle = EGsMalloc (int,
02285 n_handle);
02286 memcpy (*new_handle, handle, sizeof (int) * n_handle);
02287 memcpy (*new_n_aset, n_aset, sizeof (int) * n_dominos);
02288 memcpy (*new_n_bset, n_bset, sizeof (int) * n_dominos);
02289 for (i = n_dominos; i--;)
02290 {
02291 (*new_aset)[i] = EGsMalloc (int,
02292 n_aset[i]);
02293 (*new_bset)[i] = EGsMalloc (int,
02294 n_bset[i]);
02295 memcpy (((*new_aset)[i]), (aset[i]), sizeof (int) * n_aset[i]);
02296 memcpy (((*new_bset)[i]), (bset[i]), sizeof (int) * n_bset[i]);
02297 }
02298 *violation = 0;
02299 return 0;
02300 }
02301 #endif