Scippy

UG

Ubiquity Generator framework

bbParaNodePool.h
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and software framework */
4/* UG --- Ubquity Generator Framework */
5/* */
6/* Copyright Written by Yuji Shinano <shinano@zib.de>, */
7/* Copyright (C) 2021-2024 by Zuse Institute Berlin, */
8/* licensed under LGPL version 3 or later. */
9/* Commercial licenses are available through <licenses@zib.de> */
10/* */
11/* This code is free software; you can redistribute it and/or */
12/* modify it under the terms of the GNU Lesser General Public License */
13/* as published by the Free Software Foundation; either version 3 */
14/* of the License, or (at your option) any later version. */
15/* */
16/* This program is distributed in the hope that it will be useful, */
17/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19/* GNU Lesser General Public License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
23/* */
24/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
26/**@file bbParaNodePool.h
27 * @brief BbParaNode Pool.
28 * @author Yuji Shinano
29 *
30 *
31 *
32 */
33
34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36
37#ifndef __BB_PARA_NODE_POOL_H__
38#define __BB_PARA_NODE_POOL_H__
39#include <map>
40#include <queue>
41#include <cfloat>
42#include <cmath>
43#include "bbParaInstance.h"
44#include "bbParaNodesMerger.h"
45#include "bbParaNode.h"
46
47namespace UG
48{
49
50static const double eps = 1.0e-12;
51
52
53///
54/// class BbParaNodeSortCriterion
55///
57{
58
59public:
60
61 ///
62 /// ()operator
63 /// @return true if n1 < n2
64 ///
66 const BbParaNodePtr& n1, ///< BbParaNode pointer n1
67 const BbParaNodePtr& n2 ///< BbParaNode pointer n2
68 ) const
69 {
70
71 return EPSLT(n1->getDualBoundValue(),n2->getDualBoundValue(),eps) ||
73 n1->getDiffSubproblem() && n2->getDiffSubproblem() &&
75
76 }
77};
78
79///
80/// class BbParaNodeSortCriterionForCleanUp
81///
83{
84
85public:
86
87 ///
88 /// ()operator
89 /// @return true if n1 > n2
90 ///
92 const BbParaNodePtr& n1, ///< BbParaNode pointer n1
93 const BbParaNodePtr& n2 ///< BbParaNode pointer n2
94 ) const
95 {
96
97 return EPSGT(n1->getDualBoundValue(),n2->getDualBoundValue(),eps) ||
99 n1->getDiffSubproblem() && n2->getDiffSubproblem() &&
101
102 }
103};
104
105///
106/// class BbParaNodePool
107///
109{
110
111protected:
112
113 double bgap; ///< gap which can be considered as good
114 size_t maxUsageOfPool; ///< maximum usage of this pool
115
116public:
117
118 ///
119 /// constructor
120 ///
122 double inBgap ///< gap which can be considered as good
123 )
124 : bgap(inBgap),
126 {
127 }
128
129 ///
130 /// destructor
131 ///
133 )
134 {
135 }
136
137 ///
138 /// insert BbParaNode to this pool
139 ///
140 virtual void insert(
141 BbParaNodePtr node ///< pointer to BbParaNode object
142 ) = 0;
143
144 ///
145 /// check if this pool is empty or not
146 /// @return true if this pool is empty
147 ///
148 virtual bool isEmpty(
149 ) = 0;
150
151 ///
152 /// extract a BbParaNode object from this pool
153 /// @return pointer to BbParaNode object extracted
154 ///
156 ) = 0;
157
158 ///
159 /// extract a BbParaNode object with the lowest priority from this pool
160 /// @return pointer to BbParaNode object extracted
161 ///
163 ) = 0;
164
165 ///
166 /// extract a BbParaNode object randomly from this pool
167 /// @return pointer to BbParaNode object extracted
168 ///
170 ) = 0;
171
172 ///
173 /// get best dual bound value of BbParaNode object in this pool
174 /// @return best dual bound value
175 ///
176 virtual double getBestDualBoundValue(
177 ) = 0;
178
179 ///
180 /// get number of good (heavy) BbParaNodes in this pool
181 /// @return the number of good BbParaNodes
182 ///
183 virtual unsigned int getNumOfGoodNodes(
184 double globalBestBound ///< global best bound value to evaluate goodness
185 ) = 0;
186
187 ///
188 /// get number of BbParaNodes in this pool
189 /// @return number of BbParaNodes
190 ///
191 virtual size_t getNumOfNodes(
192 ) = 0;
193
194 ///
195 /// remove bounded BbParaNodes by given incumbnet value
196 /// @return the number of bounded BbParaNodes
197 ///
199 double incumbentValue ///< incumbent value
200 ) = 0;
201
202 ///
203 /// update dual bound values for saving BbParaNodes to checkpoint file
204 ///
206 ) = 0;
207
208#ifdef UG_WITH_ZLIB
209
210 ///
211 /// write BbParaNodes to checkpoint file
212 /// @return number of BbParaNodes written
213 ///
215 gzstream::ogzstream &out ///< gzstream for output
216 ) = 0;
217
218#endif
219
220 ///
221 /// remove merged BbParaNodes from this pool
222 /// @return
223 ///
224 virtual int removeMergedNodes(
225 BbParaMergedNodeListElement *head ///< head of Merged BbParaNodes list
226 ) = 0;
227
228 ///
229 /// stringfy this object
230 /// @return string which shows inside of this object as string
231 ///
232 virtual const std::string toString(
233 ) = 0;
234
235 ///
236 /// get maximum usage of this pool
237 /// @return the maximum number of BbParaNodes that were in this pool
238 ///
240 )
241 {
242 return maxUsageOfPool;
243 }
244
245};
246
247///
248/// class BbParaNodePoolForMinimization
249/// @note only minimization pool was written, since all problem is converted to minimization problem inside of UG solvers
250///
252{
253
254 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion > ascendingPool; ///< asnding pool
255
256public:
257
258 ///
259 /// constructor
260 ///
262 double inBgap ///< gap to evaluate a BbParaNode is good or not
263 )
264 : BbParaNodePool(inBgap)
265 {
266 }
267
268 ///
269 /// destructor
270 ///
272 )
273 {
274 if( ascendingPool.size() > 0 )
275 {
276 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
277 for( p = ascendingPool.begin(); p != ascendingPool.end(); )
278 {
279 if( p->second ) delete p->second;
280 ascendingPool.erase(p++);
281 }
282 }
283 }
284
285 ///
286 /// insert a BbParaNode object to this pool
287 ///
288 void insert(
289 BbParaNodePtr paraNode ///< pointer to BbParaNode object to insert
290 )
291 {
292 ascendingPool.insert(std::make_pair(paraNode,paraNode));
293 if( maxUsageOfPool < ascendingPool.size() )
294 {
296 }
297 }
298
299 ///
300 /// check if this pool is empty or not
301 /// @return true if this pool is empty
302 ///
304 )
305 {
306 return ( ascendingPool.size() == 0 );
307 }
308
309 ///
310 /// extract a BbParaNode from this pool
311 /// @return pointer to BbParaNode object extracted
312 ///
314 )
315 {
316 BbParaNodePtr extracted = 0;
317 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
318 p = ascendingPool.begin();
319 while( p != ascendingPool.end() )
320 {
321 if( p->second->getMergeNodeInfo() )
322 {
323 assert( p->second->getMergeNodeInfo()->status != BbParaMergeNodeInfo::PARA_MERGING );
324 if( p->second->getMergingStatus() == 4 ) // merging representative was already deleted
325 {
326 delete p->second; // this delete is not counted in statistics
327 ascendingPool.erase(p++);
328 }
329 else
330 {
331 if( p->second->getMergeNodeInfo()->status == BbParaMergeNodeInfo::PARA_MERGE_CHECKING_TO_OTHER_NODE )
332 {
334 p++;
335 }
336 else
337 {
338 extracted = p->second;
339 ascendingPool.erase(p);
340 break;
341 }
342 }
343 }
344 else
345 {
346 extracted = p->second;
347 ascendingPool.erase(p);
348 break;
349 }
350 }
351 assert( ( p == ascendingPool.end() && (!extracted) ) || ( p != ascendingPool.end() && extracted ) );
352 return extracted;
353 }
354
355 ///
356 /// extract a BbParaNode object with the lowest priority from this pool
357 /// @return pointer to BbParaNode object extracted
358 /// TODO: need to debug
360 )
361 {
362 BbParaNodePtr extracted = 0;
363 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::reverse_iterator rp;
364 rp = ascendingPool.rbegin();
365 // while( rp != ascendingPool.rend() )
366 if( rp != ascendingPool.rend() )
367 {
368 assert( !(rp->second->getMergeNodeInfo()) );
369 extracted = rp->second;
370 // ascendingPool.erase(--(rp.base()));
371 ascendingPool.erase((rp.base()));
372 // break;
373 }
374 // assert( ( rp == ascendingPool.rend() && (!extracted) ) || ( rp != ascendingPool.rend() && extracted ) );
375 return extracted;
376 }
377
378 ///
379 /// get a BbParaNode object, which is expected to extract from this pool
380 /// @return pointer to BbParaNode object, which is expected to extract (Note: the BbParaNode object stays in pool)
381 ///
383 )
384 {
385 BbParaNodePtr node = 0;
386 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
387 p = ascendingPool.begin();
388 while( p != ascendingPool.end() )
389 {
390 assert( !(p->second->getMergeNodeInfo()) ); // should not have this info.
391 node = p->second;
392 break;
393 }
394 assert( ( p == ascendingPool.end() && (!node) ) || ( p != ascendingPool.end() && node ) );
395 return node;
396 }
397
398
399 ///
400 /// extract a BbParaNode object randomly from this pool
401 /// @return pointer to BbParaNode object extracted
402 ///
404 )
405 {
406 BbParaNodePtr extracted = 0;
407 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
408 p = ascendingPool.begin();
409 size_t nNodes = ascendingPool.size();
410 if( nNodes == 0 ) return extracted;
411 int pos = 0;
412 if( nNodes > 10 )
413 {
414 // select nodes randomly
415 pos = rand()% static_cast<int>( nNodes * 0.8 ) + static_cast<int>(nNodes*0.1);
416 if( pos < (static_cast<int>(nNodes*0.1)) || pos > nNodes*0.9 )
417 {
418 THROW_LOGICAL_ERROR4("Invalid pos in extractNodeRandomly in BbParaNodePool: pos = ", pos, ", nNodes = ", nNodes);
419 }
420 for( int j = 0; j < pos; j++ )
421 {
422 p++;
423 }
424 }
425 assert( p != ascendingPool.end() );
426 if( p == ascendingPool.end() ) // should not happen
427 {
428 p = ascendingPool.begin();
429 }
430 if( p->second->getMergeNodeInfo() )
431 {
432 assert( p->second->getMergeNodeInfo()->status != BbParaMergeNodeInfo::PARA_MERGING );
433 if( p->second->getMergingStatus() == 4 ) // merging representative was already deleted
434 {
435 delete p->second; // this delete is not counted in statistics
436 ascendingPool.erase(p);
437 }
438 else
439 {
440 if( p->second->getMergeNodeInfo()->status == BbParaMergeNodeInfo::PARA_MERGE_CHECKING_TO_OTHER_NODE )
441 {
443 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator pp;
444 pp = ascendingPool.begin();
445 while( pp != p )
446 {
447 if( dynamic_cast<BbParaNodePtr>(pp->second) == dynamic_cast<BbParaNodePtr>(p->second)->getMergeNodeInfo()->mergedTo->paraNode )
448 {
449 extracted = pp->second;
450 ascendingPool.erase(pp);
451 break;
452 }
453 pp++;
454 }
455 }
456 else
457 {
458 extracted = p->second;
459 ascendingPool.erase(p);
460 }
461 }
462 }
463 else
464 {
465 extracted = p->second;
466 ascendingPool.erase(p);
467 }
468 if( !extracted )
469 {
470 /** check nodes from the head of this pool */
471 p = ascendingPool.begin();
472 while( p != ascendingPool.end() )
473 {
474 if( p->second->getMergeNodeInfo() )
475 {
476 assert( p->second->getMergeNodeInfo()->status != BbParaMergeNodeInfo::PARA_MERGING );
477 if( p->second->getMergingStatus() == 4 ) // merging representative was already deleted
478 {
479 delete p->second; // this delete is not counted in statistics
480 ascendingPool.erase(p++);
481 }
482 else
483 {
484 if( p->second->getMergeNodeInfo()->status == BbParaMergeNodeInfo::PARA_MERGE_CHECKING_TO_OTHER_NODE )
485 {
487 p++;
488 }
489 else
490 {
491 extracted = p->second;
492 ascendingPool.erase(p);
493 break;
494 }
495 }
496 }
497 else
498 {
499 extracted = p->second;
500 ascendingPool.erase(p);
501 break;
502 }
503 }
504 }
505 assert( ( p == ascendingPool.end() && (!extracted) ) || ( p != ascendingPool.end() && extracted ) );
506 return extracted;
507 }
508
509 ///
510 /// update dual bound values for saving BbParaNodes to checkpoint file
511 ///
513 )
514 {
515 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
516 for( p = ascendingPool.begin(); p != ascendingPool.end(); ++p )
517 {
518 if( p->second->getAncestor() == 0 )
519 {
520 p->second->updateInitialDualBoundToSubtreeDualBound();
521 }
522 }
523 }
524
525#ifdef UG_WITH_ZLIB
526
527 ///
528 /// write BbParaNodes to checkpoint file
529 /// @return number of BbParaNodes written
530 ///
532 gzstream::ogzstream &out ///< gzstream for output
533 )
534 {
535 int n = 0;
536 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
537 for( p = ascendingPool.begin(); p != ascendingPool.end(); ++p )
538 {
539 if( p->second->getAncestor() == 0 )
540 {
541 p->second->write(out);
542 n++;
543 }
544 }
545 return n;
546 }
547
548#endif
549
550 ///
551 /// get best dual bound value of BbParaNode object in this pool
552 /// @return best dual bound value
553 ///
555 )
556 {
557 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
558 p = ascendingPool.begin();
559 if( p != ascendingPool.end() )
560 {
561 return p->second->getDualBoundValue();
562 }
563 else
564 {
565 return DBL_MAX; // no nodes exist
566 }
567 }
568
569 ///
570 /// get number of good (heavy) BbParaNodes in this pool
571 /// @return the number of good BbParaNodes
572 ///
573 unsigned int getNumOfGoodNodes(
574 double globalBestBound ///< global best bound value to evaluate goodness
575 )
576 {
577 /** The following code is not a good idea,
578 * because only a node is received from a solver, LC can switch out
579 if( globalBestBound > getBestDualBoundValue() )
580 globalBestBound = getBestDualBoundValue();
581 */
582//
583// Old code: we had an issue when Pool size is huge
584//
585// int num = 0;
586// std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
587// for( p = ascendingPool.begin(); p != ascendingPool.end() &&
588// ( ( ( p->second->getDualBoundValue() ) - globalBestBound ) /
589// std::max( fabs(globalBestBound) , 1.0 ) ) < bgap;
590// ++p )
591// {
592// num++;
593// }
594
595 int num2 = 0;
596 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::reverse_iterator rp;
597 for( rp = ascendingPool.rbegin(); rp != ascendingPool.rend() &&
598 ( ( ( rp->second->getDualBoundValue() ) - globalBestBound ) /
599 std::max( fabs(globalBestBound) , 1.0 ) ) > bgap;
600 ++rp )
601 {
602 num2++;
603 }
604 int num3 = ascendingPool.size() - num2;
605// assert( num == num3 );
606// std::cout << "################### num = " << num << ", num3 = " << num3 << std::endl;
607
608 return num3;
609 }
610
611 ///
612 /// get number of BbParaNodes in this pool
613 /// @return number of BbParaNodes
614 ///
616 )
617 {
618 return ascendingPool.size();
619 }
620
621 ///
622 /// remove bounded BbParaNodes by given incumbnet value
623 /// @return the number of bounded BbParaNodes
624 ///
626 double incumbentValue ///< incumbent value
627 )
628 {
629 int nDeleted = 0;
630 if( ascendingPool.size() > 0 )
631 {
632 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
633 for( p = ascendingPool.begin(); p != ascendingPool.end(); )
634 {
635 assert( p->second );
636 if( !p->second->getMergeNodeInfo() )
637 {
638 if( p->second->getDualBoundValue() > incumbentValue || p->second->getMergingStatus() == 4 )
639 {
640 nDeleted++;
641 delete p->second;
642 ascendingPool.erase(p++);
643 }
644 else
645 {
646 p++;
647 }
648 }
649 else
650 {
651 if( p->second->getMergeNodeInfo()->status == BbParaMergeNodeInfo::PARA_MERGE_CHECKING_TO_OTHER_NODE )
652 {
653 if( p->second->getDualBoundValue() > incumbentValue || p->second->getMergingStatus() == 4 )
654 {
655 nDeleted++;
656 delete p->second;
657 ascendingPool.erase(p++);
658 }
659 else
660 {
661 p++;
662 }
663 }
664 else
665 {
666 p++;
667 }
668 }
669 }
670 }
671 return nDeleted;
672 }
673
674 ///
675 /// remove merged BbParaNodes from this pool
676 /// @return the number of BbParaNodes removed
677 ///
679 BbParaMergedNodeListElement *head ///< head of Merged BbParaNodes list
680 )
681 {
682 int nDeleted = 0;
683 assert( ascendingPool.size() > 0 );
684 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
685 for( p = ascendingPool.begin(); p != ascendingPool.end() && head; )
686 {
687 assert( p->second );
688 if( p->second->getMergingStatus() == 2 )
689 {
690 BbParaMergedNodeListElement *prev = head;
691 BbParaMergedNodeListElement *cur = head;
692 for( ; cur; cur=cur->next )
693 {
694 if( p->second == cur->node )
695 {
696 break;
697 }
698 prev = cur;
699 }
700 assert(cur);
701 if( prev == head )
702 {
703 if( cur == prev )
704 {
705 head = head->next;
706 }
707 else
708 {
709 assert( cur == prev->next );
710 prev->next = prev->next->next;
711 }
712 }
713 else
714 {
715 assert( cur == prev->next );
716 prev->next = prev->next->next;
717 }
718 assert( p->second == cur->node );
719 assert( cur->node->getMergeNodeInfo() );
720 delete cur;
721 nDeleted++;
722 delete p->second;
723 ascendingPool.erase(p++);
724 }
725 else
726 {
727 p++;
728 }
729 }
730 assert(!head);
731 return nDeleted;
732 }
733
734 ///
735 /// stringfy this object
736 /// @return string which shows inside of this object as string
737 ///
738 const std::string toString(
739 )
740 {
741 std::ostringstream s;
742 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion >::iterator p;
743 for( p = ascendingPool.begin(); p != ascendingPool.end(); ++p )
744 {
745 s << p->second->toString();
746 }
747 return s.str();
748 }
749};
750
751///
752/// class BbParaNodePoolForCleanUp
753///
755{
756 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp > descendingPool;
757
758public:
759
760 ///
761 /// constructor
762 ///
764 double inBgap ///< gap which can be considered as good
765 )
766 : BbParaNodePool(inBgap)
767 {
768 }
769
770 ///
771 /// destructor
772 ///
774 )
775 {
776 if( descendingPool.size() > 0 )
777 {
778 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::iterator p;
779 for( p = descendingPool.begin(); p != descendingPool.end(); )
780 {
781 if( p->second ) delete p->second;
782 descendingPool.erase(p++);
783 }
784 }
785 }
786
787 ///
788 /// insert BbParaNode to this pool
789 ///
790 void insert(
791 BbParaNodePtr paraNode ///< pointer to BbParaNode object
792 )
793 {
794 descendingPool.insert(std::make_pair(paraNode,paraNode));
795 if( maxUsageOfPool < descendingPool.size() )
796 {
798 }
799 }
800
801 ///
802 /// check if this pool is empty or not
803 /// @return true if this pool is empty
804 ///
806 )
807 {
808 return ( descendingPool.size() == 0 );
809 }
810
811 ///
812 /// extract a BbParaNode object from this pool
813 /// @return pointer to BbParaNode object extracted
814 ///
816 )
817 {
818 BbParaNodePtr extracted = 0;
819 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::iterator p;
820 p = descendingPool.begin();
821 while( p != descendingPool.end() )
822 {
823 if( p->second->getMergeNodeInfo() )
824 {
825 THROW_LOGICAL_ERROR1("Nodes merging was used in clean up process!");
826 }
827 extracted = p->second;
828 descendingPool.erase(p);
829 break;
830 }
831 assert( ( p == descendingPool.end() && (!extracted) ) || ( p != descendingPool.end() && extracted ) );
832 return extracted;
833 }
834
835 ///
836 /// extract a BbParaNode object with the lowest priority from this pool
837 /// @return pointer to BbParaNode object extracted
838 ///
840 )
841 {
842 std::cerr << "***** LOGICAL ERROR : should not be called *****" << std::endl;
843 abort();
844 }
845
846 ///
847 /// extract a BbParaNode object randomly from this pool
848 /// @return pointer to BbParaNode object extracted
849 ///
851 )
852 {
853 BbParaNodePtr extracted = 0;
854 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::iterator p;
855 p = descendingPool.begin();
856 while( p != descendingPool.end() )
857 {
858 if( p->second->getMergeNodeInfo() )
859 {
860 THROW_LOGICAL_ERROR1("Nodes merging was used in clean up process!");
861 }
862 extracted = p->second;
863 descendingPool.erase(p);
864 break;
865 }
866 assert( ( p == descendingPool.end() && (!extracted) ) || ( p != descendingPool.end() && extracted ) );
867 return extracted;
868 }
869
870 ///
871 /// update dual bound values for saving BbParaNodes to checkpoint file
872 ///
874 )
875 {
876 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::iterator p;
877 for( p = descendingPool.begin(); p != descendingPool.end(); ++p )
878 {
879 if( p->second->getAncestor() == 0 )
880 {
881 p->second->updateInitialDualBoundToSubtreeDualBound();
882 }
883 }
884 }
885
886#ifdef UG_WITH_ZLIB
887
888 ///
889 /// write BbParaNodes to checkpoint file
890 /// @return number of BbParaNodes written
891 ///
893 gzstream::ogzstream &out ///< gzstram for output
894 )
895 {
896 int n = 0;
897 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::iterator p;
898 for( p = descendingPool.begin(); p != descendingPool.end(); ++p )
899 {
900 if( p->second->getAncestor() == 0 )
901 {
902 p->second->write(out);
903 n++;
904 }
905 }
906 return n;
907 }
908
909#endif
910
911 ///
912 /// get best dual bound value of BbParaNode object in this pool
913 /// @return best dual bound value
914 ///
916 )
917 {
918 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::reverse_iterator rp;
919 rp = descendingPool.rbegin();
920 if( rp != descendingPool.rend() )
921 {
922 return rp->second->getDualBoundValue();
923 }
924 else
925 {
926 return DBL_MAX; // no nodes exist
927 }
928 }
929
930 ///
931 /// get number of good (heavy) BbParaNodes in this pool
932 /// @return the number of good BbParaNodes
933 ///
934 unsigned int getNumOfGoodNodes(
935 double globalBestBound ///< global best bound value to evaluate goodness
936 )
937 {
938 /** The following code is not a good idea,
939 * because only a node is received from a solver, LC can switch out
940 if( globalBestBound > getBestDualBoundValue() )
941 globalBestBound = getBestDualBoundValue();
942 */
943 int num = 0;
944 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::reverse_iterator rp;
945 for( rp = descendingPool.rbegin(); rp != descendingPool.rend() &&
946 ( ( ( rp->second->getDualBoundValue() ) - globalBestBound ) /
947 std::max( fabs(globalBestBound) , 1.0 ) ) < bgap;
948 ++rp )
949 {
950 num++;
951 }
952 return num;
953 }
954
955 ///
956 /// get number of BbParaNodes in this pool
957 /// @return number of BbParaNodes
958 ///
960 )
961 {
962 return descendingPool.size();
963 }
964
965 ///
966 /// remove bounded BbParaNodes by given incumbnet value
967 /// @return the number of bounded BbParaNodes
968 ///
970 double incumbentValue ///< incumbent value
971 )
972 {
973 int nDeleted = 0;
974 if( descendingPool.size() > 0 )
975 {
976 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::iterator p;
977 for( p = descendingPool.begin(); p != descendingPool.end(); )
978 {
979 assert( p->second );
980 if( !p->second->getMergeNodeInfo() )
981 {
982 if( p->second->getDualBoundValue() > incumbentValue )
983 {
984 nDeleted++;
985 delete p->second;
986 descendingPool.erase(p++);
987 }
988 else
989 {
990 p++;
991 }
992 }
993 else
994 {
995 THROW_LOGICAL_ERROR1("Nodes merging was used in clean up process!");
996 }
997 }
998 }
999 return nDeleted;
1000 }
1001
1002 ///
1003 /// remove merged BbParaNodes from this pool
1004 /// @return the number of BbParaNodes removed
1005 ///
1007 BbParaMergedNodeListElement *head ///< head of Merged BbParaNodes list
1008 )
1009 {
1010 THROW_LOGICAL_ERROR1("Nodes merging was used in clean up process!");
1011 }
1012
1013 ///
1014 /// stringfy this object
1015 /// @return string which shows inside of this object as string
1016 ///
1017 const std::string toString(
1018 )
1019 {
1020 std::ostringstream s;
1021 std::multimap<BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp >::iterator p;
1022 for( p = descendingPool.begin(); p != descendingPool.end(); ++p )
1023 {
1024 s << p->second->toString();
1025 }
1026 return s.str();
1027 }
1028};
1029
1030}
1031
1032#endif // __BB_PARA_NODE_POOL_H__
Base class for instance data.
Base class for BbParaNode.
Structs used for merging nodes.
virtual int getNBoundChanges()=0
get the number of bound changes
class BbParaNodePoolForCleanUp
const std::string toString()
stringfy this object
int writeBbParaNodesToCheckpointFile(gzstream::ogzstream &out)
write BbParaNodes to checkpoint file
unsigned int getNumOfGoodNodes(double globalBestBound)
get number of good (heavy) BbParaNodes in this pool
size_t getNumOfNodes()
get number of BbParaNodes in this pool
int removeMergedNodes(BbParaMergedNodeListElement *head)
remove merged BbParaNodes from this pool
int removeBoundedNodes(double incumbentValue)
remove bounded BbParaNodes by given incumbnet value
BbParaNodePtr extractWorstNode()
extract a BbParaNode object with the lowest priority from this pool
BbParaNodePtr extractNode()
extract a BbParaNode object from this pool
void insert(BbParaNodePtr paraNode)
insert BbParaNode to this pool
std::multimap< BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterionForCleanUp > descendingPool
BbParaNodePoolForCleanUp(double inBgap)
constructor
void updateDualBoundsForSavingNodes()
update dual bound values for saving BbParaNodes to checkpoint file
double getBestDualBoundValue()
get best dual bound value of BbParaNode object in this pool
BbParaNodePtr extractNodeRandomly()
extract a BbParaNode object randomly from this pool
bool isEmpty()
check if this pool is empty or not
class BbParaNodePoolForMinimization
const std::string toString()
stringfy this object
int writeBbParaNodesToCheckpointFile(gzstream::ogzstream &out)
write BbParaNodes to checkpoint file
unsigned int getNumOfGoodNodes(double globalBestBound)
get number of good (heavy) BbParaNodes in this pool
size_t getNumOfNodes()
get number of BbParaNodes in this pool
int removeMergedNodes(BbParaMergedNodeListElement *head)
remove merged BbParaNodes from this pool
int removeBoundedNodes(double incumbentValue)
remove bounded BbParaNodes by given incumbnet value
BbParaNodePtr extractWorstNode()
extract a BbParaNode object with the lowest priority from this pool
BbParaNodePtr extractNode()
extract a BbParaNode from this pool
void insert(BbParaNodePtr paraNode)
insert a BbParaNode object to this pool
std::multimap< BbParaNodePtr, BbParaNodePtr, BbParaNodeSortCriterion > ascendingPool
asnding pool
BbParaNodePtr getNextNode()
get a BbParaNode object, which is expected to extract from this pool
void updateDualBoundsForSavingNodes()
update dual bound values for saving BbParaNodes to checkpoint file
double getBestDualBoundValue()
get best dual bound value of BbParaNode object in this pool
BbParaNodePtr extractNodeRandomly()
extract a BbParaNode object randomly from this pool
bool isEmpty()
check if this pool is empty or not
BbParaNodePoolForMinimization(double inBgap)
constructor
class BbParaNodePool
virtual void insert(BbParaNodePtr node)=0
insert BbParaNode to this pool
double bgap
gap which can be considered as good
size_t maxUsageOfPool
maximum usage of this pool
virtual BbParaNodePtr extractNode()=0
extract a BbParaNode object from this pool
virtual double getBestDualBoundValue()=0
get best dual bound value of BbParaNode object in this pool
virtual BbParaNodePtr extractWorstNode()=0
extract a BbParaNode object with the lowest priority from this pool
virtual bool isEmpty()=0
check if this pool is empty or not
BbParaNodePool(double inBgap)
constructor
size_t getMaxUsageOfPool()
get maximum usage of this pool
virtual int removeBoundedNodes(double incumbentValue)=0
remove bounded BbParaNodes by given incumbnet value
virtual ~BbParaNodePool()
destructor
virtual int writeBbParaNodesToCheckpointFile(gzstream::ogzstream &out)=0
write BbParaNodes to checkpoint file
virtual const std::string toString()=0
stringfy this object
virtual void updateDualBoundsForSavingNodes()=0
update dual bound values for saving BbParaNodes to checkpoint file
virtual BbParaNodePtr extractNodeRandomly()=0
extract a BbParaNode object randomly from this pool
virtual size_t getNumOfNodes()=0
get number of BbParaNodes in this pool
virtual unsigned int getNumOfGoodNodes(double globalBestBound)=0
get number of good (heavy) BbParaNodes in this pool
virtual int removeMergedNodes(BbParaMergedNodeListElement *head)=0
remove merged BbParaNodes from this pool
class BbParaNodeSortCriterionForCleanUp
bool operator()(const BbParaNodePtr &n1, const BbParaNodePtr &n2) const
()operator
class BbParaNodeSortCriterion
bool operator()(const BbParaNodePtr &n1, const BbParaNodePtr &n2) const
()operator
class BbParaNode
Definition: bbParaNode.h:62
BbParaMergeNodeInfo * getMergeNodeInfo()
get merge node information struct
Definition: bbParaNode.h:658
BbParaDiffSubproblem * getDiffSubproblem()
getter of diffSubproblem
Definition: bbParaNode.h:353
double getDualBoundValue()
getter of dual bound value
Definition: bbParaNode.h:303
static const double eps
#define THROW_LOGICAL_ERROR1(msg1)
Definition: paraDef.h:52
#define EPSLT(x, y, eps)
Definition: paraDef.h:167
#define THROW_LOGICAL_ERROR4(msg1, msg2, msg3, msg4)
Definition: paraDef.h:103
#define EPSEQ(x, y, eps)
Definition: paraDef.h:166
#define EPSGT(x, y, eps)
Definition: paraDef.h:169
@ PARA_MERGE_CHECKING_TO_OTHER_NODE
checking possibility to merge with the other nodes
@ PARA_MERGED_RPRESENTATIVE
representative node for merging
@ PARA_MERGING
in merging process
BbParaMergeNodeInfo * mergedTo
pointer to merge node info to which this node is merged *‍/
BbParaNode * paraNode
BbParaNode corresponding to this ParaMergeModeInfo *‍/.
enum UG::BbParaMergeNodeInfo_::@0 status
status of this ParaMargeNodeInfo
merged node list element stract
BbParaMergedNodeListElement * next
pointer to the next ParaMergedNodeListElement
BbParaNode * node
pointer to BbParaNode object