📄 trees.c
字号:
/*************************************************************************/
/* */
/* Routines for displaying, building, saving and restoring trees */
/* ------------------------------------------------------------- */
/* */
/*************************************************************************/
#include "defns.i"
#include "types.i"
#include "extern.i"
#define Tab "| "
#define TabSize 4
#define Width 80 /* approx max width of printed trees */
/* If lines look like getting too long while a tree is being
printed, subtrees are broken off and printed separately after
the main tree is finished */
short Subtree; /* highest subtree to be printed */
Tree Subdef[100]; /* pointers to subtrees */
FILE *TRf = 0, *fopen(); /* file pointer for tree i/o */
char Fn[500]; /* file name */
/*************************************************************************/
/* */
/* Display entire decision tree T */
/* */
/*************************************************************************/
PrintTree(T)
/* ---------- */
Tree T;
{
short s;
Subtree=0;
printf("Decision Tree:\n");
Show(T, 0);
printf("\n");
ForEach(s, 1, Subtree)
{
printf("\n\nSubtree [S%d]\n", s);
Show(Subdef[s], 0);
printf("\n");
}
printf("\n");
}
/*************************************************************************/
/* */
/* Display the tree T with offset Sh */
/* */
/*************************************************************************/
Show(T, Sh)
/* ---- */
Tree T;
short Sh;
{
DiscrValue v, MaxV;
short MaxLine();
if ( T->NodeType )
{
/* See whether separate subtree needed */
if ( T != Nil && Sh && Sh * TabSize + MaxLine(T) > Width )
{
if ( Subtree < 99 )
{
Subdef[++Subtree] = T;
printf("[S%d]", Subtree);
}
else
{
printf("[S??]");
}
}
else
{
MaxV = T->Forks;
/* Print simple cases first */
ForEach(v, 1, MaxV)
{
if ( ! T->Branch[v]->NodeType )
{
ShowBranch(Sh, T, v);
}
}
/* Print subtrees */
ForEach(v, 1, MaxV)
{
if ( T->Branch[v]->NodeType )
{
ShowBranch(Sh, T, v);
}
}
}
}
else
{
printf(" %s (%.1f", ClassName[T->Leaf], T->Items);
if ( T->Errors > 0 ) printf("/%.1f", T->Errors);
printf(")");
}
}
/*************************************************************************/
/* */
/* Print a node T with offset Sh, branch value v, and continue */
/* */
/*************************************************************************/
ShowBranch(Sh, T, v)
/* ----------- */
short Sh;
Tree T;
DiscrValue v;
{
DiscrValue Pv, Last;
Attribute Att;
Boolean FirstValue;
short TextWidth, Skip, Values=0, i;
Att = T->Tested;
switch ( T->NodeType )
{
case BrDiscr:
Indent(Sh, Tab);
printf("%s = %s:", AttName[Att], AttValName[Att][v]);
break;
case ThreshContin:
Indent(Sh, Tab);
printf("%s %s %g ",
AttName[Att], ( v == 1 ? "<=" : ">" ), T->Cut);
if ( T->Lower != T->Upper )
{
printf("[%g,%g]", T->Lower, T->Upper);
}
printf(":");
break;
case BrSubset:
/* Count values at this branch */
ForEach(Pv, 1, MaxAttVal[Att])
{
if ( In(Pv, T->Subset[v]) )
{
Last = Pv;
Values++;
}
}
if ( ! Values ) return;
Indent(Sh, Tab);
if ( Values == 1 )
{
printf("%s = %s:", AttName[Att], AttValName[Att][Last]);
break;
}
printf("%s in {", AttName[Att]);
FirstValue = true;
Skip = TextWidth = strlen(AttName[Att]) + 5;
ForEach(Pv, 1, MaxAttVal[Att])
{
if ( In(Pv, T->Subset[v]) )
{
if ( ! FirstValue &&
TextWidth + strlen(AttValName[Att][Pv]) + 11 > Width )
{
Indent(Sh, Tab);
ForEach(i, 1, Skip) putchar(' ');
TextWidth = Skip;
FirstValue = true;
}
printf("%s%c", AttValName[Att][Pv], Pv == Last ? '}' : ',');
TextWidth += strlen(AttValName[Att][Pv]) + 1;
FirstValue = false;
}
}
putchar(':');
}
Show(T->Branch[v], Sh+1);
}
/*************************************************************************/
/* */
/* Find the maximum single line size for non-leaf subtree St. */
/* The line format is */
/* <attribute> <> X.xx:[ <class (<Items>)], or */
/* <attribute> = <DVal>:[ <class> (<Items>)] */
/* */
/*************************************************************************/
short MaxLine(St)
/* -------- */
Tree St;
{
Attribute a;
DiscrValue v, MaxV, Next;
short Ll, MaxLl=0;
a = St->Tested;
MaxV = St->Forks;
ForEach(v, 1, MaxV)
{
Ll = ( St->NodeType == 2 ? 4 : strlen(AttValName[a][v]) ) + 1;
/* Find the appropriate branch */
Next = v;
if ( ! St->Branch[Next]->NodeType )
{
Ll += strlen(ClassName[St->Branch[Next]->Leaf]) + 6;
}
MaxLl = Max(MaxLl, Ll);
}
return strlen(AttName[a]) + 4 + MaxLl;
}
/*************************************************************************/
/* */
/* Indent Sh columns */
/* */
/*************************************************************************/
Indent(Sh, Mark)
/* ------ */
short Sh;
char *Mark;
{
printf("\n");
while ( Sh-- ) printf("%s", Mark);
}
/*************************************************************************/
/* */
/* Save entire decision tree T in file with extension Extension */
/* */
/*************************************************************************/
SaveTree(T, Extension)
/* --------- */
Tree T;
String Extension;
{
static char *LastExt="";
if ( strcmp(LastExt, Extension) )
{
LastExt = Extension;
if ( TRf ) fclose(TRf);
strcpy(Fn, FileName);
strcat(Fn, Extension);
if ( ! ( TRf = fopen(Fn, "w") ) )
Error(0, Fn, " for writing");
}
putc('\n', TRf);
OutTree(T);
SaveDiscreteNames();
}
/*************************************************************************/
/* */
/* Save tree T as characters */
/* */
/*************************************************************************/
OutTree(T)
/* -------- */
Tree T;
{
DiscrValue v;
int Bytes;
StreamOut((char *) &T->NodeType, sizeof(short));
StreamOut((char *) &T->Leaf, sizeof(ClassNo));
StreamOut((char *) &T->Items, sizeof(ItemCount));
StreamOut((char *) &T->Errors, sizeof(ItemCount));
StreamOut((char *) T->ClassDist, (MaxClass + 1) * sizeof(ItemCount));
if ( T->NodeType )
{
StreamOut((char *) &T->Tested, sizeof(Attribute));
StreamOut((char *) &T->Forks, sizeof(short));
switch ( T->NodeType )
{
case BrDiscr:
break;
case ThreshContin:
StreamOut((char *) &T->Cut, sizeof(float));
StreamOut((char *) &T->Lower, sizeof(float));
StreamOut((char *) &T->Upper, sizeof(float));
break;
case BrSubset:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -