📄 consultr.c
字号:
/*************************************************************************//* *//* Classify items interactively using a set of rules *//* ------------------------------------------------- *//* *//*************************************************************************/#include "defns.i"#include "types.i" /* External data */short MaxAtt, MaxClass, MaxDiscrVal;ItemNo MaxItem;Description *Item;DiscrValue *MaxAttVal;String *ClassName, *AttName, **AttValName, FileName = "DF";char *SpecialStatus;short VERBOSITY = 0, TRACE = 0;Boolean FirstTime = true;PR *Rule;RuleNo NRules = 0, *RuleIndex; short RuleSpace = 0; ClassNo DefaultClass; /* The interview module uses a more complex description of an case called a "Range Description" with lower and upper bounds. For further information, see consult.c */typedef struct ValRange *RangeDescRec;struct ValRange { Boolean Known, Asked; float LowerBound, UpperBound, *Probability; };RangeDescRec RangeDesc;float Confidence;#define MINCF 0.50 /* minimum cf for useable rule *//*************************************************************************//* *//* Find the best rule for the current case. *//* Note: leave probability in Confidence *//* *//*************************************************************************/RuleNo BestRule()/* -------- */{ RuleNo r; float cf, RuleStrength(); Confidence = 0.0; ForEach(r, 1, NRules) { cf = RuleStrength(Rule[r]); if ( cf > 0.3 ) { Confidence = cf; return r; } } return 0;}/*************************************************************************//* *//* Given a rule, determine the strength with which we can conclude *//* that the current case belongs to the class specified by the RHS *//* of the rule *//* *//*************************************************************************/float RuleStrength(Rule)/* ------------ */ PR Rule;{ short d; float RuleProb=1.0, ProbSatisfied(); ForEach(d, 1, Rule.Size) { RuleProb *= ProbSatisfied(Rule.Lhs[d]); if ( RuleProb < MINCF ) { return 0.0; } } return ( (1 - Rule.Error) * RuleProb );}/*************************************************************************//* *//* Determine the probability of the current case description *//* satisfying the given condition *//* *//*************************************************************************/float ProbSatisfied(c)/* ------------- */ Condition c;{ Attribute a; char v; float AddProb=0.0; Test t; DiscrValue i; t = c->CondTest; a = t->Tested; v = c->TestValue; CheckValue(a, Nil); if ( ! RangeDesc[a].Known ) { return 0.0; } switch ( t->NodeType ) { case BrDiscr: /* test of discrete attribute */ return RangeDesc[a].Probability[v]; case ThreshContin: /* test of continuous attribute */ if ( RangeDesc[a].UpperBound <= t->Cut ) { return ( v == 1 ? 1.0 : 0.0 ); } else if ( RangeDesc[a].LowerBound > t->Cut ) { return ( v == 2 ? 1.0 : 0.0 ); } else if ( v == 1 ) { return (t->Cut - RangeDesc[a].LowerBound) / (RangeDesc[a].UpperBound - RangeDesc[a].LowerBound); } else { return (RangeDesc[a].UpperBound - t->Cut) / (RangeDesc[a].UpperBound - RangeDesc[a].LowerBound); } case BrSubset: /* subset test on discrete attribute */ ForEach(i, 1, MaxAttVal[a]) { if ( In(i, t->Subset[v]) ) { AddProb += RangeDesc[a].Probability[i]; } } return AddProb; } return 0.0;}/*************************************************************************//* *//* Process a single case *//* *//*************************************************************************/ InterpretRuleset()/* ---------------- */{ char Reply; Attribute a; RuleNo r; /* Initialise */ ForEach(a, 0, MaxAtt) { RangeDesc[a].Asked = false; } if ( FirstTime ) { FirstTime = false; printf("\n"); } else { printf("\n-------------------------------------------\n\n"); } /* Find the first rule that fires on the item */ if ( r = BestRule() ) { printf("\nDecision:\n"); printf("\t%s", ClassName[Rule[r].Rhs]); if ( Confidence < 1.0 ) { printf(" CF = %.2f", Confidence); } printf("\n"); } else { printf("\nDecision:\n"); printf("\t%s (default class)\n", ClassName[DefaultClass]); } /* Prompt for what to do next */ while ( true ) { printf("\nRetry, new case or quit [r,n,q]: "); Reply = getchar(); SkipLine(Reply); switch ( Reply ) { case 'r': return; case 'n': Clear(); return; case 'q': exit(0); default: printf("Please enter 'r', 'n' or 'q'"); } }} /*************************************************************************//* *//* Main routine for classifying items using a set of rules *//* *//*************************************************************************/ main(Argc, Argv)/* ---- */ int Argc; char *Argv[];{ int o; extern char *optarg; extern int optind; Attribute a; RuleNo r; PrintHeader("production rule interpreter"); /* Process options */ while ( (o = getopt(Argc, Argv, "tvf:")) != EOF ) { switch (o) { case 't': TRACE = 1; break; case 'v': VERBOSITY = 1; break; case 'f': FileName = optarg; break; case '?': printf("unrecognised option\n"); exit(1); } } /* Initialise */ GetNames(); GetRules(); if ( TRACE ) { ForEach(r, 1, NRules) { PrintRule(r); } printf("\nDefault class: %s\n", ClassName[DefaultClass]); } /* Allocate value ranges */ RangeDesc = (struct ValRange *) calloc(MaxAtt+1, sizeof(struct ValRange)); ForEach(a, 0, MaxAtt) { if ( MaxAttVal[a] ) { RangeDesc[a].Probability = (float *) calloc(MaxAttVal[a]+1, sizeof(float)); } } /* Consult */ Clear(); while ( true ) { InterpretRuleset(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -