Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

378 lines
9.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1997
  6. //
  7. // File: recomend.h
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // recomend.h: Recommendations computations
  12. //
  13. #ifndef _RECOMEND_H_
  14. #define _RECOMEND_H_
  15. #include "cliqset.h"
  16. const IST istNormal = 0; // MSRDEVBUG!
  17. class MBNET_RECOMMENDER;
  18. class GPNDDDIST
  19. {
  20. public:
  21. GPNDDDIST ( GNODEMBND * pgndd = NULL )
  22. :_pgndd(pgndd)
  23. {
  24. }
  25. GNODEMBND & Gnd()
  26. {
  27. assert( _pgndd != NULL );
  28. return *_pgndd;
  29. }
  30. GNODEMBND * & Pgnd()
  31. {
  32. return _pgndd;
  33. }
  34. MDVCPD & Dist ()
  35. {
  36. return _dd;
  37. }
  38. DECLARE_ORDERING_OPERATORS(GPNDDDIST);
  39. protected:
  40. GNODEMBND * _pgndd;
  41. MDVCPD _dd;
  42. };
  43. inline bool GPNDDDIST :: operator < ( const GPNDDDIST & gpndist ) const
  44. {
  45. return _pgndd < gpndist._pgndd;
  46. }
  47. // Define VGPNDDDIST, an array of GPNDDDISTs
  48. DEFINEV(GPNDDDIST);
  49. // Define a pair of node pointer and state index
  50. typedef pair<GNODEMBND *,IST> PNDD_IST;
  51. // Define VPNDD_IST
  52. DEFINEV(PNDD_IST);
  53. //
  54. // Helper class containing processed node information extracted from
  55. // the belief network.
  56. //
  57. class GNODEREFP
  58. {
  59. public:
  60. GNODEREFP ( PROPMGR & propMgr, GNODEMBND * pgndd );
  61. const COST CostObserve () const { return _costObserve; }
  62. const COST CostFix () const { return _costFix; }
  63. COST & Util () { return _costUtil; }
  64. ESTDLBL ELbl () const { return _eLbl; }
  65. GNODEMBND & Gndd () { return *_pgndd; }
  66. GNODEMBND * Pgndd () { return _pgndd; }
  67. bool BLeak () const { return _bLeak; }
  68. bool operator == ( const GNODEREFP & gndref ) const
  69. { return _pgndd == gndref._pgndd ; }
  70. bool operator < ( const GNODEREFP & gndref ) const
  71. { return _pgndd < gndref._pgndd; }
  72. bool operator != ( const GNODEREFP & gndref ) const
  73. { return !(self == gndref); }
  74. bool operator == ( const GNODEMBND * pgndd ) const
  75. { return _pgndd == pgndd ; }
  76. bool operator < ( const GNODEMBND * pgndd ) const
  77. { return _pgndd < pgndd; }
  78. bool operator != ( const GNODEMBND * pgndd ) const
  79. { return !(self == pgndd); }
  80. protected:
  81. GNODEMBND * _pgndd; // Node pointer
  82. ESTDLBL _eLbl; // Standard label
  83. COST _costObserve; // Cost to observe
  84. COST _costFix; // Cost to fix
  85. COST _costUtil; // Computed utility
  86. bool _bLeak; // Leak node from CI expansion?
  87. };
  88. class VPGNODEREFP : public vector<GNODEREFP *>
  89. {
  90. public:
  91. ~ VPGNODEREFP ()
  92. {
  93. clear();
  94. }
  95. int ifind ( const GNODEMBND * pgndd )
  96. {
  97. for ( int indref = 0; indref < size(); indref++ )
  98. {
  99. if ( self[indref]->Pgndd() == pgndd )
  100. return indref;
  101. }
  102. return -1;
  103. }
  104. void clear ()
  105. {
  106. for ( int i = 0; i < size(); i++ )
  107. delete self[i];
  108. vector<GNODEREFP *>::clear();
  109. }
  110. };
  111. //
  112. // Recommendations work node structure. (Formerly 'PROBNODE')
  113. //
  114. class GNODERECWORK
  115. {
  116. friend class VGNODERECWORK;
  117. public:
  118. GNODERECWORK ()
  119. : _pgndref(NULL),
  120. _pbFault(0),
  121. _pbOverCost(0)
  122. {}
  123. GNODEREFP * operator -> ()
  124. { return _pgndref; }
  125. GNODEREFP * operator -> () const
  126. { return _pgndref; }
  127. COST CostObsIfFixable () const
  128. {
  129. return BFixable()
  130. ? _pgndref->CostObserve()
  131. : 0.0;
  132. }
  133. GNODEREFP * Pgndref () const
  134. { return _pgndref; }
  135. GNODEREFP & Gndref () const
  136. {
  137. assert( _pgndref );
  138. return *_pgndref;
  139. }
  140. void SetCost ( COST cost )
  141. {
  142. assert( _pgndref );
  143. _pgndref->Util() = - cost;
  144. }
  145. bool BFixable () const
  146. {
  147. ESTDLBL elbl = Pgndref()->ELbl();
  148. return elbl == ESTDLBL_fixunobs
  149. || elbl == ESTDLBL_fixobs;
  150. }
  151. PROB PbOverCost () const { return _pbOverCost; }
  152. PROB PbFault () const { return _pbFault; }
  153. void SetPbFault ( PROB prob )
  154. { _pbFault = prob ; }
  155. DECLARE_ORDERING_OPERATORS(GNODERECWORK);
  156. protected:
  157. GNODEREFP * _pgndref;
  158. PROB _pbFault;
  159. PROB _pbOverCost;
  160. protected:
  161. void Init ( MBNET_RECOMMENDER & mbnRecom, GNODEREFP * pgndref );
  162. void Init ( GNODEREFP * pgndref, PROB pbFault );
  163. };
  164. //
  165. // Controlled array of recommendations node work structures (Formerly RGPROBNODE).
  166. //
  167. class VGNODERECWORK : public vector<GNODERECWORK>
  168. {
  169. public:
  170. VGNODERECWORK ( MBNET_RECOMMENDER * pmbnRec = NULL )
  171. : _pmbnRec( pmbnRec ),
  172. _bSeqSet( false ),
  173. _iFixedK(-1)
  174. {}
  175. void InitElem ( GNODEMBND * pgndd, int index = -1 );
  176. void InitElem ( GNODEREFP * pgndref, int index = -1 );
  177. enum ESORT
  178. {
  179. ESRT_ProbOverCost,
  180. ESRT_SgnProb,
  181. ESRT_NegCost,
  182. ESRT_SgnUtil
  183. };
  184. void Sort ( ESORT esort );
  185. void Rescale ();
  186. COST Cost ( int ielemFirst = 0, int * piMinK = NULL );
  187. bool BSameSequence ( const VGNODERECWORK & vgnw );
  188. void SetSequenceCost ();
  189. COST CostECRDefault () const
  190. {
  191. assert( _bSeqSet );
  192. return size()
  193. ? self[0]->Util()
  194. : CostService();
  195. }
  196. MBNET_RECOMMENDER & MbnRec ()
  197. {
  198. assert( _pmbnRec );
  199. return *_pmbnRec;
  200. }
  201. const MBNET_RECOMMENDER & MbnRec () const
  202. {
  203. assert( _pmbnRec );
  204. return *_pmbnRec;
  205. }
  206. MBNET_RECOMMENDER * & PmbnRec ()
  207. { return _pmbnRec; }
  208. COST CostService () const;
  209. protected:
  210. MBNET_RECOMMENDER * _pmbnRec; // The controlling recommendations object
  211. bool _bSeqSet; // Has the sequence been set yet?
  212. int _iFixedK; // Fixed state point
  213. };
  214. DEFINEV(VGNODERECWORK);
  215. ///////////////////////////////////////////////////////////////////////////////////////
  216. //
  217. // MBNET_RECOMMENDER:
  218. //
  219. // The troubleshooting recommendations object. It's a "node ranker",
  220. // so its results are a list of node pointers and real values stored in members
  221. // of the base class, MBNET_NODE_RANKER.
  222. //
  223. // Since all evidence is relative to a particular inference engine, that engine
  224. // must be used during construction.
  225. //
  226. // To invoke, use operator(). To determine if network state is compatible with
  227. // troubleshooting recommendations, call BReady(). If successful, the information
  228. // collected is saved for the next recommendations call. To force recollection
  229. // of troubleshooting information, call Unready().
  230. //
  231. ///////////////////////////////////////////////////////////////////////////////////////
  232. class MBNET_RECOMMENDER : public MBNET_NODE_RANKER
  233. {
  234. public:
  235. // Recommendations computation method
  236. enum ERCMETHOD
  237. {
  238. ERCM_None,
  239. ERCM_FixPlan,
  240. ERCM_Cheap,
  241. ERCM_MostLikely,
  242. ERCM_Random,
  243. ERCM_FixPlanOnly,
  244. ERCM_Max
  245. };
  246. // Construct using the appropriate inference engine
  247. MBNET_RECOMMENDER ( GOBJMBN_CLIQSET & inferEng,
  248. ERCMETHOD ercm = ERCM_FixPlan );
  249. virtual ~ MBNET_RECOMMENDER ();
  250. INT EType () const
  251. { return EBNO_RANKER_RECOMMENDATIONS; }
  252. // The ranking function
  253. virtual void operator () ();
  254. // Return true if the network is in a state compatible with
  255. // troubleshooting recommendations or sets ErcError(). Can
  256. // be called separately or will be called by ranking operator().
  257. bool BReady ();
  258. // Clear the "ready" condition of the object
  259. void Unready ()
  260. { _bReady = false; }
  261. // Check to see if the object is in the "ready" condition
  262. bool BIsReady() const
  263. { return _bReady; }
  264. // Enter evidence for a troubleshooting model
  265. void EnterEvidence ( GNODEMBND * pgndd, // Node to set/observe
  266. const CLAMP & clamp, // Value to set/unset
  267. bool bSet = true ); // Set or observe?
  268. // Return the cost-of-service from the model; it's stored as
  269. // the model's 'cost-to-fix'.
  270. COST CostServiceModel ();
  271. // General accessors
  272. ECGM EcError () const
  273. { return _err; }
  274. ERCMETHOD ErcMethod () const
  275. { return _ercm; }
  276. COST CostService () const
  277. { return _costService; }
  278. COST CostObsProbDef () const
  279. { return _costObsProbDef; }
  280. PROPMGR & PropMgr()
  281. { return _propMgr; }
  282. GNODEMBND * PgnddProbDefAbnormal () const
  283. { return _pgnddPDAbnormal; }
  284. VPGNODEMBND & VpgnddFix ()
  285. { return _vpgnddFix; }
  286. VPGNODEREFP & Vpgndref ()
  287. { return _vpgndref; }
  288. ESTDLBL ELbl ( GNODEMBN & gnd );
  289. // Result array of relevant fixables; if 'bUsePriorList'
  290. // is true, member array is starting point. 'pgnddInfo'
  291. // is optional pointer to info node used in INFOPLAN.
  292. void DetermineRelevantFixableNodes ( VGPNDDDIST & vgndddFixRelevant,
  293. bool bUsePriorList,
  294. GNODEMBND * pgnddInfoPlan = NULL );
  295. void ComputeFixSequence ( VGPNDDDIST & vgndddFixRelevant, // IN: Relevant fixable nodes
  296. VGNODERECWORK & vgnrwFix ); // OUT: Ordered fix/repair sequence
  297. // Interface to inference engine
  298. void InferGetBelief ( GNODEMBND * pgndd, MDVCPD & mdvBel );
  299. void InferGetEvidence ( GNODEMBND * pgndd, CLAMP & clamp );
  300. void InferEnterEvidence ( GNODEMBND * pgndd, const CLAMP & clamp );
  301. bool BInferImpossible ();
  302. protected:
  303. GOBJMBN_CLIQSET & _inferEng; // Inference engine
  304. PROPMGR _propMgr; // Property handler
  305. ECGM _err; // Last error code
  306. ERCMETHOD _ercm; // Planning method
  307. GNODEMBND * _pgnddPDAbnormal; // Abnormal PD node
  308. COST _costService; // Service cost; cost-to-fix of network
  309. COST _costObsProbDef; // Cost to observe PD node
  310. VPGNODEMBND _vpgnddFix; // Fixable nodes
  311. VPGNODEREFP _vpgndref; // Array of references to all nodes
  312. bool _bReady; // BReady() has been successfully called
  313. VGPNDDDIST _vgndddFixRelevant; // Relevant fixable nodes with unconditional distributions
  314. protected:
  315. GOBJMBN_CLIQSET & InferEng ()
  316. { return _inferEng; }
  317. // Formerly "ComputeCosts"
  318. void DetermineRelevantInfoNodes ( VGNODERECWORK & vgnrwFix, // IN: relevant fixables
  319. VGNODERECWORK & vgnrwInfo ); // OUT: relevant infos
  320. // Add to the given array all nodes which are downstream
  321. void ExpandDownstream ( VPGNODEMBND & vpgndd );
  322. // Return true if the current state of evidence gives a different probability
  323. // distribution that the one stored
  324. bool BProbsChange ( GPNDDDIST & gpndddist );
  325. void PrintInstantiations ();
  326. HIDE_UNSAFE(MBNET_RECOMMENDER);
  327. };
  328. #endif // _RECOMEND_H_