/// <summary> /// Renders a overlay effect /// </summary> /// <param name="cameraInfo"></param> public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { base.RenderOverlay(cameraInfo); if (m_mouseTerrainPosition.HasValue) { m_action?.OnRenderOverlay(cameraInfo, m_mouseTerrainPosition.Value); } if (m_distribution != null) { DistributionUtils.RenderSegments(cameraInfo, ColorConstants.SelectionColor, m_distribution.Road); } }
/// <summary> /// This method selects a given number of configurations by using the sample mechanism of the CSP solver. /// </summary> /// <returns>A set of configurations that have been picked to fit the given distribution.</returns> /// <param name="wantedDistribution">The wanted distribution of the samples.</param> /// <param name="allBuckets">The buckets containing at least one configuration.</param> /// <param name="count">The number of configurations to select.</param> /// <param name="optimization">The optimization to use</param> public List <Configuration> SampleFromDistribution(Dictionary <double, double> wantedDistribution, List <double> allBuckets, int count, List <BinaryOption> desiredOptions, Optimization optimization = Optimization.NONE) { wantedDistribution = new Dictionary <double, double>(wantedDistribution); Random rand = new Random(seed); List <Configuration> selectedConfigurations = new List <Configuration>(); Dictionary <int, Configuration> selectedConfigurationsFromBucket = new Dictionary <int, Configuration>(); for (int i = 0; i < allBuckets.Count; i++) { selectedConfigurationsFromBucket[i] = null; } // Create and initialize the weight function Dictionary <int, Dictionary <List <BinaryOption>, int> > featureWeight = new Dictionary <int, Dictionary <List <BinaryOption>, int> >(); if (optimization == Optimization.GLOBAL) { if (this.featureRange.Item1 != 0 && this.featureRange.Item2 != 0) { featureWeight.Add(0, InitializeWeightDict(GlobalState.varModel)); } else { featureWeight.Add(0, new Dictionary <List <BinaryOption>, int>()); } existingConfigurations.ForEach(config => { ConfigurationBuilder.vg.AddConstraint(GlobalState.varModel, config, config.getBinaryOptions(BinaryOption.BinaryValue.Selected).Count); UpdateWeights(GlobalState.varModel, featureWeight[0], config); }); } else if (optimization == Optimization.LOCAL) { for (int i = 0; i < allBuckets.Count; i++) { if (this.featureRange.Item1 != 0 && this.featureRange.Item2 != 0) { featureWeight.Add(i, InitializeWeightDict(GlobalState.varModel)); } else { featureWeight.Add(i, new Dictionary <List <BinaryOption>, int>()); } existingConfigurations.ForEach(config => { ConfigurationBuilder.vg.AddConstraint(GlobalState.varModel, config, config.getBinaryOptions(BinaryOption.BinaryValue.Selected).Count); UpdateWeights(GlobalState.varModel, featureWeight[0], config); }); } } bool[] noSamples = new bool[allBuckets.Count]; Dictionary <double, int> sampleSetFrequency = makeFrequencyMap(existingConfigurations, wantedDistribution.Keys); while (selectedConfigurations.Count < count && HasSamples(noSamples)) { double randomDouble = rand.NextDouble(); double currentProbability = 0; int currentBucket = 0; while (randomDouble > currentProbability + wantedDistribution.ElementAt(currentBucket).Value) { currentProbability += wantedDistribution.ElementAt(currentBucket).Value; currentBucket++; } // Note: This method works only for binary features and therefore, only integer buckets int distanceOfBucket = Convert.ToInt32(wantedDistribution.ElementAt(currentBucket).Key); sampleSetFrequency[distanceOfBucket] -= 1; if (sampleSetFrequency[distanceOfBucket] > 0) { continue; } // Repeat if there are currently no solutions in the bucket. // This is intended to reduce the work of the solver. // Should not happen anymore! if (noSamples[currentBucket] || !allBuckets.Contains(distanceOfBucket)) { throw new InvalidProgramException("A bucket was selected that already contains no more samples! This shouldn't happen."); } if (ConfigurationBuilder.vg is Solver.Z3VariantGenerator) { ((Solver.Z3VariantGenerator)ConfigurationBuilder.vg).setSeed(Convert.ToUInt32(this.seed)); } List <BinaryOption> solution = null; // Now select the configuration by using the solver if (optimization == Optimization.NONE) { solution = ConfigurationBuilder.vg.GenerateConfigurationFromBucket(GlobalState.varModel, distanceOfBucket, null, desiredOptions); } else if (optimization == Optimization.GLOBAL) { solution = ConfigurationBuilder.vg.GenerateConfigurationFromBucket(GlobalState.varModel, distanceOfBucket, featureWeight[0], desiredOptions); } else if (optimization == Optimization.LOCAL) { solution = ConfigurationBuilder.vg.GenerateConfigurationFromBucket(GlobalState.varModel, distanceOfBucket, featureWeight[currentBucket], desiredOptions); } // If a bucket was selected that now contains no more configurations, repeat the procedure if (solution == null) { // TODO maybe optimize performance: additionally sample configuration from bucket to check if there are any more configurations in the bucket noSamples[currentBucket] = true; // As a consequence, the probability to pick this bucket is set to 0 and the whole // distribution is readjusted so that the sum of all probabilities is equal to 1 (i.e., 100%). wantedDistribution[wantedDistribution.ElementAt(currentBucket).Key] = 0d; wantedDistribution = DistributionUtils.AdjustToOne(wantedDistribution); continue; } Configuration currentSelectedConfiguration = new Configuration(solution); ConfigurationBuilder.vg.AddConstraint(GlobalState.varModel, currentSelectedConfiguration, distanceOfBucket); selectedConfigurations.Add(currentSelectedConfiguration); selectedConfigurationsFromBucket[currentBucket] = currentSelectedConfiguration; if (optimization == Optimization.GLOBAL) { UpdateWeights(GlobalState.varModel, featureWeight[0], currentSelectedConfiguration); } else if (optimization == Optimization.LOCAL) { UpdateWeights(GlobalState.varModel, featureWeight[currentBucket], currentSelectedConfiguration); } } if (selectedConfigurations.Count < count && (desiredOptions == null || desiredOptions.Count == 0)) { GlobalState.logError.logLine("Sampled only " + selectedConfigurations.Count + " configurations as there are no more configurations."); } return(selectedConfigurations); }