void generateRandomDistributions(int nNodes, int nValues) {
	    // Reserve space for CPTs
    	int nMaxParentCardinality = 1;
	    for (int iAttribute = 0; iAttribute < nNodes; iAttribute++) {
            if (m_ParentSets[iAttribute].getCardinalityOfParents() > nMaxParentCardinality) {
	             nMaxParentCardinality = m_ParentSets[iAttribute].getCardinalityOfParents();
            } 
        } 

        // Reserve plenty of memory
        m_Distributions = new Estimator[m_Instances.numAttributes()][nMaxParentCardinality];

        // estimate CPTs
        for (int iAttribute = 0; iAttribute < nNodes; iAttribute++) {
        	int [] nPs = new int [nValues + 1];
        	nPs[0] = 0;
        	nPs[nValues] = 1000;
            for (int iParent = 0; iParent < m_ParentSets[iAttribute].getCardinalityOfParents(); iParent++) {
            	// fill array with random nr's
            	for (int iValue = 1; iValue < nValues; iValue++)  {
            		nPs[iValue] = random.nextInt(1000);
            	}
            	// sort
            	for (int iValue = 1; iValue < nValues; iValue++)  {
	            	for (int iValue2 = iValue + 1; iValue2 < nValues; iValue2++)  {
	            		if (nPs[iValue2] < nPs[iValue]) {
	            			int h = nPs[iValue2]; nPs[iValue2] = nPs[iValue]; nPs[iValue] = h;
	            		}
	            	}
            	}
            	// assign to probability tables
            	DiscreteEstimatorBayes d = new DiscreteEstimatorBayes(nValues, getEstimator().getAlpha());
            	for (int iValue = 0; iValue < nValues; iValue++)  {
            		d.addValue(iValue, nPs[iValue + 1] - nPs[iValue]);
            	}
	            m_Distributions[iAttribute][iParent] = d;
            } 
        } 
    } // GenerateRandomDistributions