home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 07 DecisionMaking Architectures / 03 Laramée / Evidence.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-18  |  4.7 KB  |  186 lines

  1. #include "Evidence.h"
  2. #include <iostream.h>
  3.  
  4.  
  5. /*****************************************************************
  6.  * PieceOfEvidence Implementation
  7.  * All very straightforward
  8.  ****************************************************************/
  9.  
  10. PieceOfEvidence::PieceOfEvidence()
  11. {
  12.     Clear();
  13. }
  14.  
  15. void PieceOfEvidence::Clear()
  16. {
  17.     beliefSet = 0;
  18.     beliefValue = 0.0;
  19. }
  20.  
  21.  
  22. /***************************************************************
  23.  * Implementation of BodyOfEvidence
  24.  **************************************************************/
  25.  
  26. BodyOfEvidence::BodyOfEvidence()
  27. {
  28.     Clear();
  29. }
  30.  
  31.  
  32. void BodyOfEvidence::Clear()
  33. {
  34.     for( int i = 0; i < eventAllEvents; i++ )
  35.     {
  36.         mass[ i ].Clear();
  37.         mass[ i ].beliefSet = i;
  38.     }
  39. }
  40.  
  41.  
  42. void BodyOfEvidence::AcceptEvidence( int set, double belief )
  43. {
  44.     mass[ set ].beliefSet = set;
  45.     mass[ set ].beliefValue = belief;
  46. }
  47.  
  48. char * eventNames[] =
  49. {
  50.     "Null event",
  51.     "Pitcher OK",
  52.     "Pitcher Nervous",
  53.     "Pitcher OK or Nervous",
  54.     "Pitcher Tired",
  55.     "Pitcher Tired or OK",
  56.     "Pitcher Tired or Nervous",
  57.     "No opinion"
  58. };
  59.  
  60. void BodyOfEvidence::Print()
  61. {
  62.     for( int i = 0; i < eventAllEvents; i++ )
  63.     {
  64.         cout << "EVENT " << eventNames[ i ] 
  65.                << " has credibility: " << Credibility( mass[ i ].beliefSet )
  66.                  << " and plausibility: " << Plausibility( mass[ i ].beliefSet )
  67.                  << endl;
  68.     }
  69. }
  70.  
  71.  
  72. void BodyOfEvidence::Copy( BodyOfEvidence & source )
  73. {
  74.     for( int i = 0; i < eventAllEvents; i++ )
  75.     {
  76.         mass[ i ].beliefSet = source.mass[ i ].beliefSet;
  77.         mass[ i ].beliefValue = source.mass[ i ].beliefValue;
  78.     }
  79. }
  80.  
  81.  
  82. /**************************************************************
  83.  *
  84.  * BodyOfEvidence::Combine
  85.  *
  86.  * The real meat of the class.  This method implements Dempster's
  87.  * rule for combination of evidence.
  88.  *
  89.  * Return value: true if the two sources of evidence can be 
  90.  * combined, false otherwise.  Dempster's rule fails when the two
  91.  * sources of evidence are completely contradictory, i.e., if
  92.  * Source #1 is absolutely convinced that A is true and Source #2
  93.  * is equally convinced that B is true, there is no way to 
  94.  * reconcile them.
  95.  *
  96.  *************************************************************/
  97.  
  98. bool BodyOfEvidence::Combine( BodyOfEvidence & source )
  99. {
  100.     // Temporary storage required by the application of Dempster's
  101.     // rule; see the article for a discussion of the denominator
  102.   PieceOfEvidence temp[ eventAllEvents ];
  103.     double denominator = 1.0;
  104.  
  105.     // Compare the sets of events in both sources for compatibility
  106.     for( int i = 0; i < eventAllEvents; i++ )
  107.   {
  108.     for( int j = 0; j < eventAllEvents; j++ )
  109.     {
  110.             int intersection = PieceOfEvidence::Intersection( mass[ i ], source.mass[ j ] );
  111.  
  112.             // If the sources corroborate each other, store the combined evidence; otherwise,
  113.             // increase the denominator.  This is direct implementation of Dempster's rule
  114.       if ( intersection )
  115.         temp[ intersection ].beliefValue += PieceOfEvidence::CombinedEvidence( mass[ i ], source.mass[ j ] );
  116.       else
  117.         denominator -= PieceOfEvidence::CombinedEvidence( mass[ i ], source.mass[ j ] );
  118.     }
  119.   }
  120.  
  121.     // If the denominator underflows, the sources contradict each other;
  122.     // there is nothing more we can do
  123.     if ( denominator < 0.0001 )
  124.         return false;
  125.  
  126.     // Otherwise, apply the correction factor to each element of the new
  127.     // body of evidence
  128.     for( i = 0; i < eventAllEvents; i++ )
  129.     {
  130.         mass[ i ].beliefValue = temp[ i ].beliefValue / denominator;
  131.     }
  132.  
  133.     return true;
  134. }
  135.  
  136.  
  137. /***************************************************************
  138.  * 
  139.  * BodyOfEvidence::Plausibility
  140.  *
  141.  * Plausibility of X is equal to the sum of the evidence  
  142.  * supporting all event sets with which X is not 
  143.  * in complete contradiction.  It represents an upper bound on
  144.  * the probability that one or more of the events in X
  145.  * is true.
  146.  *
  147.  **************************************************************/
  148.  
  149. double BodyOfEvidence::Plausibility( int set )
  150. {
  151.     double val = 0.0;
  152.     
  153.     for( int i = 0; i < eventAllEvents; i++ )
  154.     {
  155.         if( PieceOfEvidence::Intersection( mass[ i ], set ) != 0 )
  156.             val += mass[ i ].beliefValue;
  157.     }
  158.  
  159.   return val;
  160. }
  161.  
  162.  
  163. /***************************************************************
  164.  * 
  165.  * BodyOfEvidence::Credibility
  166.  *
  167.  * Credibility of X is equal to the sum of the evidence
  168.  * supporting all event sets completely contained in X.  It 
  169.  * represents a lower bound on the probability that some event
  170.  * in X is true.
  171.  *
  172.  **************************************************************/
  173.  
  174. double BodyOfEvidence::Credibility( int set )
  175. {
  176.     double val = 0.0;
  177.     
  178.     for( int i = 0; i < eventAllEvents; i++ )
  179.     {
  180.         if( PieceOfEvidence::Intersection( mass[ i ], set ) == mass[ i ].beliefSet )
  181.             val += mass[ i ].beliefValue;
  182.     }
  183.  
  184.   return val;
  185. }
  186.