Windows2003-3790/enduser/troubleshoot/bn/recomend.h
2020-09-30 16:53:55 +02:00

379 lines
9.9 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1997
//
// File: recomend.h
//
//--------------------------------------------------------------------------
//
// recomend.h: Recommendations computations
//
#ifndef _RECOMEND_H_
#define _RECOMEND_H_
#include "cliqset.h"
const IST istNormal = 0; // MSRDEVBUG!
class MBNET_RECOMMENDER;
class GPNDDDIST
{
public:
GPNDDDIST ( GNODEMBND * pgndd = NULL )
:_pgndd(pgndd)
{
}
GNODEMBND & Gnd()
{
assert( _pgndd != NULL );
return *_pgndd;
}
GNODEMBND * & Pgnd()
{
return _pgndd;
}
MDVCPD & Dist ()
{
return _dd;
}
DECLARE_ORDERING_OPERATORS(GPNDDDIST);
protected:
GNODEMBND * _pgndd;
MDVCPD _dd;
};
inline bool GPNDDDIST :: operator < ( const GPNDDDIST & gpndist ) const
{
return _pgndd < gpndist._pgndd;
}
// Define VGPNDDDIST, an array of GPNDDDISTs
DEFINEV(GPNDDDIST);
// Define a pair of node pointer and state index
typedef pair<GNODEMBND *,IST> PNDD_IST;
// Define VPNDD_IST
DEFINEV(PNDD_IST);
//
// Helper class containing processed node information extracted from
// the belief network.
//
class GNODEREFP
{
public:
GNODEREFP ( PROPMGR & propMgr, GNODEMBND * pgndd );
const COST CostObserve () const { return _costObserve; }
const COST CostFix () const { return _costFix; }
COST & Util () { return _costUtil; }
ESTDLBL ELbl () const { return _eLbl; }
GNODEMBND & Gndd () { return *_pgndd; }
GNODEMBND * Pgndd () { return _pgndd; }
bool BLeak () const { return _bLeak; }
bool operator == ( const GNODEREFP & gndref ) const
{ return _pgndd == gndref._pgndd ; }
bool operator < ( const GNODEREFP & gndref ) const
{ return _pgndd < gndref._pgndd; }
bool operator != ( const GNODEREFP & gndref ) const
{ return !(self == gndref); }
bool operator == ( const GNODEMBND * pgndd ) const
{ return _pgndd == pgndd ; }
bool operator < ( const GNODEMBND * pgndd ) const
{ return _pgndd < pgndd; }
bool operator != ( const GNODEMBND * pgndd ) const
{ return !(self == pgndd); }
protected:
GNODEMBND * _pgndd; // Node pointer
ESTDLBL _eLbl; // Standard label
COST _costObserve; // Cost to observe
COST _costFix; // Cost to fix
COST _costUtil; // Computed utility
bool _bLeak; // Leak node from CI expansion?
};
class VPGNODEREFP : public vector<GNODEREFP *>
{
public:
~ VPGNODEREFP ()
{
clear();
}
int ifind ( const GNODEMBND * pgndd )
{
for ( int indref = 0; indref < size(); indref++ )
{
if ( self[indref]->Pgndd() == pgndd )
return indref;
}
return -1;
}
void clear ()
{
for ( int i = 0; i < size(); i++ )
delete self[i];
vector<GNODEREFP *>::clear();
}
};
//
// Recommendations work node structure. (Formerly 'PROBNODE')
//
class GNODERECWORK
{
friend class VGNODERECWORK;
public:
GNODERECWORK ()
: _pgndref(NULL),
_pbFault(0),
_pbOverCost(0)
{}
GNODEREFP * operator -> ()
{ return _pgndref; }
GNODEREFP * operator -> () const
{ return _pgndref; }
COST CostObsIfFixable () const
{
return BFixable()
? _pgndref->CostObserve()
: 0.0;
}
GNODEREFP * Pgndref () const
{ return _pgndref; }
GNODEREFP & Gndref () const
{
assert( _pgndref );
return *_pgndref;
}
void SetCost ( COST cost )
{
assert( _pgndref );
_pgndref->Util() = - cost;
}
bool BFixable () const
{
ESTDLBL elbl = Pgndref()->ELbl();
return elbl == ESTDLBL_fixunobs
|| elbl == ESTDLBL_fixobs;
}
PROB PbOverCost () const { return _pbOverCost; }
PROB PbFault () const { return _pbFault; }
void SetPbFault ( PROB prob )
{ _pbFault = prob ; }
DECLARE_ORDERING_OPERATORS(GNODERECWORK);
protected:
GNODEREFP * _pgndref;
PROB _pbFault;
PROB _pbOverCost;
protected:
void Init ( MBNET_RECOMMENDER & mbnRecom, GNODEREFP * pgndref );
void Init ( GNODEREFP * pgndref, PROB pbFault );
};
//
// Controlled array of recommendations node work structures (Formerly RGPROBNODE).
//
class VGNODERECWORK : public vector<GNODERECWORK>
{
public:
VGNODERECWORK ( MBNET_RECOMMENDER * pmbnRec = NULL )
: _pmbnRec( pmbnRec ),
_bSeqSet( false ),
_iFixedK(-1)
{}
void InitElem ( GNODEMBND * pgndd, int index = -1 );
void InitElem ( GNODEREFP * pgndref, int index = -1 );
enum ESORT
{
ESRT_ProbOverCost,
ESRT_SgnProb,
ESRT_NegCost,
ESRT_SgnUtil
};
void Sort ( ESORT esort );
void Rescale ();
COST Cost ( int ielemFirst = 0, int * piMinK = NULL );
bool BSameSequence ( const VGNODERECWORK & vgnw );
void SetSequenceCost ();
COST CostECRDefault () const
{
assert( _bSeqSet );
return size()
? self[0]->Util()
: CostService();
}
MBNET_RECOMMENDER & MbnRec ()
{
assert( _pmbnRec );
return *_pmbnRec;
}
const MBNET_RECOMMENDER & MbnRec () const
{
assert( _pmbnRec );
return *_pmbnRec;
}
MBNET_RECOMMENDER * & PmbnRec ()
{ return _pmbnRec; }
COST CostService () const;
protected:
MBNET_RECOMMENDER * _pmbnRec; // The controlling recommendations object
bool _bSeqSet; // Has the sequence been set yet?
int _iFixedK; // Fixed state point
};
DEFINEV(VGNODERECWORK);
///////////////////////////////////////////////////////////////////////////////////////
//
// MBNET_RECOMMENDER:
//
// The troubleshooting recommendations object. It's a "node ranker",
// so its results are a list of node pointers and real values stored in members
// of the base class, MBNET_NODE_RANKER.
//
// Since all evidence is relative to a particular inference engine, that engine
// must be used during construction.
//
// To invoke, use operator(). To determine if network state is compatible with
// troubleshooting recommendations, call BReady(). If successful, the information
// collected is saved for the next recommendations call. To force recollection
// of troubleshooting information, call Unready().
//
///////////////////////////////////////////////////////////////////////////////////////
class MBNET_RECOMMENDER : public MBNET_NODE_RANKER
{
public:
// Recommendations computation method
enum ERCMETHOD
{
ERCM_None,
ERCM_FixPlan,
ERCM_Cheap,
ERCM_MostLikely,
ERCM_Random,
ERCM_FixPlanOnly,
ERCM_Max
};
// Construct using the appropriate inference engine
MBNET_RECOMMENDER ( GOBJMBN_CLIQSET & inferEng,
ERCMETHOD ercm = ERCM_FixPlan );
virtual ~ MBNET_RECOMMENDER ();
INT EType () const
{ return EBNO_RANKER_RECOMMENDATIONS; }
// The ranking function
virtual void operator () ();
// Return true if the network is in a state compatible with
// troubleshooting recommendations or sets ErcError(). Can
// be called separately or will be called by ranking operator().
bool BReady ();
// Clear the "ready" condition of the object
void Unready ()
{ _bReady = false; }
// Check to see if the object is in the "ready" condition
bool BIsReady() const
{ return _bReady; }
// Enter evidence for a troubleshooting model
void EnterEvidence ( GNODEMBND * pgndd, // Node to set/observe
const CLAMP & clamp, // Value to set/unset
bool bSet = true ); // Set or observe?
// Return the cost-of-service from the model; it's stored as
// the model's 'cost-to-fix'.
COST CostServiceModel ();
// General accessors
ECGM EcError () const
{ return _err; }
ERCMETHOD ErcMethod () const
{ return _ercm; }
COST CostService () const
{ return _costService; }
COST CostObsProbDef () const
{ return _costObsProbDef; }
PROPMGR & PropMgr()
{ return _propMgr; }
GNODEMBND * PgnddProbDefAbnormal () const
{ return _pgnddPDAbnormal; }
VPGNODEMBND & VpgnddFix ()
{ return _vpgnddFix; }
VPGNODEREFP & Vpgndref ()
{ return _vpgndref; }
ESTDLBL ELbl ( GNODEMBN & gnd );
// Result array of relevant fixables; if 'bUsePriorList'
// is true, member array is starting point. 'pgnddInfo'
// is optional pointer to info node used in INFOPLAN.
void DetermineRelevantFixableNodes ( VGPNDDDIST & vgndddFixRelevant,
bool bUsePriorList,
GNODEMBND * pgnddInfoPlan = NULL );
void ComputeFixSequence ( VGPNDDDIST & vgndddFixRelevant, // IN: Relevant fixable nodes
VGNODERECWORK & vgnrwFix ); // OUT: Ordered fix/repair sequence
// Interface to inference engine
void InferGetBelief ( GNODEMBND * pgndd, MDVCPD & mdvBel );
void InferGetEvidence ( GNODEMBND * pgndd, CLAMP & clamp );
void InferEnterEvidence ( GNODEMBND * pgndd, const CLAMP & clamp );
bool BInferImpossible ();
protected:
GOBJMBN_CLIQSET & _inferEng; // Inference engine
PROPMGR _propMgr; // Property handler
ECGM _err; // Last error code
ERCMETHOD _ercm; // Planning method
GNODEMBND * _pgnddPDAbnormal; // Abnormal PD node
COST _costService; // Service cost; cost-to-fix of network
COST _costObsProbDef; // Cost to observe PD node
VPGNODEMBND _vpgnddFix; // Fixable nodes
VPGNODEREFP _vpgndref; // Array of references to all nodes
bool _bReady; // BReady() has been successfully called
VGPNDDDIST _vgndddFixRelevant; // Relevant fixable nodes with unconditional distributions
protected:
GOBJMBN_CLIQSET & InferEng ()
{ return _inferEng; }
// Formerly "ComputeCosts"
void DetermineRelevantInfoNodes ( VGNODERECWORK & vgnrwFix, // IN: relevant fixables
VGNODERECWORK & vgnrwInfo ); // OUT: relevant infos
// Add to the given array all nodes which are downstream
void ExpandDownstream ( VPGNODEMBND & vpgndd );
// Return true if the current state of evidence gives a different probability
// distribution that the one stored
bool BProbsChange ( GPNDDDIST & gpndddist );
void PrintInstantiations ();
HIDE_UNSAFE(MBNET_RECOMMENDER);
};
#endif // _RECOMEND_H_