private void GenerateCliques(int[] variableSizes, IList <int> startSet, ICollection <int> alreadyRepresented, GraphicalModel model, SourceOfRandomness randomness) { if (alreadyRepresented.Count == variableSizes.Length) { return; } // Generate the clique variable set IList <int> cliqueContents = new List <int>(); Sharpen.Collections.AddAll(cliqueContents, startSet); Sharpen.Collections.AddAll(alreadyRepresented, startSet); while (true) { if (alreadyRepresented.Count == variableSizes.Length) { break; } if (cliqueContents.Count == 0 || randomness.NextDouble(0, 1) < 0.7) { int gen; do { gen = randomness.NextInt(variableSizes.Length); }while (alreadyRepresented.Contains(gen)); alreadyRepresented.Add(gen); cliqueContents.Add(gen); } else { break; } } // Create the actual table int[] neighbors = new int[cliqueContents.Count]; int[] neighborSizes = new int[neighbors.Length]; for (int j = 0; j < neighbors.Length; j++) { neighbors[j] = cliqueContents[j]; neighborSizes[j] = variableSizes[neighbors[j]]; } ConcatVectorTable table = new ConcatVectorTable(neighborSizes); foreach (int[] assignment in table) { // Generate a vector ConcatVector v = new ConcatVector(ConcatVecComponents); for (int x = 0; x < ConcatVecComponents; x++) { if (randomness.NextBoolean()) { v.SetSparseComponent(x, randomness.NextInt(32), randomness.NextDouble()); } else { double[] val = new double[randomness.NextInt(12)]; for (int y = 0; y < val.Length; y++) { val[y] = randomness.NextDouble(); } v.SetDenseComponent(x, val); } } // set vec in table table.SetAssignmentValue(assignment, null); } model.AddFactor(table, neighbors); // Pick the number of children IList <int> availableVariables = new List <int>(); Sharpen.Collections.AddAll(availableVariables, cliqueContents); availableVariables.RemoveAll(startSet); int numChildren = randomness.NextInt(0, availableVariables.Count); if (numChildren == 0) { return; } IList <IList <int> > children = new List <IList <int> >(); for (int i = 0; i < numChildren; i++) { children.Add(new List <int>()); } // divide up the shared variables across the children int cursor = 0; while (true) { if (availableVariables.Count == 0) { break; } if (children[cursor].Count == 0 || randomness.NextBoolean()) { int gen = randomness.NextInt(availableVariables.Count); children[cursor].Add(availableVariables[gen]); availableVariables.Remove(availableVariables[gen]); } else { break; } cursor = (cursor + 1) % numChildren; } foreach (IList <int> shared1 in children) { foreach (int i_1 in shared1) { foreach (IList <int> shared2 in children) { System.Diagnostics.Debug.Assert((shared1 == shared2 || !shared2.Contains(i_1))); } } } foreach (IList <int> shared in children) { if (shared.Count > 0) { GenerateCliques(variableSizes, shared, alreadyRepresented, model, randomness); } } }