private static IValueGenerator[] ConvertToValueGenerators(IEnumerable <SweepableParam> hps) { var results = new IValueGenerator[hps.Count()]; for (int i = 0; i < hps.Count(); i++) { switch (hps.ElementAt(i)) { case SweepableDiscreteParam dp: var dpArgs = new DiscreteParamArguments() { Name = dp.Name, Values = dp.Options.Select(o => o.ToString()).ToArray() }; results[i] = new DiscreteValueGenerator(dpArgs); break; case SweepableFloatParam fp: var fpArgs = new FloatParamArguments() { Name = fp.Name, Min = fp.Min, Max = fp.Max, LogBase = fp.IsLogScale, }; if (fp.NumSteps.HasValue) { fpArgs.NumSteps = fp.NumSteps.Value; } if (fp.StepSize.HasValue) { fpArgs.StepSize = fp.StepSize.Value; } results[i] = new FloatValueGenerator(fpArgs); break; case SweepableLongParam lp: var lpArgs = new LongParamArguments() { Name = lp.Name, Min = lp.Min, Max = lp.Max, LogBase = lp.IsLogScale }; if (lp.NumSteps.HasValue) { lpArgs.NumSteps = lp.NumSteps.Value; } if (lp.StepSize.HasValue) { lpArgs.StepSize = lp.StepSize.Value; } results[i] = new LongValueGenerator(lpArgs); break; } } return(results); }
/// <summary> /// Computes a single-mutation neighborhood (one parameter at a time) for a given configuration. For /// numeric parameters, samples K mutations (i.e., creates K neighbors based on that parameter). /// </summary> /// <param name="parent">Starting configuration.</param> /// <returns>A set of configurations that each differ from parent in exactly one parameter.</returns> private ParameterSet[] GetOneMutationNeighborhood(ParameterSet parent) { List <ParameterSet> neighbors = new List <ParameterSet>(); SweeperProbabilityUtils spu = new SweeperProbabilityUtils(); for (int i = 0; i < _sweepParameters.Length; i++) { // This allows us to query possible values of this parameter. IValueGenerator sweepParam = _sweepParameters[i]; // This holds the actual value for this parameter, chosen in this parameter set. IParameterValue pset = parent[sweepParam.Name]; Runtime.Contracts.Assert(pset != null); DiscreteValueGenerator parameterDiscrete = sweepParam as DiscreteValueGenerator; if (parameterDiscrete != null) { // Create one neighbor for every discrete parameter. Float[] neighbor = SweeperProbabilityUtils.ParameterSetAsFloatArray(_sweepParameters, parent, false); int hotIndex = -1; for (int j = 0; j < parameterDiscrete.Count; j++) { if (parameterDiscrete[j].Equals(pset)) { hotIndex = j; break; } } Runtime.Contracts.Assert(hotIndex >= 0); Random r = new Random(); int randomIndex = r.Next(0, parameterDiscrete.Count - 1); randomIndex += randomIndex >= hotIndex ? 1 : 0; neighbor[i] = randomIndex; neighbors.Add(SweeperProbabilityUtils.FloatArrayAsParameterSet(_sweepParameters, neighbor, false)); } else { INumericValueGenerator parameterNumeric = sweepParam as INumericValueGenerator; Runtime.Contracts.Assert(parameterNumeric != null, "SMAC sweeper can only sweep over discrete and numeric parameters"); // Create k neighbors (typically 4) for every numerical parameter. for (int j = 0; j < _args.NumNeighborsForNumericalParams; j++) { Float[] neigh = SweeperProbabilityUtils.ParameterSetAsFloatArray(_sweepParameters, parent, false); double newVal = spu.NormalRVs(1, neigh[i], 0.2)[0]; while (newVal <= 0.0 || newVal >= 1.0) { newVal = spu.NormalRVs(1, neigh[i], 0.2)[0]; } neigh[i] = (Float)newVal; ParameterSet neighbor = SweeperProbabilityUtils.FloatArrayAsParameterSet(_sweepParameters, neigh, false); neighbors.Add(neighbor); } } } return(neighbors.ToArray()); }