public FilteredDimensionIndexCombinationGenerator(DimensionIndexCombinationGenerator underlyingGenerator, Func<ReadOnlyCollection<int>, bool> filter) { if (underlyingGenerator == null) { throw new ArgumentNullException("underlyingGenerator"); } if (filter == null) { throw new ArgumentNullException("filter"); } _underlyingGenerator = underlyingGenerator; _filter = filter; }
private DimensionIndexCombinationGenerator CreateDimensionIndexCombinationGenerator(ReadOnlyCollection <DimensionWithValues> dimensionValues) { return(DimensionIndexCombinationGenerator.Create(dimensionValues.Count, _order, _extendedCoverageDimensionSubsets.Select(s => Tuple.Create( s.Item1.Select(d => GetIndexOfDimension(d, dimensionValues, "ExtendedCoverageDimensionSubsets")).ToList().AsReadOnly(), s.Item2 ) ), _noCoverageGuaranteeDimensions.Select(d => GetIndexOfDimension(d, dimensionValues, "NoCoverageGuaranteeDimensions") ) )); }
public TranslatedDimensionIndexCombinationGenerator(DimensionIndexCombinationGenerator underlyingGenerator, ReadOnlyCollection<int> translatedIndexes) { if (underlyingGenerator == null) { throw new ArgumentNullException("underlyingGenerator"); } if (translatedIndexes == null) { throw new ArgumentNullException("translatedIndexes"); } _underlyingGenerator = underlyingGenerator; _translatedIndexes = translatedIndexes; }
public TranslatedDimensionIndexCombinationGenerator(DimensionIndexCombinationGenerator underlyingGenerator, ReadOnlyCollection <int> translatedIndexes) { if (underlyingGenerator == null) { throw new ArgumentNullException("underlyingGenerator"); } if (translatedIndexes == null) { throw new ArgumentNullException("translatedIndexes"); } _underlyingGenerator = underlyingGenerator; _translatedIndexes = translatedIndexes; }
public FilteredDimensionIndexCombinationGenerator(DimensionIndexCombinationGenerator underlyingGenerator, Func <ReadOnlyCollection <int>, bool> filter) { if (underlyingGenerator == null) { throw new ArgumentNullException("underlyingGenerator"); } if (filter == null) { throw new ArgumentNullException("filter"); } _underlyingGenerator = underlyingGenerator; _filter = filter; }
/// <summary> /// Adds all the combinations of the given order as covered. /// </summary> /// <param name="combination">The combination to cover.</param> /// <param name="dimensionIndexGenerator">The dimension index generator to use for getting all dimension index combinations we care about.</param> public void AddCoveredPairwiseCombinations(DimensionValueIndexCombination combination, DimensionIndexCombinationGenerator dimensionIndexGenerator) { foreach (ReadOnlyCollection <int> dimensionsOfInterest in dimensionIndexGenerator.Generate()) { if (!IsCombinationCovered(dimensionsOfInterest, combination)) { _coveredCombinations.Add(EncodeCombination(dimensionsOfInterest, combination)); } } }
/// <summary> /// Explores the input (sub-)space. Each invocation may return a different set. /// </summary> /// <returns> /// A (reasonably-sized) stream of vectors/values from the (sub-)space. /// </returns> public override IEnumerable <Vector> Explore() { if (TargetMatrix.Dimensions.Count == 0) { // No dimensions to explore, then yield one empty vector. yield return(new Vector()); yield break; } ReadOnlyCollection <DimensionWithValues> dimensionValues = GetAllDimensionValues(); if (dimensionValues.Any(dim => dim.Values.Count == 0)) { yield break; // One of the dimensions is empty } if (dimensionValues.Count < _order) { // This is really non-sensical to ask for an n-wise strategy for a matrix with less than n dimensions // but I'd rather return a good default than throw. So I'll just cheat and do an exhaustive strategy instead ExhaustiveCombinatorialStrategy exhaustiveStrategy = new ExhaustiveCombinatorialStrategy(this); foreach (Vector v in exhaustiveStrategy.Explore()) { yield return(v); } yield break; } CoveredPairwiseCombinations coveredCombinations = new CoveredPairwiseCombinations(); DimensionValueIndexCombination currentCombination = new DimensionValueIndexCombination(dimensionValues); DimensionIndexCombinationGenerator dimensionIndexGenerator = CreateDimensionIndexCombinationGenerator(dimensionValues); Vector currentVector = currentCombination.GenerateVector(); if (IsValidVector(currentVector)) { coveredCombinations.AddCoveredPairwiseCombinations(currentCombination, dimensionIndexGenerator); yield return(currentVector); } PartialVectorConstraintChecker partialConstraintChecker = UsePartialConstraintChecker ? new PartialVectorConstraintChecker(dimensionValues, Constraints) : null; foreach (ReadOnlyCollection <int> currentDimensionsToCover in dimensionIndexGenerator.Generate()) { // Initialize the selection of values in the newly selected pairwise combination for (int i = 0; i < currentDimensionsToCover.Count; i++) { currentCombination[currentDimensionsToCover[i]] = 0; } while (true) { bool selectionSucceeded = SelectNextValuesForCurrentDimensionCombination(currentCombination, currentDimensionsToCover); if (!selectionSucceeded) { // We exhausted all combinations of values for the current pairwise combination // select the next pairwise combination break; } if (coveredCombinations.IsCombinationCovered(currentDimensionsToCover, currentCombination)) { continue; } if (partialConstraintChecker != null && !partialConstraintChecker.IsValidForApplicableConstraints(currentCombination, currentDimensionsToCover)) { // This combination is forbidden by constraints - carry on continue; } // Randomize other values, try at most MAXTRIES since we might hit invalid combinations for (int i = 0; i < MAXTRIES; i++) { List <int> remainingDimensionIndexes = Enumerable.Range(0, dimensionValues.Count) .Where(di => !currentDimensionsToCover.Contains(di)) // Don't randomize the pair currently worked on .ToList(); RandomUtilities.ShuffleList(remainingDimensionIndexes, _nextInt); List <int> setDimensionIndexes = new List <int>(currentDimensionsToCover); foreach (int dimensionIndex in remainingDimensionIndexes) { ReadOnlyCollection <int> allowedValueIndexes = UsePartialConstraintChecker ? partialConstraintChecker.GetAllowedValueIndexesForDimension(dimensionIndex, setDimensionIndexes, currentCombination) : Enumerable.Range(0, currentCombination.GetDimensionSize(dimensionIndex)).ToList().AsReadOnly(); if (allowedValueIndexes.Count == 0) { break; } currentCombination[dimensionIndex] = allowedValueIndexes[_nextInt(allowedValueIndexes.Count)]; setDimensionIndexes.Add(dimensionIndex); } if (setDimensionIndexes.Count < dimensionValues.Count) { // Couldn't set all dimension values, try again (or quit) continue; } currentVector = currentCombination.GenerateVector(); if (partialConstraintChecker != null || IsValidVector(currentVector)) { coveredCombinations.AddCoveredPairwiseCombinations(currentCombination, dimensionIndexGenerator); yield return(currentVector); break; // Out of the MAXTRIES loop } } } } }
/// <summary> /// Adds all the combinations of the given order as covered. /// </summary> /// <param name="combination">The combination to cover.</param> /// <param name="dimensionIndexGenerator">The dimension index generator to use for getting all dimension index combinations we care about.</param> public void AddCoveredPairwiseCombinations(DimensionValueIndexCombination combination, DimensionIndexCombinationGenerator dimensionIndexGenerator) { foreach (ReadOnlyCollection<int> dimensionsOfInterest in dimensionIndexGenerator.Generate()) { if (!IsCombinationCovered(dimensionsOfInterest, combination)) _coveredCombinations.Add(EncodeCombination(dimensionsOfInterest, combination)); } }