1 /*
2 ================================================================================
3 PROJECT:
4
5 John Eddy's Genetic Algorithms (JEGA)
6
7 CONTENTS:
8
9 Implementation of class DesignTarget.
10
11 NOTES:
12
13 See notes of DesignTarget.hpp.
14
15 PROGRAMMERS:
16
17 John Eddy (jpeddy@sandia.gov) (JE)
18
19 ORGANIZATION:
20
21 Sandia National Laboratories
22
23 COPYRIGHT:
24
25 See the LICENSE file in the top level JEGA directory.
26
27 VERSION:
28
29 2.0.0
30
31 CHANGES:
32
33 Tue Dec 20 08:11:48 2005 - Original Version (JE)
34
35 ================================================================================
36 */
37
38
39
40
41 /*
42 ================================================================================
43 Document This File
44 ================================================================================
45 */
46 /** \file
47 * \brief Contains the implementation of the DesignTarget class.
48 */
49
50
51
52
53 /*
54 ================================================================================
55 Includes
56 ================================================================================
57 */
58 // JEGAConfig.hpp should be the first include in all JEGA files.
59 #include <../Utilities/include/JEGAConfig.hpp>
60
61 #ifdef JEGA_THREADSAFE
62 #include <threads/include/mutex.hpp>
63 #include <threads/include/mutex_lock.hpp>
64 #endif
65
66 #include <../Utilities/include/Design.hpp>
67 #include <../Utilities/include/Logging.hpp>
68 #include <../Utilities/include/DesignTarget.hpp>
69 #include <utilities/include/EDDY_DebugScope.hpp>
70 #include <../Utilities/include/RegionOfSpace.hpp>
71 #include <../Utilities/include/LRUDesignCache.hpp>
72 #include <../Utilities/include/ConstraintInfo.hpp>
73 #include <../Utilities/include/DesignMultiSet.hpp>
74 #include <../Utilities/include/DesignVariableInfo.hpp>
75 #include <../Utilities/include/ObjectiveFunctionInfo.hpp>
76
77
78
79
80
81
82
83 /*
84 ================================================================================
85 Namespace Using Directives
86 ================================================================================
87 */
88 JEGA_IF_THREADSAFE(using namespace eddy::threads;)
89 using namespace JEGA::Logging;
90
91
92
93
94
95
96 /*
97 ================================================================================
98 Begin Namespace
99 ================================================================================
100 */
101 namespace JEGA {
102 namespace Utilities {
103
104
105
106 /*
107 ================================================================================
108 Nested Utility Class Implementations
109 ================================================================================
110 */
111 #ifdef JEGA_THREADSAFE
112
113 /// A class housing all mutexes used by the DesignTarget.
114 /**
115 * This gets removed if JEGA_THREADSAFE is not defined.
116 */
117 class DesignTarget::Mutexes
118 {
119 /*
120 ============================================================================
121 Member Data Declarations
122 ============================================================================
123 */
124 public:
125
126 /// A mutex to protect the collection of discards.
127 mutable mutex _discardMutex;
128
129 /*
130 ============================================================================
131 Structors
132 ============================================================================
133 */
134 public:
135
136 /**
137 * \brief Default constructs a Mutexes object which default constructs
138 * all mutexes.
139 */
Mutexes()140 Mutexes(
141 ) :
142 _discardMutex(PTHREAD_MUTEX_RECURSIVE)
143 {
144 EDDY_FUNC_DEBUGSCOPE
145 }
146
147 }; // class DesignTarget::Mutexes
148
149 #endif // JEGA_THREADSAFE
150
151 /*
152 ================================================================================
153 Static Member Data Definitions
154 ================================================================================
155 */
156
157 const std::size_t DesignTarget::DEFAULT_MAX_GUFF_SIZE = 1000;
158
159
160
161
162 /*
163 ================================================================================
164 Mutators
165 ================================================================================
166 */
167
168 void
SetTrackDiscards(bool use)169 DesignTarget::SetTrackDiscards(
170 bool use
171 )
172 {
173 EDDY_FUNC_DEBUGSCOPE
174 this->_trackDiscards = use;
175
176 JEGALOG_II_G(lverbose(), this,
177 ostream_entry(
178 lverbose(), "Design Target: The track discards flag is now set to "
179 // The compiler on sass9000 doesn't like boolalpha.
180 //) << std::boolalpha << this->_trackDiscards
181 ) << (this->_trackDiscards ? "true" : "false")
182 )
183 }
184
185 void
SetMaxGuffSize(std::size_t mgs)186 DesignTarget::SetMaxGuffSize(
187 std::size_t mgs
188 )
189 {
190 EDDY_FUNC_DEBUGSCOPE
191
192 EDDY_SCOPEDLOCK(l, this->_mutexes->_discardMutex)
193 this->_maxGuffSize = mgs;
194 this->_guff.reserve(this->_maxGuffSize);
195
196 // do lazy size decrease. Don't trim the end here. Just wait for it to
197 // fall below the desired number.
198
199 JEGALOG_II_G(lverbose(), this,
200 ostream_entry(
201 lverbose(), "Design Target: The maximum Guff size is now set to "
202 ) << this->_maxGuffSize << '.'
203 )
204 }
205
206 void
SetMaxDiscardCacheSize(std::size_t maxSize)207 DesignTarget::SetMaxDiscardCacheSize(
208 std::size_t maxSize
209 )
210 {
211 EDDY_FUNC_DEBUGSCOPE
212
213 EDDY_SCOPEDLOCK(l, this->_mutexes->_discardMutex)
214 this->_discCache->max_size(maxSize);
215
216 JEGALOG_II_G(lverbose(), this,
217 ostream_entry(
218 lverbose(), "Design Target: The maximum discards cache size is "
219 "now set to ") << this->_maxGuffSize << '.'
220 )
221 }
222
223
224
225
226
227
228
229
230
231 /*
232 ================================================================================
233 Accessors
234 ================================================================================
235 */
236 std::size_t
GetMaxDiscardCacheSize() const237 DesignTarget::GetMaxDiscardCacheSize(
238 ) const
239 {
240 EDDY_FUNC_DEBUGSCOPE
241 return this->_discCache->max_size();
242 }
243
244
245
246
247
248
249
250 /*
251 ================================================================================
252 Public Methods
253 ================================================================================
254 */
255
256
257
258
259
260
261
262
263 /*
264 ================================================================================
265 Subclass Visible Methods
266 ================================================================================
267 */
268
269
270
271
272
273
274
275
276 /*
277 ================================================================================
278 Subclass Overridable Methods
279 ================================================================================
280 */
281 const LRUDesignCache&
CheckoutDiscards() const282 DesignTarget::CheckoutDiscards(
283 ) const
284 {
285 EDDY_FUNC_DEBUGSCOPE
286 JEGA_IF_THREADSAFE(this->_mutexes->_discardMutex.lock();)
287 return *this->_discCache;
288 }
289
290 void
CheckinDiscards() const291 DesignTarget::CheckinDiscards(
292 ) const
293 {
294 EDDY_FUNC_DEBUGSCOPE
295 JEGA_IF_THREADSAFE(this->_mutexes->_discardMutex.unlock();)
296 }
297
298 Design*
GetNewDesign() const299 DesignTarget::GetNewDesign(
300 ) const
301 {
302 EDDY_FUNC_DEBUGSCOPE
303
304 Design* ret = 0x0;
305 {
306 EDDY_SCOPEDLOCK(l, this->_mutexes->_discardMutex)
307 if(this->_guff.empty())
308 return new Design(const_cast<DesignTarget&>(*this));
309 ret = this->_guff.back();
310 this->_guff.pop_back();
311 }
312 ret->ResetID();
313 return ret;
314 }
315
316 Design*
GetNewDesign(const Design & copy) const317 DesignTarget::GetNewDesign(
318 const Design& copy
319 ) const
320 {
321 EDDY_FUNC_DEBUGSCOPE
322
323 Design* ret = 0x0;
324 {
325 EDDY_SCOPEDLOCK(l, this->_mutexes->_discardMutex)
326 if(this->_guff.empty()) return new Design(copy);
327 ret = this->_guff.back();
328 this->_guff.pop_back();
329 }
330 ret->operator =(copy);
331 ret->ResetID();
332 return ret;
333 }
334
335 bool
CheckFeasibility(Design & des) const336 DesignTarget::CheckFeasibility(
337 Design& des
338 ) const
339 {
340 EDDY_FUNC_DEBUGSCOPE
341
342 this->CheckSideConstraints(des);
343 this->CheckNonSideConstraints(des);
344 return des.IsFeasible();
345 }
346
347 bool
CheckSideConstraints(Design & des) const348 DesignTarget::CheckSideConstraints(
349 Design& des
350 ) const
351 {
352 EDDY_FUNC_DEBUGSCOPE
353
354 // Iterating through the design variables and look for out-of-bounds values.
355 for(DesignVariableInfoVector::const_iterator dit(this->_dvInfos.begin());
356 dit!=this->_dvInfos.end(); ++dit)
357 {
358 if(!(*dit)->IsRepInBounds((*dit)->WhichRep(des)))
359 {
360 des.SetSatisfiesBounds(false);
361 return false;
362 }
363 }
364
365 // if we make it here, we satisfied them all.
366 des.SetSatisfiesBounds(true);
367 return true;
368 }
369
370 bool
CheckNonSideConstraints(Design & des) const371 DesignTarget::CheckNonSideConstraints(
372 Design& des
373 ) const
374 {
375 EDDY_FUNC_DEBUGSCOPE
376
377 // iterate through the constraint info list and check for violations.
378 for(ConstraintInfoVector::const_iterator cit(this->_cnInfos.begin());
379 cit!=this->_cnInfos.end(); ++cit)
380 {
381 if((*cit)->GetViolationAmount(des) != 0.0)
382 {
383 des.SetSatisfiesConstraints(false);
384 return false;
385 }
386 }
387
388 // if we make it here, we satisfied them all.
389 des.SetSatisfiesConstraints(true);
390 return true;
391 }
392
393 void
TakeDesign(Design * des)394 DesignTarget::TakeDesign(
395 Design* des
396 )
397 {
398 EDDY_FUNC_DEBUGSCOPE
399 EDDY_ASSERT(des != 0x0);
400 EDDY_ASSERT(&des->GetDesignTarget() == this);
401
402 if(this->_trackDiscards && des->IsEvaluated())
403 {
404 EDDY_SCOPEDLOCK(l, this->_mutexes->_discardMutex)
405 this->_discCache->insert(des);
406 }
407 else
408 {
409 {
410 EDDY_SCOPEDLOCK(l, this->_mutexes->_discardMutex)
411 if(this->_guff.size() < this->_maxGuffSize)
412 {
413 // Must clear prior to unlocking mutex b/c otherwise the design
414 // could be pulled out and used prior to clearing, then get
415 // cleared, etc.
416 des->Dispose();
417 this->_guff.push_back(des);
418 return;
419 }
420 }
421
422 // if we make it here, we're not keeping the design at all. Delete it.
423 delete des;
424 }
425 }
426
427 bool
ReclaimDesign(const Design & des)428 DesignTarget::ReclaimDesign(
429 const Design& des
430 )
431 {
432 EDDY_FUNC_DEBUGSCOPE
433
434 EDDY_SCOPEDLOCK(l, this->_mutexes->_discardMutex)
435 DesignDVSortSet::iterator it(
436 this->_discCache->find_exact(const_cast<Design*>(&des))
437 );
438
439 if(it == this->_discCache->end()) return false;
440 this->_discCache->erase(it);
441 return true;
442 }
443
444 void
RecordAllConstraintViolations(const Design & des) const445 DesignTarget::RecordAllConstraintViolations(
446 const Design& des
447 ) const
448 {
449 EDDY_FUNC_DEBUGSCOPE
450
451 for(ConstraintInfoVector::const_iterator it(this->_cnInfos.begin());
452 it!=this->_cnInfos.end(); ++it)
453 (*it)->RecordViolation(des);
454 }
455
456 bool
AddDesignVariableInfo(DesignVariableInfo & info)457 DesignTarget::AddDesignVariableInfo(
458 DesignVariableInfo& info
459 )
460 {
461 EDDY_FUNC_DEBUGSCOPE
462 EDDY_ASSERT(&info.GetDesignTarget() == this);
463 EDDY_ASSERT(this->_discCache->empty());
464
465 if(&info.GetDesignTarget() != this) return false;
466
467 info.SetNumber(this->_dvInfos.size());
468 this->_dvInfos.push_back(&info);
469
470 JEGALOG_II_G(lverbose(), this,
471 ostream_entry(lverbose(), "Design Target: Design variable " +
472 info.GetLabel() + " added. ") << this->_dvInfos.size()
473 << " design variables now in target."
474 )
475
476 EDDY_SCOPEDLOCK(l2, this->_mutexes->_discardMutex)
477 this->_discCache->flush();
478 this->FlushTheGuff();
479 return true;
480 }
481
482 bool
AddConstraintInfo(ConstraintInfo & info)483 DesignTarget::AddConstraintInfo(
484 ConstraintInfo& info
485 )
486 {
487 EDDY_FUNC_DEBUGSCOPE
488 EDDY_ASSERT(&info.GetDesignTarget() == this);
489 EDDY_ASSERT(this->_discCache->empty());
490
491 if(&info.GetDesignTarget() != this) return false;
492
493 info.SetNumber(this->_cnInfos.size());
494 this->_cnInfos.push_back(&info);
495
496 JEGALOG_II_G(lverbose(), this,
497 ostream_entry(lverbose(), "Design Target: Constraint " +
498 info.GetLabel()) << '(' << info.GetEquation() << ") added. "
499 << this->_cnInfos.size() << " constraints now in target."
500 )
501
502 EDDY_SCOPEDLOCK(l2, this->_mutexes->_discardMutex)
503 this->_discCache->flush();
504 this->FlushTheGuff();
505 return true;
506 }
507
508 bool
AddObjectiveFunctionInfo(ObjectiveFunctionInfo & info)509 DesignTarget::AddObjectiveFunctionInfo(
510 ObjectiveFunctionInfo& info
511 )
512 {
513 EDDY_FUNC_DEBUGSCOPE
514 EDDY_ASSERT(&info.GetDesignTarget() == this);
515 EDDY_ASSERT(this->_discCache->empty());
516
517 if(&info.GetDesignTarget() != this) return false;
518
519 info.SetNumber(this->_ofInfos.size());
520 this->_ofInfos.push_back(&info);
521
522 JEGALOG_II_G(lverbose(), this,
523 ostream_entry(lverbose(), "Design Target: Objective " +
524 info.GetLabel() + " added. ") << this->_ofInfos.size()
525 << " objectives now in target."
526 )
527
528 EDDY_SCOPEDLOCK(l2, this->_mutexes->_discardMutex)
529 this->_discCache->flush();
530 this->FlushTheGuff();
531 return true;
532 }
533
534 RegionOfSpace
GetDesignSpace() const535 DesignTarget::GetDesignSpace(
536 ) const
537 {
538 EDDY_FUNC_DEBUGSCOPE
539 RegionOfSpace ret(this->_dvInfos.size());
540 for(DesignVariableInfoVector::const_iterator it(this->_dvInfos.begin());
541 it!=this->_dvInfos.end(); ++it)
542 ret.SetLimits(
543 (*it)->GetNumber(),
544 (*it)->GetMinRep(),
545 (*it)->GetMaxRep()
546 );
547
548 return ret;
549 }
550
551
552 /*
553 ================================================================================
554 Private Methods
555 ================================================================================
556 */
557
558 void
FlushTheGuff()559 DesignTarget::FlushTheGuff(
560 )
561 {
562 EDDY_FUNC_DEBUGSCOPE
563 EDDY_SCOPEDLOCK(l, this->_mutexes->_discardMutex)
564 for(size_t i=0; i<this->_guff.size(); ++i) delete this->_guff[i];
565 this->_guff.clear();
566 }
567
568
569
570
571
572
573
574 /*
575 ================================================================================
576 Structors
577 ================================================================================
578 */
DesignTarget()579 DesignTarget::DesignTarget(
580 ) :
581 _trackDiscards(true),
582 _discCache(new LRUDesignCache(100)),
583 //_discards(new DesignDVSortSet()),
584 _dvInfos(),
585 _ofInfos(),
586 _cnInfos(),
587 _guff(),
588 _maxGuffSize(DEFAULT_MAX_GUFF_SIZE) JEGA_COMMA_IF_THREADSAFE
589 JEGA_IF_THREADSAFE(_mutexes(new Mutexes()))
590 {
591 EDDY_FUNC_DEBUGSCOPE
592 }
593
~DesignTarget()594 DesignTarget::~DesignTarget(
595 )
596 {
597 EDDY_FUNC_DEBUGSCOPE
598
599 JEGA_IF_THREADSAFE(this->_mutexes->_discardMutex.lock();)
600 //this->_discards->flush();
601 this->_discCache->flush();
602 this->FlushTheGuff();
603 JEGA_IF_THREADSAFE(this->_mutexes->_discardMutex.unlock();)
604
605 DesignVariableInfoVector::iterator dit(this->_dvInfos.begin());
606 for(; dit!=this->_dvInfos.end(); ++dit) delete *dit;
607
608 ConstraintInfoVector::iterator cit(this->_cnInfos.begin());
609 for(; cit!=this->_cnInfos.end(); ++cit) delete *cit;
610
611 ObjectiveFunctionInfoVector::iterator oit(this->_ofInfos.begin());
612 for(; oit!=this->_ofInfos.end(); ++oit) delete *oit;
613
614 JEGA_IF_THREADSAFE(delete this->_mutexes;)
615 //delete this->_discards;
616 delete this->_discCache;
617 }
618
619
620
621
622
623
624 /*
625 ================================================================================
626 End Namespace
627 ================================================================================
628 */
629 } // namespace Utilities
630 } // namespace JEGA
631
632