Changeset 70


Ignore:
Timestamp:
Jan 7, 2010, 9:02:28 AM (14 years ago)
Author:
(none)
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • proiecte/Parallel-DT/R8/Src/subset.c

    r26 r70  
    66/*************************************************************************/
    77
    8 
    98#include "buildex.i"
    109
    11 
    12 ItemCount
    13         *Slice1,        /* Slice1[c]    = saved values of Freq[x][c] in subset.c */
    14         *Slice2;        /* Slice2[c]    = saved values of Freq[y][c] */
    15 
    16 Set
    17         **Subset;       /* Subset[a][s] = subset s for att a */
    18 
    19 short
    20         *Subsets;       /* Subsets[a] = no. subsets for att a */
    21 
    22 
     10ItemCount *Slice1, /* Slice1[c]    = saved values of Freq[x][c] in subset.c */
     11*Slice2; /* Slice2[c]    = saved values of Freq[y][c] */
     12
     13Set **Subset; /* Subset[a][s] = subset s for att a */
     14
     15short *Subsets; /* Subsets[a] = no. subsets for att a */
    2316
    2417/*************************************************************************/
     
    3023/*************************************************************************/
    3124
    32 
    33     EvalSubset(Att, Fp, Lp, Items)
    34 /*  ----------  */
    35     Attribute Att;
    36     ItemNo Fp, Lp;
    37     ItemCount Items;
    38 {
    39     DiscrValue V1, V2, BestV1, BestV2, Barred;
    40     ItemCount KnownItems;
    41     ClassNo c;
    42     float BaseInfo, MinGain, ThisGain, ThisInfo,
    43         Val, BestVal, BestGain, BestInfo,
    44         PrevVal, PrevGain, PrevInfo,
    45         DiscrKnownBaseInfo(), Worth(), ComputeGain(), TotalInfo();
    46     short Blocks=0, MissingValues=0, ReasonableSubsets, Bytes, b;
    47     Boolean MergedSubsets = false;
    48     int SaveMINOBJS;
    49 
    50     SaveMINOBJS = MINOBJS;
    51     MINOBJS = 1;
    52 
    53     /*  First compute Freq[][], ValFreq[], base info, and the gain
    54         and total info of a split on discrete attribute Att  */
    55 
    56     ComputeFrequencies(Att, Fp, Lp);
    57 
    58     KnownItems = Items - ValFreq[0];
    59     if ( KnownItems < Epsilon )
    60     {
    61         Verbosity(2) printf("\tAtt %s: no known values\n", AttName[Att]);
    62 
    63         Gain[Att] = -Epsilon;
    64         Info[Att] = 0;
    65         return;
    66     }
    67 
    68     BaseInfo = DiscrKnownBaseInfo(KnownItems, MaxAttVal[Att]);
    69 
    70     PrevGain = ComputeGain(BaseInfo, UnknownRate[Att], MaxAttVal[Att],KnownItems);
    71     PrevInfo = TotalInfo(ValFreq, 0, MaxAttVal[Att]) / Items;
    72     PrevVal = Worth(PrevInfo, PrevGain, Epsilon);
    73 
    74     Verbosity(2)
    75     {
    76         printf("\tAtt %s", AttName[Att]);
    77 
    78         Verbosity(3) PrintDistribution(Att, MaxAttVal[Att], true);
    79 
    80         printf("\tinf %.3f, gain %.3f, val=%.3f\n",
    81                 PrevInfo, PrevGain, PrevVal);
    82     }
    83 
    84     /*  Eliminate unrepresented attribute values from Freq[] and ValFreq[]
    85         and form a separate subset for each represented attribute value  */
    86 
    87     Bytes = (MaxAttVal[Att]>>3) + 1;
    88     ClearBits(Bytes, Subset[Att][0]);
    89 
    90     ForEach(V1, 1, MaxAttVal[Att])
    91     {
    92         if ( ValFreq[V1] > 0.5 )
    93         {
    94             if ( ++Blocks < V1 )
    95             {
    96                 ValFreq[Blocks] = ValFreq[V1];
    97                 ForEach(c, 0, MaxClass)
    98                 {
    99                     Freq[Blocks][c] = Freq[V1][c];
    100                 }
    101             }
    102             ClearBits(Bytes, Subset[Att][Blocks]);
    103             SetBit(V1, Subset[Att][Blocks]);
    104         }
    105         else
    106         {
    107             SetBit(V1, Subset[Att][0]);
    108             MissingValues++;
    109         }
    110     }
    111 
    112     /*  Merge any single-class subsets with others of the same class  */
    113     /*  Note: have ValFreq[V] > 0 for all V  */
    114 
    115     ForEach(V1, 1, Blocks-1)
    116     {
    117         for ( c = 0 ; Freq[V1][c] < 0.1 ; c++ )
    118             ;
    119 
    120         if ( Freq[V1][c] < ValFreq[V1] - 0.1 ) continue;
    121 
    122         /*  Now have a single class -- look for others  */
    123 
    124         for ( V2 = V1+1 ; V2 <= Blocks ; )
    125         {
    126             if ( Freq[V2][c] < ValFreq[V2] - 0.1 )
    127             {
    128                 V2++;
    129             }
    130             else
    131             {
    132                 /*  Merge these subsets  */
    133 
    134                 Combine(V1, V2, Blocks);
    135 
    136                 ForEach(b, 0, Bytes-1)
    137                 {
    138                     Subset[Att][V1][b] |= Subset[Att][V2][b];
    139                     Subset[Att][V2][b] = Subset[Att][Blocks][b];
     25EvalSubset(Att, Fp, Lp, Items)
     26        /*  ----------  */
     27        Attribute Att;ItemNo Fp, Lp;ItemCount Items; {
     28        DiscrValue V1, V2, BestV1, BestV2, Barred;
     29        ItemCount KnownItems;
     30        ClassNo c;
     31        float BaseInfo, MinGain, ThisGain, ThisInfo, Val, BestVal, BestGain,
     32                        BestInfo, PrevVal, PrevGain, PrevInfo, DiscrKnownBaseInfo(),
     33                        Worth(), ComputeGain(), TotalInfo();
     34        short Blocks = 0, MissingValues = 0, ReasonableSubsets, Bytes, b;
     35        Boolean MergedSubsets = false;
     36        int SaveMINOBJS;
     37
     38        SaveMINOBJS = MINOBJS;
     39        MINOBJS = 1;
     40
     41        /*  First compute Freq[][], ValFreq[], base info, and the gain
     42         and total info of a split on discrete attribute Att  */
     43
     44        ComputeFrequencies(Att, Fp, Lp);
     45
     46        KnownItems = Items - ValFreq[0];
     47        if (KnownItems < Epsilon) {
     48                Verbosity(2)
     49                        printf("\tAtt %s: no known values\n", AttName[Att]);
     50
     51                Gain[Att] = -Epsilon;
     52                Info[Att] = 0;
     53                return;
     54        }
     55
     56        BaseInfo = DiscrKnownBaseInfo(KnownItems, MaxAttVal[Att]);
     57
     58        PrevGain = ComputeGain(BaseInfo, UnknownRate[Att], MaxAttVal[Att],
     59                        KnownItems);
     60        PrevInfo = TotalInfo(ValFreq, 0, MaxAttVal[Att]) / Items;
     61        PrevVal = Worth(PrevInfo, PrevGain, Epsilon);
     62
     63        Verbosity(2) {
     64                printf("\tAtt %s", AttName[Att]);
     65
     66                Verbosity(3)
     67                        PrintDistribution(Att, MaxAttVal[Att], true);
     68
     69                printf("\tinf %.3f, gain %.3f, val=%.3f\n", PrevInfo, PrevGain, PrevVal);
     70        }
     71
     72        /*  Eliminate unrepresented attribute values from Freq[] and ValFreq[]
     73         and form a separate subset for each represented attribute value  */
     74
     75        Bytes = (MaxAttVal[Att] >> 3) + 1;
     76        ClearBits(Bytes, Subset[Att][0]);
     77
     78        ForEach(V1, 1, MaxAttVal[Att]) {
     79                if (ValFreq[V1] > 0.5) {
     80                        if (++Blocks < V1) {
     81                                ValFreq[Blocks] = ValFreq[V1];
     82                                ForEach(c, 0, MaxClass) {
     83                                        Freq[Blocks][c] = Freq[V1][c];
     84                                }
     85                        }
     86                        ClearBits(Bytes, Subset[Att][Blocks]);
     87                        SetBit(V1, Subset[Att][Blocks]);
     88                } else {
     89                        SetBit(V1, Subset[Att][0]);
     90                        MissingValues++;
     91                }
     92        }
     93
     94        /*  Merge any single-class subsets with others of the same class  */
     95        /*  Note: have ValFreq[V] > 0 for all V  */
     96
     97        ForEach(V1, 1, Blocks-1) {
     98                for (c = 0; Freq[V1][c] < 0.1; c++)
     99                        ;
     100
     101                if (Freq[V1][c] < ValFreq[V1] - 0.1)
     102                        continue;
     103
     104                /*  Now have a single class -- look for others  */
     105
     106                for (V2 = V1 + 1; V2 <= Blocks;) {
     107                        if (Freq[V2][c] < ValFreq[V2] - 0.1) {
     108                                V2++;
     109                        } else {
     110                                /*  Merge these subsets  */
     111
     112                                Combine(V1, V2, Blocks);
     113
     114                                ForEach(b, 0, Bytes-1) {
     115                                        Subset[Att][V1][b] |= Subset[Att][V2][b];
     116                                        Subset[Att][V2][b] = Subset[Att][Blocks][b];
     117                                }
     118
     119                                Blocks--;
     120                                MergedSubsets = true;
     121                        }
     122                }
     123        }
     124
     125        if (MergedSubsets) {
     126                PrevGain = ComputeGain(BaseInfo, UnknownRate[Att], Blocks, KnownItems);
     127                PrevInfo = TotalInfo(ValFreq, 0, Blocks) / Items;
     128                PrevVal = Worth(PrevInfo, PrevGain, Epsilon);
     129
     130                Verbosity(2) {
     131                        printf("\tAfter merging single-class subsets:");
     132
     133                        Verbosity(3)
     134                                PrintDistribution(Att, Blocks, false);
     135
     136                        printf("\tinf %.3f, gain %.3f, val=%.3f\n", PrevInfo, PrevGain,
     137                                        PrevVal);
     138                }
     139        }
     140
     141        /*  Examine possible pair mergers and hill-climb  */
     142
     143        MinGain = PrevGain / 2;
     144
     145        while (Blocks > 2) {
     146                BestVal = BestV1 = 0;
     147                BestGain = -Epsilon;
     148
     149                /*  Check reasonable subsets; if less than 3, bar mergers
     150                 involving the largest block  */
     151
     152                ReasonableSubsets = 0;
     153                Barred = 1;
     154
     155                ForEach(V1, 1, Blocks) {
     156                        if (ValFreq[V1] >= SaveMINOBJS)
     157                                ReasonableSubsets++;
     158
     159                        if (ValFreq[V1] > ValFreq[Barred])
     160                                Barred = V1;
     161                }
     162
     163                if (ReasonableSubsets >= 3)
     164                        Barred = 0;
     165
     166                /*  For each possible pair of values, calculate the gain and
     167                 total info of a split in which they are treated as one.
     168                 Keep track of the pair with the best gain.  */
     169
     170                ForEach(V1, 1, Blocks-1) {
     171                        ForEach(V2, V1+1, Blocks) {
     172                                if (V1 == Barred || V2 == Barred)
     173                                        continue;
     174
     175                                Combine(V1, V2, Blocks);
     176
     177                                ThisGain = ComputeGain(BaseInfo, UnknownRate[Att], Blocks - 1,
     178                                                KnownItems);
     179                                ThisInfo = TotalInfo(ValFreq, 0, Blocks - 1) / Items;
     180                                Val = Worth(ThisInfo, ThisGain, Epsilon);
     181
     182                                Verbosity(4) {
     183                                        printf("\tcombine %d %d info %.3f gain %.3f val %.3f", V1,
     184                                                        V2, ThisInfo, ThisGain, Val);
     185                                        PrintDistribution(Att, Blocks - 1, false);
     186                                }
     187
     188                                /*  Force a split if
     189                                 less than two reasonable subsets, or
     190                                 using GAIN criterion
     191                                 Prefer this split to the previous one if
     192                                 gain >= MinGain (and previous < MinGain), or
     193                                 val >= previous best val  */
     194
     195                                if (ThisGain >= MinGain && BestGain < MinGain || Val >= BestVal
     196                                                || !BestV1 && (!GAINRATIO || ReasonableSubsets < 2)) {
     197                                        BestVal = Val;
     198                                        BestGain = ThisGain;
     199                                        BestInfo = ThisInfo;
     200                                        BestV1 = V1;
     201                                        BestV2 = V2;
     202                                }
     203
     204                                Uncombine(V1, V2);
     205                        }
     206                }
     207
     208                if (GAINRATIO && ReasonableSubsets >= 2 && (!BestV1 || BestVal
     209                                < PrevVal + 1E-5 || BestVal == PrevVal && BestGain < PrevGain))
     210                        break;
     211
     212                PrevGain = BestGain;
     213                PrevInfo = BestInfo;
     214                PrevVal = BestVal;
     215
     216                Combine(BestV1, BestV2, Blocks);
     217
     218                ForEach(b, 0, Bytes-1) {
     219                        Subset[Att][BestV1][b] |= Subset[Att][BestV2][b];
     220                        Subset[Att][BestV2][b] = Subset[Att][Blocks][b];
    140221                }
    141222
    142223                Blocks--;
    143                 MergedSubsets = true;
    144             }
    145         }
    146     }
    147 
    148     if ( MergedSubsets )
    149     {
    150         PrevGain = ComputeGain(BaseInfo, UnknownRate[Att], Blocks, KnownItems);
    151         PrevInfo = TotalInfo(ValFreq, 0, Blocks) / Items;
    152         PrevVal = Worth(PrevInfo, PrevGain, Epsilon);
    153 
    154         Verbosity(2)
    155         {
    156             printf("\tAfter merging single-class subsets:");
    157 
    158             Verbosity(3) PrintDistribution(Att, Blocks, false);
    159 
    160             printf("\tinf %.3f, gain %.3f, val=%.3f\n",
    161                     PrevInfo, PrevGain, PrevVal);
    162         }
    163     }
    164 
    165     /*  Examine possible pair mergers and hill-climb  */
    166 
    167     MinGain = PrevGain / 2;
    168 
    169     while ( Blocks > 2 )
    170     {
    171         BestVal = BestV1 = 0;
    172         BestGain = -Epsilon;
    173 
    174         /*  Check reasonable subsets; if less than 3, bar mergers
    175             involving the largest block  */
    176 
    177         ReasonableSubsets = 0;
    178         Barred = 1;
    179 
    180         ForEach(V1, 1, Blocks)
    181         {
    182             if ( ValFreq[V1] >= SaveMINOBJS ) ReasonableSubsets++;
    183 
    184             if ( ValFreq[V1] > ValFreq[Barred] ) Barred = V1;
    185         }
    186 
    187         if ( ReasonableSubsets >= 3 ) Barred = 0;
    188 
    189         /*  For each possible pair of values, calculate the gain and
    190             total info of a split in which they are treated as one.
    191             Keep track of the pair with the best gain.  */
    192 
    193         ForEach(V1, 1, Blocks-1)
    194         {
    195             ForEach(V2, V1+1, Blocks)
    196             {
    197                 if ( V1 == Barred || V2 == Barred ) continue;
    198 
    199                 Combine(V1, V2, Blocks);
    200 
    201                 ThisGain = ComputeGain(BaseInfo, UnknownRate[Att],
    202                                         Blocks-1, KnownItems);
    203                 ThisInfo = TotalInfo(ValFreq, 0, Blocks-1) / Items;
    204                 Val      = Worth(ThisInfo, ThisGain, Epsilon);
    205 
    206                 Verbosity(4)
    207                 {
    208                     printf("\tcombine %d %d info %.3f gain %.3f val %.3f",
    209                            V1, V2, ThisInfo, ThisGain, Val);
    210                     PrintDistribution(Att, Blocks-1, false);
    211                 }
    212 
    213                 /*  Force a split if
    214                         less than two reasonable subsets, or
    215                         using GAIN criterion
    216                     Prefer this split to the previous one if
    217                         gain >= MinGain (and previous < MinGain), or
    218                         val >= previous best val  */
    219 
    220                 if ( ThisGain >= MinGain && BestGain < MinGain ||
    221                      Val >= BestVal ||
    222                      ! BestV1 && ( ! GAINRATIO || ReasonableSubsets < 2 ) )
    223                 {
    224                     BestVal  = Val;
    225                     BestGain = ThisGain;
    226                     BestInfo = ThisInfo;
    227                     BestV1   = V1;
    228                     BestV2   = V2;
    229                 }
    230 
    231                 Uncombine(V1, V2);
    232             }
    233         }
    234 
    235         if ( GAINRATIO &&
    236              ReasonableSubsets >= 2 &&
    237              ( ! BestV1 ||
    238                BestVal < PrevVal + 1E-5 ||
    239                BestVal == PrevVal && BestGain < PrevGain ) ) break;
    240 
    241         PrevGain = BestGain;
    242         PrevInfo = BestInfo;
    243         PrevVal = BestVal;
    244 
    245         Combine(BestV1, BestV2, Blocks);
    246 
    247         ForEach(b, 0, Bytes-1)
    248         {
    249             Subset[Att][BestV1][b] |= Subset[Att][BestV2][b];
    250             Subset[Att][BestV2][b] = Subset[Att][Blocks][b];
    251         }
    252 
    253         Blocks--;
    254 
    255         Verbosity(2)
    256         {
    257             printf("\t\tform subset ");
    258             PrintSubset(Att, Subset[Att][BestV1]);
    259             printf(": %d subsets, inf %.3f, gain %.3f, val %.3f\n",
    260                    Blocks, BestInfo, BestGain, BestVal);
    261             Verbosity(3)
    262             {
    263                 printf("\t\tcombine %d, %d", BestV1, BestV2);
    264                 PrintDistribution(Att, Blocks, false);
    265             }
    266         }
    267     }
    268 
    269     MINOBJS = SaveMINOBJS;
    270 
    271     if ( PrevVal <= 0 )
    272     {
    273         Gain[Att] = -Epsilon;
    274         Info[Att] = 0;
    275     }
    276     else
    277     {
    278         Gain[Att] = ComputeGain(BaseInfo, UnknownRate[Att], Blocks, KnownItems);
    279         Info[Att] = PrevInfo;
    280 
    281         if ( MissingValues )
    282         {
    283             Blocks++;
    284             CopyBits(Bytes, Subset[Att][0], Subset[Att][Blocks]);
    285         }
    286 
    287         Subsets[Att] = Blocks;
    288 
    289         Verbosity(2) printf("\tFinal subsets:");
    290         Verbosity(3) PrintDistribution(Att, Blocks, false);
    291         Verbosity(2)
    292             printf("\tinf %.3f gain %.3f val %.3f\n",
    293                    Info[Att], Gain[Att], Worth(Info[Att], Gain[Att], Epsilon));
    294     }
    295 }
    296 
    297 
     224
     225                Verbosity(2) {
     226                        printf("\t\tform subset ");
     227                        PrintSubset(Att, Subset[Att][BestV1]);
     228                        printf(": %d subsets, inf %.3f, gain %.3f, val %.3f\n", Blocks,
     229                                        BestInfo, BestGain, BestVal);
     230                        Verbosity(3) {
     231                                printf("\t\tcombine %d, %d", BestV1, BestV2);
     232                                PrintDistribution(Att, Blocks, false);
     233                        }
     234                }
     235        }
     236
     237        MINOBJS = SaveMINOBJS;
     238
     239        if (PrevVal <= 0) {
     240                Gain[Att] = -Epsilon;
     241                Info[Att] = 0;
     242        } else {
     243                Gain[Att] = ComputeGain(BaseInfo, UnknownRate[Att], Blocks, KnownItems);
     244                Info[Att] = PrevInfo;
     245
     246                if (MissingValues) {
     247                        Blocks++;
     248                        CopyBits(Bytes, Subset[Att][0], Subset[Att][Blocks]);
     249                }
     250
     251                Subsets[Att] = Blocks;
     252
     253                Verbosity(2)
     254                        printf("\tFinal subsets:");
     255                Verbosity(3)
     256                        PrintDistribution(Att, Blocks, false);
     257                Verbosity(2)
     258                        printf("\tinf %.3f gain %.3f val %.3f\n", Info[Att], Gain[Att],
     259                                        Worth(Info[Att], Gain[Att], Epsilon));
     260        }
     261}
    298262
    299263/*************************************************************************/
     
    305269/*************************************************************************/
    306270
    307 
    308     Combine(x, y, Last)
    309 /*  -------  */
    310     DiscrValue x, y, Last;
    311 {
    312     ClassNo c;
    313 
    314     ForEach(c, 0, MaxClass)
    315     {
    316         Slice1[c] = Freq[x][c];
    317         Slice2[c] = Freq[y][c];
    318 
    319         Freq[x][c] += Freq[y][c];
    320         Freq[y][c]  = Freq[Last][c];
    321     }
    322 
    323     Slice1[MaxClass+1] = ValFreq[x];
    324     Slice2[MaxClass+1] = ValFreq[y];
    325 
    326     ValFreq[x] += ValFreq[y];
    327     ValFreq[y]  = ValFreq[Last];
    328 }
    329 
    330 
     271Combine(x, y, Last)
     272        /*  -------  */
     273        DiscrValue x, y, Last; {
     274        ClassNo c;
     275
     276        ForEach(c, 0, MaxClass) {
     277                Slice1[c] = Freq[x][c];
     278                Slice2[c] = Freq[y][c];
     279
     280                Freq[x][c] += Freq[y][c];
     281                Freq[y][c] = Freq[Last][c];
     282        }
     283
     284        Slice1[MaxClass + 1] = ValFreq[x];
     285        Slice2[MaxClass + 1] = ValFreq[y];
     286
     287        ValFreq[x] += ValFreq[y];
     288        ValFreq[y] = ValFreq[Last];
     289}
    331290
    332291/*************************************************************************/
     
    337296/*************************************************************************/
    338297
    339 
    340     Uncombine(x, y)
    341 /*  ---------  */
    342     DiscrValue x, y;
    343 {
    344     ClassNo c;
    345 
    346     ForEach(c, 0, MaxClass)
    347     {
    348         Freq[x][c] = Slice1[c];
    349         Freq[y][c] = Slice2[c];
    350     }
    351 
    352     ValFreq[x] = Slice1[MaxClass+1];
    353     ValFreq[y] = Slice2[MaxClass+1];
    354 }
    355 
    356 
     298Uncombine(x, y)
     299        /*  ---------  */
     300        DiscrValue x, y; {
     301        ClassNo c;
     302
     303        ForEach(c, 0, MaxClass) {
     304                Freq[x][c] = Slice1[c];
     305                Freq[y][c] = Slice2[c];
     306        }
     307
     308        ValFreq[x] = Slice1[MaxClass + 1];
     309        ValFreq[y] = Slice2[MaxClass + 1];
     310}
    357311
    358312/*************************************************************************/
     
    362316/*************************************************************************/
    363317
    364 
    365     PrintSubset(Att, Ss)
    366 /*  -----------  */
    367     Attribute Att;
    368     Set Ss;
    369 {
    370     DiscrValue V1;
    371     Boolean First=true;
    372 
    373     ForEach(V1, 1, MaxAttVal[Att])
    374     {
    375         if ( In(V1, Ss) )
    376         {
    377             if ( First )
    378             {
    379                 First = false;
    380             }
    381             else
    382             {
    383                 printf(", ");
    384             }
    385 
    386             printf("%s", AttValName[Att][V1]);
    387         }
    388     }
    389 }
    390 
    391 
     318PrintSubset(Att, Ss)
     319        /*  -----------  */
     320        Attribute Att;Set Ss; {
     321        DiscrValue V1;
     322        Boolean First = true;
     323
     324        ForEach(V1, 1, MaxAttVal[Att]) {
     325                if (In(V1, Ss)) {
     326                        if (First) {
     327                                First = false;
     328                        } else {
     329                                printf(", ");
     330                        }
     331
     332                        printf("%s", AttValName[Att][V1]);
     333                }
     334        }
     335}
    392336
    393337/*************************************************************************/
     
    397341/*************************************************************************/
    398342
    399 
    400     SubsetTest(Node, Att)
    401 /*  -----------  */
    402     Tree Node;
    403     Attribute Att;
    404 {
    405     ItemCount CountItems();
    406     short S, Bytes;
    407 
    408     Sprout(Node, Subsets[Att]);
    409 
    410     Node->NodeType      = BrSubset;
    411     Node->Tested        = Att;
    412     Node->Errors        = 0;
    413    
    414     Bytes = (MaxAttVal[Att]>>3) + 1;
    415     Node->Subset = (Set *) calloc(Subsets[Att] + 1, sizeof(Set));
    416     ForEach(S, 1, Node->Forks)
    417     {
    418         Node->Subset[S] = (Set) malloc(Bytes);
    419         CopyBits(Bytes, Subset[Att][S], Node->Subset[S]);
    420     }
    421 }
     343SubsetTest(Node, Att)
     344        /*  -----------  */
     345        Tree Node;Attribute Att; {
     346        ItemCount CountItems();
     347        short S, Bytes;
     348
     349        Sprout(Node, Subsets[Att]);
     350
     351        Node->NodeType = BrSubset;
     352        Node->Tested = Att;
     353        Node->Errors = 0;
     354
     355        Bytes = (MaxAttVal[Att] >> 3) + 1;
     356        Node->Subset = (Set *) calloc(Subsets[Att] + 1, sizeof(Set));
     357        ForEach(S, 1, Node->Forks) {
     358                Node->Subset[S] = (Set) malloc(Bytes);
     359                CopyBits(Bytes, Subset[Att][S], Node->Subset[S]);
     360        }
     361}
Note: See TracChangeset for help on using the changeset viewer.