Coverage Report - weka.classifiers.bayes.net.BayesNetGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
BayesNetGenerator
0%
0/248
0%
0/126
4.5
 
 1  
 /*
 2  
  *   This program is free software: you can redistribute it and/or modify
 3  
  *   it under the terms of the GNU General Public License as published by
 4  
  *   the Free Software Foundation, either version 3 of the License, or
 5  
  *   (at your option) any later version.
 6  
  *
 7  
  *   This program is distributed in the hope that it will be useful,
 8  
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 9  
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10  
  *   GNU General Public License for more details.
 11  
  *
 12  
  *   You should have received a copy of the GNU General Public License
 13  
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 14  
  */
 15  
 
 16  
 /*
 17  
  * BayesNet.java
 18  
  * Copyright (C) 2003-2012 University of Waikato, Hamilton, New Zealand
 19  
  * 
 20  
  */
 21  
 
 22  
 package weka.classifiers.bayes.net;
 23  
 
 24  
 import java.util.Enumeration;
 25  
 import java.util.Random;
 26  
 import java.util.Vector;
 27  
 
 28  
 import weka.classifiers.bayes.net.estimate.DiscreteEstimatorBayes;
 29  
 import weka.core.Attribute;
 30  
 import weka.core.DenseInstance;
 31  
 import weka.core.FastVector;
 32  
 import weka.core.Instance;
 33  
 import weka.core.Instances;
 34  
 import weka.core.Option;
 35  
 import weka.core.OptionHandler;
 36  
 import weka.core.RevisionUtils;
 37  
 import weka.core.Utils;
 38  
 import weka.estimators.Estimator;
 39  
 
 40  
 /**
 41  
  <!-- globalinfo-start -->
 42  
  * Bayes Network learning using various search algorithms and quality measures.<br/>
 43  
  * Base class for a Bayes Network classifier. Provides datastructures (network structure, conditional probability distributions, etc.) and facilities common to Bayes Network learning algorithms like K2 and B.<br/>
 44  
  * <br/>
 45  
  * For more information see:<br/>
 46  
  * <br/>
 47  
  * http://www.cs.waikato.ac.nz/~remco/weka.pdf
 48  
  * <p/>
 49  
  <!-- globalinfo-end -->
 50  
  * 
 51  
  <!-- options-start -->
 52  
  * Valid options are: <p/>
 53  
  * 
 54  
  * <pre> -B
 55  
  *  Generate network (instead of instances)
 56  
  * </pre>
 57  
  * 
 58  
  * <pre> -N &lt;integer&gt;
 59  
  *  Nr of nodes
 60  
  * </pre>
 61  
  * 
 62  
  * <pre> -A &lt;integer&gt;
 63  
  *  Nr of arcs
 64  
  * </pre>
 65  
  * 
 66  
  * <pre> -M &lt;integer&gt;
 67  
  *  Nr of instances
 68  
  * </pre>
 69  
  * 
 70  
  * <pre> -C &lt;integer&gt;
 71  
  *  Cardinality of the variables
 72  
  * </pre>
 73  
  * 
 74  
  * <pre> -S &lt;integer&gt;
 75  
  *  Seed for random number generator
 76  
  * </pre>
 77  
  * 
 78  
  * <pre> -F &lt;file&gt;
 79  
  *  The BIF file to obtain the structure from.
 80  
  * </pre>
 81  
  * 
 82  
  <!-- options-end -->
 83  
  *
 84  
  * @author Remco Bouckaert (rrb@xm.co.nz)
 85  
  * @version $Revision: 8034 $
 86  
  */
 87  
 public class BayesNetGenerator extends EditableBayesNet {
 88  
     /** the seed value */
 89  0
     int m_nSeed = 1;
 90  
     
 91  
     /** the random number generator */
 92  
     Random random;
 93  
     
 94  
     /** for serialization */
 95  
     static final long serialVersionUID = -7462571170596157720L;
 96  
 
 97  
         /**
 98  
          * Constructor for BayesNetGenerator.
 99  
          */
 100  
         public BayesNetGenerator() {
 101  0
                 super();
 102  0
         } // c'tor
 103  
 
 104  
         /** 
 105  
          * Generate random connected Bayesian network with discrete nodes
 106  
          * having all the same cardinality.
 107  
          * 
 108  
          * @throws Exception if something goes wrong
 109  
          */
 110  
         public void generateRandomNetwork () throws Exception {
 111  0
                 if (m_otherBayesNet == null) {
 112  
                         // generate from scratch
 113  0
                         Init(m_nNrOfNodes, m_nCardinality);
 114  0
                         generateRandomNetworkStructure(m_nNrOfNodes, m_nNrOfArcs);
 115  0
                         generateRandomDistributions(m_nNrOfNodes, m_nCardinality);
 116  
                 } else {
 117  
                         // read from file, just copy parent sets and distributions
 118  0
                         m_nNrOfNodes = m_otherBayesNet.getNrOfNodes();
 119  0
                         m_ParentSets = m_otherBayesNet.getParentSets();
 120  0
                         m_Distributions = m_otherBayesNet.getDistributions();
 121  
 
 122  
 
 123  0
                         random = new Random(m_nSeed);
 124  
                         // initialize m_Instances
 125  0
                         FastVector attInfo = new FastVector(m_nNrOfNodes);
 126  
                         // generate value strings
 127  
 
 128  0
                         for (int iNode = 0; iNode < m_nNrOfNodes; iNode++) {
 129  0
                                 int nValues = m_otherBayesNet.getCardinality(iNode);
 130  0
                                 FastVector nomStrings = new FastVector(nValues + 1);
 131  0
                                 for (int iValue = 0; iValue < nValues; iValue++) {
 132  0
                                         nomStrings.addElement(m_otherBayesNet.getNodeValue(iNode, iValue));
 133  
                                 }
 134  0
                                 Attribute att = new Attribute(m_otherBayesNet.getNodeName(iNode), nomStrings);
 135  0
                                 attInfo.addElement(att);
 136  
                         }
 137  
 
 138  0
                         m_Instances = new Instances(m_otherBayesNet.getName(), attInfo, 100);
 139  0
                         m_Instances.setClassIndex(m_nNrOfNodes - 1);
 140  
                 }
 141  0
         } // GenerateRandomNetwork
 142  
 
 143  
         /** 
 144  
          * Init defines a minimal Bayes net with no arcs
 145  
          * @param nNodes number of nodes in the Bayes net 
 146  
          * @param nValues number of values each of the nodes can take
 147  
          * @throws Exception if something goes wrong
 148  
          */
 149  
         public void Init(int nNodes, int nValues) throws Exception {
 150  0
                 random = new Random(m_nSeed);
 151  
                 // initialize structure
 152  0
                 FastVector attInfo = new FastVector(nNodes);
 153  
                 // generate value strings
 154  0
         FastVector nomStrings = new FastVector(nValues + 1);
 155  0
         for (int iValue = 0; iValue < nValues; iValue++) {
 156  0
                         nomStrings.addElement("Value" + (iValue + 1));
 157  
         }
 158  
 
 159  0
                 for (int iNode = 0; iNode < nNodes; iNode++) {
 160  0
                         Attribute att = new Attribute("Node" + (iNode + 1), nomStrings);
 161  0
                         attInfo.addElement(att);
 162  
                 }
 163  0
                  m_Instances = new Instances("RandomNet", attInfo, 100);
 164  0
                  m_Instances.setClassIndex(nNodes - 1);
 165  0
                 setUseADTree(false);
 166  
 //                 m_bInitAsNaiveBayes = false;
 167  
 //                 m_bMarkovBlanketClassifier = false;
 168  0
                 initStructure();
 169  
                 
 170  
                 // initialize conditional distribution tables
 171  0
                 m_Distributions = new Estimator[nNodes][1];
 172  0
                 for (int iNode = 0; iNode < nNodes; iNode++) {
 173  0
                         m_Distributions[iNode][0] = 
 174  
                           new DiscreteEstimatorBayes(nValues, getEstimator().getAlpha());
 175  
                 }
 176  0
                 m_nEvidence = new FastVector(nNodes);
 177  0
                 for (int i = 0; i < nNodes; i++) {
 178  0
                         m_nEvidence.addElement(-1);
 179  
                 }
 180  0
                 m_fMarginP = new FastVector(nNodes);
 181  0
                 for (int i = 0; i < nNodes; i++) {
 182  0
                         double[] P = new double[getCardinality(i)];
 183  0
                         m_fMarginP.addElement(P);
 184  
                 }
 185  
 
 186  0
                 m_nPositionX = new FastVector(nNodes);
 187  0
                 m_nPositionY = new FastVector(nNodes);
 188  0
                 for (int iNode = 0; iNode < nNodes; iNode++) {
 189  0
                         m_nPositionX.addElement(iNode%10 * 50);
 190  0
                         m_nPositionY.addElement(((int)(iNode/10)) * 50);
 191  
                 }
 192  0
         } // DefineNodes
 193  
 
 194  
         /** 
 195  
          * GenerateRandomNetworkStructure generate random connected Bayesian network 
 196  
          * @param nNodes number of nodes in the Bayes net to generate
 197  
          * @param nArcs number of arcs to generate. Must be between nNodes - 1 and nNodes * (nNodes-1) / 2
 198  
          * @throws Exception if number of arcs is incorrect
 199  
          */
 200  
         public void generateRandomNetworkStructure(int nNodes, int nArcs) 
 201  
                 throws Exception
 202  
         {
 203  0
                 if (nArcs < nNodes - 1) {
 204  0
                         throw new Exception("Number of arcs should be at least (nNodes - 1) = " + (nNodes - 1) + " instead of " + nArcs);
 205  
                 }
 206  0
                 if (nArcs > nNodes * (nNodes - 1) / 2) {
 207  0
                         throw new Exception("Number of arcs should be at most nNodes * (nNodes - 1) / 2 = "+ (nNodes * (nNodes - 1) / 2) + " instead of " + nArcs);
 208  
                 }
 209  0
                 if (nArcs == 0) {return;} // deal with  patalogical case for nNodes = 1
 210  
 
 211  
             // first generate tree connecting all nodes
 212  0
             generateTree(nNodes);
 213  
             // The tree contains nNodes - 1 arcs, so there are 
 214  
             // nArcs - (nNodes-1) to add at random.
 215  
             // All arcs point from lower to higher ordered nodes
 216  
             // so that acyclicity is ensured.
 217  0
             for (int iArc = nNodes - 1; iArc < nArcs; iArc++) {
 218  0
                     boolean bDone = false;
 219  0
                     while (!bDone) {
 220  0
                                 int nNode1 = random.nextInt(nNodes);
 221  0
                                 int nNode2 = random.nextInt(nNodes);
 222  0
                                 if (nNode1 == nNode2) {nNode2 = (nNode1 + 1) % nNodes;}
 223  0
                                 if (nNode2 < nNode1) {int h = nNode1; nNode1 = nNode2; nNode2 = h;}
 224  0
                                 if (!m_ParentSets[nNode2].contains(nNode1)) {
 225  0
                                         m_ParentSets[nNode2].addParent(nNode1, m_Instances);
 226  0
                                         bDone = true;
 227  
                                 }
 228  0
                     }
 229  
             }
 230  
 
 231  0
         } // GenerateRandomNetworkStructure
 232  
         
 233  
         /** 
 234  
          * GenerateTree creates a tree-like network structure (actually a
 235  
          * forest) by starting with a randomly selected pair of nodes, add 
 236  
          * an arc between. Then keep on selecting one of the connected nodes 
 237  
          * and one of the unconnected ones and add an arrow between them, 
 238  
          * till all nodes are connected.
 239  
          * @param nNodes number of nodes in the Bayes net to generate
 240  
          */
 241  
         void generateTree(int nNodes) {
 242  0
         boolean [] bConnected = new boolean [nNodes];
 243  
         // start adding an arc at random
 244  0
                 int nNode1 = random.nextInt(nNodes);
 245  0
                 int nNode2 = random.nextInt(nNodes);
 246  0
                 if (nNode1 == nNode2) {nNode2 = (nNode1 + 1) % nNodes;}
 247  0
                 if (nNode2 < nNode1) {int h = nNode1; nNode1 = nNode2; nNode2 = h;}
 248  0
                 m_ParentSets[nNode2].addParent(nNode1, m_Instances);
 249  0
                 bConnected[nNode1] = true;
 250  0
                 bConnected[nNode2] = true;
 251  
                 // Repeatedly, select one of the connected nodes, and one of 
 252  
                 // the unconnected nodes and add an arc.
 253  
             // All arcs point from lower to higher ordered nodes
 254  
             // so that acyclicity is ensured.
 255  0
                 for (int iArc = 2; iArc < nNodes; iArc++ ) {
 256  0
                         int nNode = random.nextInt(nNodes);
 257  0
                         nNode1 = 0; //  one of the connected nodes
 258  0
                         while (nNode >= 0) {
 259  0
                                 nNode1 = (nNode1 + 1) % nNodes;
 260  0
                                 while (!bConnected[nNode1]) {
 261  0
                                         nNode1 = (nNode1 + 1) % nNodes;
 262  
                                 }
 263  0
                                 nNode--;
 264  
                         }
 265  0
                         nNode = random.nextInt(nNodes);
 266  0
                         nNode2 = 0; //  one of the unconnected nodes
 267  0
                         while (nNode >= 0) {
 268  0
                                 nNode2 = (nNode2 + 1) % nNodes;
 269  0
                                 while (bConnected[nNode2]) {
 270  0
                                         nNode2 = (nNode2 + 1) % nNodes;
 271  
                                 }
 272  0
                                 nNode--;
 273  
                         }
 274  0
                         if (nNode2 < nNode1) {int h = nNode1; nNode1 = nNode2; nNode2 = h;}
 275  0
                         m_ParentSets[nNode2].addParent(nNode1, m_Instances);
 276  0
                         bConnected[nNode1] = true;
 277  0
                         bConnected[nNode2] = true;
 278  
                 }
 279  0
         } // GenerateTree
 280  
         
 281  
         /** 
 282  
          * GenerateRandomDistributions generates discrete conditional distribution tables
 283  
          * for all nodes of a Bayes network once a network structure has been determined.
 284  
          * @param nNodes number of nodes in the Bayes net 
 285  
          * @param nValues number of values each of the nodes can take
 286  
          */
 287  
     void generateRandomDistributions(int nNodes, int nValues) {
 288  
             // Reserve space for CPTs
 289  0
             int nMaxParentCardinality = 1;
 290  0
             for (int iAttribute = 0; iAttribute < nNodes; iAttribute++) {
 291  0
             if (m_ParentSets[iAttribute].getCardinalityOfParents() > nMaxParentCardinality) {
 292  0
                      nMaxParentCardinality = m_ParentSets[iAttribute].getCardinalityOfParents();
 293  
             } 
 294  
         } 
 295  
 
 296  
         // Reserve plenty of memory
 297  0
         m_Distributions = new Estimator[m_Instances.numAttributes()][nMaxParentCardinality];
 298  
 
 299  
         // estimate CPTs
 300  0
         for (int iAttribute = 0; iAttribute < nNodes; iAttribute++) {
 301  0
                 int [] nPs = new int [nValues + 1];
 302  0
                 nPs[0] = 0;
 303  0
                 nPs[nValues] = 1000;
 304  0
             for (int iParent = 0; iParent < m_ParentSets[iAttribute].getCardinalityOfParents(); iParent++) {
 305  
                     // fill array with random nr's
 306  0
                     for (int iValue = 1; iValue < nValues; iValue++)  {
 307  0
                             nPs[iValue] = random.nextInt(1000);
 308  
                     }
 309  
                     // sort
 310  0
                     for (int iValue = 1; iValue < nValues; iValue++)  {
 311  0
                             for (int iValue2 = iValue + 1; iValue2 < nValues; iValue2++)  {
 312  0
                                     if (nPs[iValue2] < nPs[iValue]) {
 313  0
                                             int h = nPs[iValue2]; nPs[iValue2] = nPs[iValue]; nPs[iValue] = h;
 314  
                                     }
 315  
                             }
 316  
                     }
 317  
                     // assign to probability tables
 318  0
                     DiscreteEstimatorBayes d = new DiscreteEstimatorBayes(nValues, getEstimator().getAlpha());
 319  0
                     for (int iValue = 0; iValue < nValues; iValue++)  {
 320  0
                             d.addValue(iValue, nPs[iValue + 1] - nPs[iValue]);
 321  
                     }
 322  0
                     m_Distributions[iAttribute][iParent] = d;
 323  
             } 
 324  
         } 
 325  0
     } // GenerateRandomDistributions
 326  
     
 327  
         /**
 328  
          * GenerateInstances generates random instances sampling from the
 329  
          * distribution represented by the Bayes network structure. It assumes
 330  
          * a Bayes network structure has been initialized
 331  
          * 
 332  
          * @throws Exception if something goes wrong
 333  
          */
 334  
         public void generateInstances () throws Exception {
 335  0
             int [] order = getOrder();
 336  0
                 for (int iInstance = 0; iInstance < m_nNrOfInstances; iInstance++) {
 337  0
                     int nNrOfAtts = m_Instances.numAttributes();
 338  0
                         Instance instance = new DenseInstance(nNrOfAtts);
 339  0
                         instance.setDataset(m_Instances);
 340  0
                         for (int iAtt2 = 0; iAtt2 < nNrOfAtts; iAtt2++) {
 341  0
                             int iAtt = order[iAtt2];
 342  
 
 343  0
                                 double iCPT = 0;
 344  
 
 345  0
                                 for (int iParent = 0; iParent < m_ParentSets[iAtt].getNrOfParents(); iParent++) {
 346  0
                                   int nParent = m_ParentSets[iAtt].getParent(iParent);
 347  0
                                   iCPT = iCPT * m_Instances.attribute(nParent).numValues() + instance.value(nParent);
 348  
                                 } 
 349  
         
 350  0
                                 double fRandom = random.nextInt(1000) / 1000.0f;
 351  0
                                 int iValue = 0;
 352  0
                                 while (fRandom > m_Distributions[iAtt][(int) iCPT].getProbability(iValue)) {
 353  0
                                         fRandom = fRandom - m_Distributions[iAtt][(int) iCPT].getProbability(iValue);
 354  0
                                         iValue++ ;
 355  
                                 }
 356  0
                                 instance.setValue(iAtt, iValue);
 357  
                         }
 358  0
                         m_Instances.add(instance);
 359  
                 }
 360  0
         } // GenerateInstances
 361  
 
 362  
     /**
 363  
      * @throws Exception if there's a cycle in the graph
 364  
      */        
 365  
     int [] getOrder() throws Exception {
 366  0
         int nNrOfAtts = m_Instances.numAttributes();
 367  0
         int [] order = new int[nNrOfAtts];
 368  0
         boolean [] bDone = new boolean[nNrOfAtts];
 369  0
         for (int iAtt = 0; iAtt < nNrOfAtts; iAtt++) {
 370  0
             int iAtt2 = 0; 
 371  0
             boolean allParentsDone = false;
 372  0
             while (!allParentsDone && iAtt2 < nNrOfAtts) {
 373  0
                 if (!bDone[iAtt2]) {
 374  0
                     allParentsDone = true;
 375  0
                     int iParent = 0;
 376  0
                     while (allParentsDone && iParent < m_ParentSets[iAtt2].getNrOfParents()) {
 377  0
                         allParentsDone = bDone[m_ParentSets[iAtt2].getParent(iParent++)];
 378  
                     }
 379  0
                     if (allParentsDone && iParent == m_ParentSets[iAtt2].getNrOfParents()) {
 380  0
                         order[iAtt] = iAtt2;
 381  0
                         bDone[iAtt2] = true;
 382  
                     } else {
 383  0
                         iAtt2++;
 384  
                     }
 385  0
                 } else {
 386  0
                     iAtt2++;
 387  
                 }
 388  
             }
 389  0
             if (!allParentsDone && iAtt2 == nNrOfAtts) {
 390  0
                 throw new Exception("There appears to be a cycle in the graph");
 391  
             }
 392  
         }
 393  0
         return order;
 394  
     } // getOrder
 395  
 
 396  
             /**
 397  
              * Returns either the net (if BIF format) or the generated instances
 398  
              * 
 399  
              * @return either the net or the generated instances
 400  
              */
 401  
           public String toString() {
 402  0
             if (m_bGenerateNet) {
 403  0
               return toXMLBIF03();
 404  
             }
 405  0
             return m_Instances.toString();
 406  
           } // toString
 407  
           
 408  
 
 409  0
         boolean m_bGenerateNet = false;
 410  0
         int m_nNrOfNodes = 10;
 411  0
         int m_nNrOfArcs = 10;
 412  0
         int m_nNrOfInstances = 10;
 413  0
         int m_nCardinality = 2;
 414  0
         String m_sBIFFile = "";
 415  
 
 416  0
         void setNrOfNodes(int nNrOfNodes) {m_nNrOfNodes = nNrOfNodes;}
 417  0
         void setNrOfArcs(int nNrOfArcs) {m_nNrOfArcs = nNrOfArcs;}
 418  0
         void setNrOfInstances(int nNrOfInstances) {m_nNrOfInstances = nNrOfInstances;}
 419  0
         void setCardinality(int nCardinality) {m_nCardinality = nCardinality;}
 420  0
         void setSeed(int nSeed) {m_nSeed = nSeed;}
 421  
 
 422  
         /**
 423  
          * Returns an enumeration describing the available options
 424  
          * 
 425  
          * @return an enumeration of all the available options
 426  
          */
 427  
         public Enumeration listOptions() {
 428  0
                 Vector newVector = new Vector(6);
 429  
 
 430  0
                 newVector.addElement(new Option("\tGenerate network (instead of instances)\n", "B", 0, "-B"));
 431  0
                 newVector.addElement(new Option("\tNr of nodes\n", "N", 1, "-N <integer>"));
 432  0
                 newVector.addElement(new Option("\tNr of arcs\n", "A", 1, "-A <integer>"));
 433  0
                 newVector.addElement(new Option("\tNr of instances\n", "M", 1, "-M <integer>"));
 434  0
                 newVector.addElement(new Option("\tCardinality of the variables\n", "C", 1, "-C <integer>"));
 435  0
                 newVector.addElement(new Option("\tSeed for random number generator\n", "S", 1, "-S <integer>"));
 436  0
                 newVector.addElement(new Option("\tThe BIF file to obtain the structure from.\n", "F", 1, "-F <file>"));
 437  
 
 438  0
                 return newVector.elements();
 439  
         } // listOptions
 440  
 
 441  
         /**
 442  
          * Parses a given list of options. <p/>
 443  
          * 
 444  
          <!-- options-start -->
 445  
          * Valid options are: <p/>
 446  
          * 
 447  
          * <pre> -B
 448  
          *  Generate network (instead of instances)
 449  
          * </pre>
 450  
          * 
 451  
          * <pre> -N &lt;integer&gt;
 452  
          *  Nr of nodes
 453  
          * </pre>
 454  
          * 
 455  
          * <pre> -A &lt;integer&gt;
 456  
          *  Nr of arcs
 457  
          * </pre>
 458  
          * 
 459  
          * <pre> -M &lt;integer&gt;
 460  
          *  Nr of instances
 461  
          * </pre>
 462  
          * 
 463  
          * <pre> -C &lt;integer&gt;
 464  
          *  Cardinality of the variables
 465  
          * </pre>
 466  
          * 
 467  
          * <pre> -S &lt;integer&gt;
 468  
          *  Seed for random number generator
 469  
          * </pre>
 470  
          * 
 471  
          * <pre> -F &lt;file&gt;
 472  
          *  The BIF file to obtain the structure from.
 473  
          * </pre>
 474  
          * 
 475  
          <!-- options-end -->
 476  
          *
 477  
          * @param options the list of options as an array of strings
 478  
          * @exception Exception if an option is not supported
 479  
          */
 480  
         public void setOptions(String[] options) throws Exception {
 481  0
                 m_bGenerateNet = Utils.getFlag('B', options);
 482  
 
 483  0
                 String sNrOfNodes = Utils.getOption('N', options);
 484  0
                 if (sNrOfNodes.length() != 0) {
 485  0
                   setNrOfNodes(Integer.parseInt(sNrOfNodes));
 486  
                 } else {
 487  0
                         setNrOfNodes(10);
 488  
                 } 
 489  
 
 490  0
                 String sNrOfArcs = Utils.getOption('A', options);
 491  0
                 if (sNrOfArcs.length() != 0) {
 492  0
                   setNrOfArcs(Integer.parseInt(sNrOfArcs));
 493  
                 } else {
 494  0
                         setNrOfArcs(10);
 495  
                 } 
 496  
 
 497  0
                 String sNrOfInstances = Utils.getOption('M', options);
 498  0
                 if (sNrOfInstances.length() != 0) {
 499  0
                   setNrOfInstances(Integer.parseInt(sNrOfInstances));
 500  
                 } else {
 501  0
                         setNrOfInstances(10);
 502  
                 } 
 503  
 
 504  0
                 String sCardinality = Utils.getOption('C', options);
 505  0
                 if (sCardinality.length() != 0) {
 506  0
                   setCardinality(Integer.parseInt(sCardinality));
 507  
                 } else {
 508  0
                         setCardinality(2);
 509  
                 } 
 510  
 
 511  0
                 String sSeed = Utils.getOption('S', options);
 512  0
                 if (sSeed.length() != 0) {
 513  0
                   setSeed(Integer.parseInt(sSeed));
 514  
                 } else {
 515  0
                         setSeed(1);
 516  
                 } 
 517  
 
 518  0
                 String sBIFFile = Utils.getOption('F', options);
 519  0
                 if ((sBIFFile != null) && (sBIFFile != "")) {
 520  0
                         setBIFFile(sBIFFile);
 521  
                 }
 522  0
         } // setOptions
 523  
 
 524  
         /**
 525  
          * Gets the current settings of the classifier.
 526  
          * 
 527  
          * @return an array of strings suitable for passing to setOptions
 528  
          */
 529  
         public String[] getOptions() {
 530  0
                 String[] options = new String[13];
 531  0
                 int current = 0;
 532  0
                 if (m_bGenerateNet) {
 533  0
                   options[current++] = "-B";
 534  
                 } 
 535  
 
 536  0
                 options[current++] = "-N";
 537  0
                 options[current++] = "" + m_nNrOfNodes;
 538  
 
 539  0
                 options[current++] = "-A";
 540  0
                 options[current++] = "" + m_nNrOfArcs;
 541  
 
 542  0
                 options[current++] = "-M";
 543  0
                 options[current++] = "" + m_nNrOfInstances;
 544  
 
 545  0
                 options[current++] = "-C";
 546  0
                 options[current++] = "" + m_nCardinality;
 547  
 
 548  0
                 options[current++] = "-S";
 549  0
                 options[current++] = "" + m_nSeed;
 550  
 
 551  0
                 if (m_sBIFFile.length() != 0) {
 552  0
                   options[current++] = "-F";
 553  0
                   options[current++] = "" + m_sBIFFile;
 554  
                 }
 555  
 
 556  
                 // Fill up rest with empty strings, not nulls!
 557  0
                 while (current < options.length) {
 558  0
                         options[current++] = "";
 559  
                 }
 560  
 
 561  0
                 return options;
 562  
         } // getOptions
 563  
 
 564  
     /**
 565  
      * prints all the options to stdout
 566  
      */
 567  
     protected static void printOptions(OptionHandler o) {
 568  0
       Enumeration enm = o.listOptions();
 569  
       
 570  0
       System.out.println("Options for " + o.getClass().getName() + ":\n");
 571  
       
 572  0
       while (enm.hasMoreElements()) {
 573  0
         Option option = (Option) enm.nextElement();
 574  0
         System.out.println(option.synopsis());
 575  0
         System.out.println(option.description());
 576  0
       }
 577  0
     }
 578  
     
 579  
     /**
 580  
      * Returns the revision string.
 581  
      * 
 582  
      * @return                the revision
 583  
      */
 584  
     public String getRevision() {
 585  0
       return RevisionUtils.extract("$Revision: 8034 $");
 586  
     }
 587  
 
 588  
     /**
 589  
      * Main method
 590  
      * 
 591  
      * @param args the commandline parameters
 592  
      */
 593  
     static public void main(String [] args) {
 594  0
                 BayesNetGenerator b = new BayesNetGenerator();
 595  
             try {
 596  0
                 if ( (args.length == 0) || (Utils.getFlag('h', args)) ) {
 597  0
                         printOptions(b);
 598  0
                         return;
 599  
                 }
 600  0
                     b.setOptions(args);
 601  
                     
 602  0
                     b.generateRandomNetwork();
 603  0
                     if (!b.m_bGenerateNet) { // skip if not required
 604  0
                                 b.generateInstances();
 605  
                     }
 606  0
                     System.out.println(b.toString());
 607  0
             } catch (Exception e) {
 608  0
                     e.printStackTrace();
 609  0
                     printOptions(b);
 610  0
             }
 611  0
     } // main
 612  
     
 613  
 } // class BayesNetGenerator