public static VariabilityModel loadOptionalVM() { string optionalVm = "<vm name=\"test\">" + "<numericOptions>" + "<configurationOption>" + "<name>opt</name>" + "<minValue>0</minValue>" + "<maxValue>50</maxValue>" + "<deselectedFlag>-1</deselectedFlag>" + "<stepFunction>opt + 10</stepFunction>" + "</configurationOption>" + "</numericOptions>" + "</vm>"; string vmName = Path.GetTempPath() + "optional_" + DateTime.Now.ToShortTimeString().Replace(":", "-") + ".xml"; StreamWriter sr = new StreamWriter(vmName); sr.Write(optionalVm); sr.Flush(); sr.Close(); VariabilityModel withOptional = VariabilityModel.loadFromXML(vmName); File.Delete(vmName); return(withOptional); }
public List <List <BinaryOption> > GenerateRLinear(VariabilityModel vm, int treshold, int timeout, BackgroundWorker worker) { List <List <BinaryOption> > erglist = new List <List <BinaryOption> >(); var tasks = new Task[vm.BinaryOptions.Count]; var mylock = new object(); for (var i = 1; i <= vm.BinaryOptions.Count; i++) { var i1 = i; tasks[i - 1] = Task.Factory.StartNew(() => { var size = LinearSize(vm.BinaryOptions.Count, treshold, i1); return(generateTilSize(i1, size, timeout, vm)); }).ContinueWith(task => { lock (mylock) { erglist.AddRange(task.Result); counter++; worker.ReportProgress((int)(counter * 100.0f / (double)vm.BinaryOptions.Count), erglist.Count); } }); } Task.WaitAll(tasks); return(erglist); }
/// <summary> /// This algorithm calls for each binary option in the variability model the CSP solver to generate a valid, minimal configuration containing that option. /// </summary> /// <param name="vm">The variability model for which the feature-wise configurations should be generated.</param> /// <returns>A list of configurations, in which each configuration is a list of binary options that represent the SELECTED options.</returns> public List <List <BinaryOption> > generateFeatureWiseConfigsCSP(VariabilityModel vm) { this.configurations.Clear(); Solver.VariantGenerator generator = new Solver.VariantGenerator(null); foreach (var opt in vm.BinaryOptions) { if (opt == vm.Root) { continue; } List <BinaryOption> temp = new List <BinaryOption>(); temp.Add(opt); temp = generator.minimizeConfig(temp, vm, true, null); if (temp != null && Configuration.containsBinaryConfiguration(this.configurations, temp) == false) { this.configurations.Add(temp); } //Now finding a configuration without the current option, but with all other options to be able to compute a delta List <BinaryOption> withoutOpt = new List <BinaryOption>(); BinaryOption[] tempArray = temp.ToArray(); withoutOpt = tempArray.ToList <BinaryOption>(); withoutOpt.Remove(opt); List <BinaryOption> excluded = new List <BinaryOption>(); excluded.Add(opt); withoutOpt = generator.minimizeConfig(withoutOpt, vm, true, excluded); if (withoutOpt != null && Configuration.containsBinaryConfiguration(this.configurations, withoutOpt) == false) { this.configurations.Add(withoutOpt); } } return(this.configurations); }
private static void initVM(VariabilityModel vm) { vm.addConfigurationOption(new BinaryOption(vm, "testOption1")); vm.addConfigurationOption(new BinaryOption(vm, "testOption2")); vm.addConfigurationOption(new NumericOption(vm, "testOption3")); vm.addConfigurationOption(new NumericOption(vm, "testOption4")); }
private List <List <BinaryOption> > SelectRelativeInteractions(int order, double relativeNumber) { VariabilityModel vm = _model.Vm; List <List <BinaryOption> > allInteractions = new BinaryOptionAllInteractionGenerator().GenerateAllInteractions(_model.Vm, order); int amount = (int)Math.Round(allInteractions.Count * relativeNumber, 0); if (amount > allInteractions.Count) { return(allInteractions); } else { Random Rand = (_model.hasRandomSeed) ? new Random(_model.RandomSeed) : new Random(); List <List <BinaryOption> > selectedInteractions = new List <List <BinaryOption> >(); List <int> indices = new List <int>(); for (int i = 0; i < amount; i++) { int index = Rand.Next(allInteractions.Count); while (indices.Contains(index)) { index = Rand.Next(allInteractions.Count); } indices.Add(index); selectedInteractions.Add(allInteractions.ElementAt(index)); } return(selectedInteractions); } }
public void TestConfigurationPositiv() { VariabilityModel vm = new VariabilityModel("test"); initVM(vm); GlobalState.varModel = vm; Dictionary <NFProperty, double> measuredValuesFirst = new Dictionary <NFProperty, double>(); measuredValuesFirst.Add(GlobalState.getOrCreateProperty("test"), 2); Dictionary <NFProperty, double> measuredValuesSecond = new Dictionary <NFProperty, double>(); measuredValuesSecond.Add(GlobalState.getOrCreateProperty("test"), 3); Dictionary <BinaryOption, BinaryOption.BinaryValue> binaryOptionsFirst = new Dictionary <BinaryOption, BinaryOption.BinaryValue>(); fillUpBinaryOptions(binaryOptionsFirst, vm); Dictionary <BinaryOption, BinaryOption.BinaryValue> binaryOptionsSecond = new Dictionary <BinaryOption, BinaryOption.BinaryValue>(); fillUpBinaryOptions(binaryOptionsSecond, vm); Dictionary <NumericOption, double> numericOptionsFirst = new Dictionary <NumericOption, double>(); fillUpNumericOptions(numericOptionsFirst, vm); Dictionary <NumericOption, double> numericOptionsSecond = new Dictionary <NumericOption, double>(); fillUpNumericOptions(numericOptionsSecond, vm); Configuration configFirst = new Configuration(binaryOptionsFirst, numericOptionsFirst, measuredValuesFirst); Configuration configSecond = new Configuration(binaryOptionsSecond, numericOptionsSecond, measuredValuesSecond); Assert.AreEqual(configFirst, configSecond); }
/// <summary> /// Invokes if the 'File -> Load model'-option in the menu strip was clicked. /// /// This will open a dialog to determine which model should be loaded. /// </summary> /// <param name="sender">Sender</param> /// <param name="e">Event</param> private void loadModelToolStripMenuItem_Click(object sender, EventArgs e) { if (!dataSaved && handleUnsavedData() == DialogResult.Cancel) { return; } OpenFileDialog pfd = new OpenFileDialog(); pfd.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; if (pfd.ShowDialog() == DialogResult.OK) { System.IO.FileInfo fi = new FileInfo(pfd.FileName); GlobalState.varModel = VariabilityModel.loadFromXML(fi.FullName); this.saveModelToolStripMenuItem.Enabled = true; this.saveModelAsToolStripMenuItem.Enabled = true; this.editToolStripMenuItem.Enabled = true; this.addAlternativeGroupToolStripMenuItem.Enabled = true; currentFilePath = fi.FullName; dataSaved = true; InitTreeView(); } }
private static void createConfigurationsOptNumeric(VariabilityModel vm, List <List <BinaryOption> > binaryParts, List <Dictionary <NumericOption, Double> > numericParts, List <Configuration> results) { IEnumerable <NumericOption> optionalOptions = vm.NumericOptions.Where(x => x.Optional); foreach (List <BinaryOption> binConfig in binaryParts) { // Get all abstract binary options var abstractOptions = binConfig.Where(x => x.IsStrictlyAbstract); // get all currently deselected numeric options List <NumericOption> currentDeselected = optionalOptions .Where(x => !abstractOptions.Contains(x.abstractEnabledConfigurationOption())).ToList(); currentDeselected.ForEach(x => binConfig.Add(x.abstractDisabledConfigurationOption())); List <String> alreadyAdded = new List <String>(); foreach (Dictionary <NumericOption, double> numConf in numericParts) { Dictionary <NumericOption, double> buff = new Dictionary <NumericOption, double>(); numConf.ToList().ForEach(x => { buff[x.Key] = currentDeselected.Contains(x.Key) ? x.Key.OptionalFlag : x.Value; }); var selectedPart = String.Join(";", buff.Select(x => x.Value)); if (!alreadyAdded.Contains(selectedPart)) { alreadyAdded.Add(selectedPart); } else { continue; } Configuration c = new Configuration(binConfig, buff); results.Add(c); } } }
private void initializeArbitraryBooleanConstraints(Cplex cplex, VariabilityModel vm, Dictionary <BinaryOption, INumVar> optsToCplex) { foreach (string booleanConstraint in vm.BinaryConstraints) { string[] cnfParts = booleanConstraint.Split('&'); foreach (string cnfPart in cnfParts) { string[] variables = cnfPart.Split('|'); INumExpr[] logicOrConstr = new INumExpr[variables.Length]; for (int i = 0; i < variables.Length; i++) { string var = variables[i].Trim(); // In binary domain (1 - x) equals the negation of x if (var.StartsWith("!") || var.StartsWith("-")) { logicOrConstr[i] = cplex.Sum(1, cplex.Negative((optsToCplex[vm.getBinaryOption(var.Substring(1))]))); } else { logicOrConstr[i] = optsToCplex[vm.getBinaryOption(var)]; } } // Since we use cnf notation, it is enough to check if the sum of a single clause is // greater or equal 1 cplex.AddGe(cplex.Sum(logicOrConstr), one); } } }
/// <summary> /// Checks whether the boolean selection is valid w.r.t. the variability model. Does not check for numeric options' correctness. /// </summary> /// <param name="config">The list of binary options that are SELECTED (only selected options must occur in the list).</param> /// <param name="vm">The variability model that represents the context of the configuration.</param> /// <param name="partialConfiguration">Whether the given list of options represents only a partial configuration. This means that options not in config might be additionally select to obtain a valid configuration.</param> /// <returns>True if it is a valid selection w.r.t. the VM, false otherwise</returns> public bool checkConfigurationSAT(List <BinaryOption> config, VariabilityModel vm, bool partialConfiguration) { List <CspTerm> variables = new List <CspTerm>(); Dictionary <BinaryOption, CspTerm> elemToTerm = new Dictionary <BinaryOption, CspTerm>(); Dictionary <CspTerm, BinaryOption> termToElem = new Dictionary <CspTerm, BinaryOption>(); ConstraintSystem S = CSPsolver.getConstraintSystem(out variables, out elemToTerm, out termToElem, vm); //Feature Selection foreach (BinaryOption binayOpt in elemToTerm.Keys) { CspTerm term = elemToTerm[binayOpt]; if (config.Contains(binayOpt)) { S.AddConstraints(S.Implies(S.True, term)); } else if (!partialConfiguration) { S.AddConstraints(S.Implies(S.True, S.Not(term))); } } ConstraintSolverSolution sol = S.Solve(); if (sol.HasFoundSolution) { return(true); } else { return(false); } }
/// <summary> /// Starts the python process by sending the learner configurations. /// Then sends the configurations that are used to train the learner and the configurations that should be used for prediction by /// the learner. /// At last sends the task that should be performed(learning or parameter tuning). /// This has to be performed before requesting results and can only be done once per lifetime of the process. /// </summary> /// <param name="configsLearn">Path to the file that constains the configurations used for learning.</param> /// <param name="configsPredict">Path to the file that constains the configurations used for prediction.</param> /// <param name="nfpLearn">Path to the file that contains the nfp values that belong to the learning set.</param> /// <param name="nfpPredict">Path to the file that contains the nfp vlaues that belong to the prediction set.</param> /// <param name="task">Task that should be performed by the learner. Can either be parameter tuning /// or learning.</param> /// <param name="model">Model that contains all the configuration options.</param> public void setupApplication(string configsLearn, string nfpLearn, string configsPredict, string nfpPredict, string task, VariabilityModel model) { if (AWAITING_SETTINGS.Equals(waitForNextReceivedLine())) { initializeLearning(this.mlProperties); if (AWAITING_CONFIGS.Equals(waitForNextReceivedLine())) { passLineToApplication(configsLearn + " " + nfpLearn); while (!waitForNextReceivedLine().Equals(PASS_OK)) { ; } passLineToApplication(configsPredict + " " + nfpPredict); while (!waitForNextReceivedLine().Equals(PASS_OK)) { ; } List <string> opts = new List <string>(); model.BinaryOptions.ForEach(opt => opts.Add(opt.Name)); model.NumericOptions.ForEach(opt => opts.Add(opt.Name)); passLineToApplication(string.Join(",", opts)); while (!waitForNextReceivedLine().Equals(PASS_OK)) { ; } passLineToApplication(task); } } }
/// <summary> /// Generates up to n valid binary combinations of all binary configuration options in the given model. /// In case n < 0 all valid binary combinations will be generated. /// </summary> /// <param name="m">The variability model containing the binary options and their constraints.</param> /// <param name="n">The maximum number of samples that will be generated.</param> /// <returns>Returns a list of configurations, in which a configuration is a list of SELECTED binary options (deselected options are not present)</returns> public List <List <BinaryOption> > GenerateUpToNFast(VariabilityModel m, int n) { List <List <BinaryOption> > configurations = new List <List <BinaryOption> >(); List <CspTerm> variables = new List <CspTerm>(); Dictionary <BinaryOption, CspTerm> elemToTerm = new Dictionary <BinaryOption, CspTerm>(); Dictionary <CspTerm, BinaryOption> termToElem = new Dictionary <CspTerm, BinaryOption>(); ConstraintSystem S = CSPsolver.getConstraintSystem(out variables, out elemToTerm, out termToElem, m); ConstraintSolverSolution soln = S.Solve(); // TODO: Better solution than magic number? while (soln.HasFoundSolution && (configurations.Count < n || n < 0)) { List <BinaryOption> config = new List <BinaryOption>(); foreach (CspTerm cT in variables) { if (soln.GetIntegerValue(cT) == 1) { config.Add(termToElem[cT]); } } //THese should always be new configurations // if(!Configuration.containsBinaryConfiguration(configurations, config)) configurations.Add(config); soln.GetNext(); } return(configurations); }
private void generatePowerSet(VariabilityModel vm, List <BinaryOption> candidates, int t, List <List <BinaryOption> > result, int index) { if (candidates.Count == t) { candidates = ConfigurationBuilder.vg.MinimizeConfig(candidates, vm, true, null); if (candidates.Count != 0) { result.Add(candidates); } return; } for (int i = index; i < GlobalState.varModel.BinaryOptions.Count; i++) { if (candidates.Count < t) { if (!candidates.Contains(GlobalState.varModel.BinaryOptions[i])) { List <BinaryOption> newCand = new List <BinaryOption>(); newCand.AddRange(candidates); newCand.Add(GlobalState.varModel.BinaryOptions[i]); if (newOptionIsValidForCandidate(candidates, GlobalState.varModel.BinaryOptions[i])) { generatePowerSet(vm, newCand, t, result, i + 1); } } } } return; }
private void AddBinaryConfigurationsToConstraintSystem(VariabilityModel vm, ConstraintSystem s, Configuration configurationToExclude, Dictionary <BinaryOption, CspTerm> elemToTerm) { List <BinaryOption> allBinaryOptions = vm.BinaryOptions; List <CspTerm> positiveTerms = new List <CspTerm>(); List <CspTerm> negativeTerms = new List <CspTerm>(); foreach (BinaryOption binOpt in allBinaryOptions) { if (configurationToExclude.BinaryOptions.ContainsKey(binOpt) && configurationToExclude.BinaryOptions[binOpt] == BinaryOption.BinaryValue.Selected) { positiveTerms.Add(elemToTerm[binOpt]); } else { negativeTerms.Add(elemToTerm[binOpt]); } } if (negativeTerms.Count > 0) { positiveTerms.Add(s.Not(s.And(negativeTerms.ToArray()))); } s.AddConstraints(s.Not(s.And(positiveTerms.ToArray()))); }
public List <List <BinaryOption> > generateNegativeFWUntilSeconds(VariabilityModel vm, int seconds) { var cts = new CancellationTokenSource(); var task = Task.Factory.StartNew(() => { #region task this.configurations.Clear(); List <List <BinaryOption> > maxConfigs = new List <List <BinaryOption> >(); maxConfigs = getMaxConfigurations(vm, false); configurations.AddRange(maxConfigs); //Idea try to vary only the first maximum configuration by removing only a single feature //If a feature is not present in this maximum configuration, find a maximum configuration in which it is present and then remove the feature //Challenges: alternative features or mandatory features cannot be removed foreach (BinaryOption binOpt in vm.BinaryOptions) { if (binOpt.Optional == false || binOpt.hasAlternatives()) { continue; } foreach (List <BinaryOption> config in maxConfigs) { if (!config.Contains(binOpt)) { continue; } List <BinaryOption> removedElements = null; //Get a configuration without the feature based on the maximum configuration: config List <BinaryOption> configToMeasure = generator.generateConfigWithoutOption(binOpt, config, out removedElements, vm); if (configToMeasure == null) {//This didn't work, let us try to use another maximum configuration continue; } else { if (cts.IsCancellationRequested) { return(configurations); } if (!Configuration.containsBinaryConfiguration(configurations, configToMeasure)) { configurations.Add(configToMeasure); } break; } } } return(this.configurations); #endregion }, cts.Token); if (Task.WaitAny(new[] { task }, TimeSpan.FromMilliseconds(seconds * 1000)) < 0) { cts.Cancel(); } return(configurations); }
/// <summary> /// Generates all valid binary combinations of all binary configurations options in the given model /// </summary> /// <param name="vm">The variability model containing the binary options and their constraints.</param> /// <returns>Returns a list of configurations, in which a configuration is a list of SELECTED binary options (deselected options are not present)</returns> public List <List <BinaryOption> > generateAllVariantsFast(VariabilityModel vm) { List <List <BinaryOption> > configurations = new List <List <BinaryOption> >(); List <CspTerm> variables = new List <CspTerm>(); Dictionary <BinaryOption, CspTerm> elemToTerm = new Dictionary <BinaryOption, CspTerm>(); Dictionary <CspTerm, BinaryOption> termToElem = new Dictionary <CspTerm, BinaryOption>(); ConstraintSystem S = CSPsolver.getConstraintSystem(out variables, out elemToTerm, out termToElem, vm); ConstraintSolverSolution soln = S.Solve(); while (soln.HasFoundSolution) { List <BinaryOption> config = new List <BinaryOption>(); foreach (CspTerm cT in variables) { if (soln.GetIntegerValue(cT) == 1) { config.Add(termToElem[cT]); } } //THese should always be new configurations // if(!Configuration.containsBinaryConfiguration(configurations, config)) configurations.Add(config); soln.GetNext(); } return(configurations); }
public List <List <BinaryOption> > generateR1(VariabilityModel vm, int Random1Size, int timeout, BackgroundWorker worker) { //Synchrone Tasks erstellen List <List <BinaryOption> > erglist = new List <List <BinaryOption> >(); var tasks = new Task[vm.BinaryOptions.Count]; var mylock = new object(); for (var i = 1; i <= vm.BinaryOptions.Count; i++) { var i1 = i; tasks[i - 1] = Task.Factory.StartNew(() => generateTilSize(i1, Random1Size, timeout, vm)).ContinueWith(task => { lock (mylock) { erglist.AddRange(task.Result); counter++; worker.ReportProgress((int)(counter * 100.0f / (double)vm.BinaryOptions.Count), erglist.Count); } }); } Task.WaitAll(tasks); return(erglist); }
/// <summary> /// Try to find a configuration with low weight. /// </summary> /// <param name="sortedRanking">A list of binary options and their weight ordered by their weight.</param> /// <param name="cache">A sat solver cache instance that already contains the constraints of /// size and disallowed features.</param> /// <param name="vm">The variability model of the given system.</param> /// <returns>A configuration that has a small weight.</returns> public static List <BinaryOption> getSmallWeightConfig(List <KeyValuePair <List <BinaryOption>, int> > sortedRanking, Z3Cache cache, VariabilityModel vm) { KeyValuePair <List <BinaryOption>, int>[] ranking = sortedRanking.ToArray(); Microsoft.Z3.Solver solver = cache.GetSolver(); Context z3Context = cache.GetContext(); for (int i = 0; i < ranking.Length; i++) { List <BinaryOption> candidates = ranking[i].Key; solver.Push(); solver.Assert(forceFeatures(candidates, z3Context, cache.GetOptionToTermMapping())); if (solver.Check() == Status.SATISFIABLE) { Model model = solver.Model; solver.Pop(); return(Z3VariantGenerator.RetrieveConfiguration(cache.GetVariables(), model, cache.GetTermToOptionMapping())); } solver.Pop(); } return(null); }
/// <summary> /// Calculate the number of possible configurations for numeric options in a vm. /// </summary> /// <param name="vm">The variability model used.</param> /// <returns>Number of possible configurations.</returns> private static int computeNumberOfPossibleNumericVariants(VariabilityModel vm) { List <int> numberOfSteps = new List <int>(); foreach (NumericOption numOpt in vm.NumericOptions) { if (numOpt.Values != null) { numberOfSteps.Add(numOpt.Values.Count()); } else { numberOfSteps.Add((int)numOpt.getNumberOfSteps()); } } if (numberOfSteps.Count == 0) { return(numberOfSteps.Count); } else { int numberOfNumVariants = 1; numberOfSteps.ForEach(x => numberOfNumVariants *= x); return(numberOfNumVariants); } }
/// <summary> /// Creates the t-wise sampling according to the given t-value. /// </summary> /// <param name="vm">The variability model containing the binary options for which we want to generate the pair-wise configurations.</param> /// <param name="t"> The t of the t-wise</param> /// <returns>A list of configurations in which each configuration is represented by a list of SELECTED binary options</returns> public List <List <BinaryOption> > generateT_WiseVariants_new(VariabilityModel vm, int t) { List <BinaryOption> candidate = new List <BinaryOption>(); List <List <BinaryOption> > result = new List <List <BinaryOption> >(); generatePowerSet(vm, candidate, t, result, 0); //remove double entries... List <List <BinaryOption> > resultCleaned = new List <List <BinaryOption> >(); List <String> configs = new List <string>(); foreach (List <BinaryOption> options in result) { options.Sort(delegate(BinaryOption o1, BinaryOption o2) { return(o1.Name.CompareTo(o2.Name)); }); String currConfig = ""; foreach (BinaryOption binOpt in options) { currConfig = currConfig + " " + binOpt.Name; } if (!configs.Contains(currConfig)) { resultCleaned.Add(options); configs.Add(currConfig); } } return(resultCleaned); }
///<summary> /// This method searches for the most diverse set of partial configurations by sampling a high number of configurations and only /// adding samples to the resulting set if they increase the diversity. /// The parameter numberToSample should be relatively low compared /// to the number of possible partial configurations in order to ensure a high distance between configurations. /// </summary> /// <param name="vm">The domain for sampling.</param> /// <param name="minimalConfiguration">This parameter is not required for this implementation of the approach.</param> /// <param name="numberToSample">The number of configurations that should be sampled.</param> /// <param name="optionWeight">This parameter is not required for this implementation of the approach.</param> /// <returns>A list of distance maximized configurations.</returns> public List <List <BinaryOption> > DistanceMaximization(VariabilityModel vm, List <BinaryOption> minimalConfiguration, int numberToSample, int optionWeight) { Cplex plex = initCplex(vm); List <List <BinaryOption> > results = new List <List <BinaryOption> >(); // Set up a solution pool with a maximum size of numberToSample and set the replacement strategy to // replacing least diverse solutions and generate #BinaryOptions * number of wanted samples solutions plex.SetParam(Cplex.Param.MIP.Pool.Capacity, numberToSample); plex.SetParam(Cplex.Param.MIP.Pool.Intensity, 4); plex.SetParam(Cplex.Param.MIP.Pool.AbsGap, 0.0); plex.SetParam(Cplex.Param.MIP.Limits.Populate, vm.BinaryOptions.Count * numberToSample); plex.SetParam(Cplex.Param.MIP.Pool.Replace, 2); plex.Populate(); for (int i = 0; i < plex.GetSolnPoolNsolns(); i++) { List <BinaryOption> solution = new List <BinaryOption>(); foreach (BinaryOption binOpt in vm.BinaryOptions) { if (plex.GetValue(binOptsToCplexVars[binOpt], i) > EPSILON_THRESHOLD) { solution.Add(binOpt); } } results.Add(solution); } plex.Dispose(); return(results); }
private string parseToDimacs(VariabilityModel toParse) { if (toParse.NumericOptions.Count > 0 || toParse.NonBooleanConstraints.Count > 0) { throw new ArgumentException(); } StringBuilder parsedModel = new StringBuilder(); Dictionary <string, int> nameToIndex = binaryOptionsToIndex(toParse.BinaryOptions); foreach (KeyValuePair <string, int> nameAndIndex in nameToIndex) { parsedModel.Append("c " + nameAndIndex.Value + " " + nameAndIndex.Key + System.Environment.NewLine); } List <string> parsedNonOptionNonExclusive = parseNonOptionalAndNotExcluded(nameToIndex, toParse); List <string> parsedParentExpressions = parseParentExpressions(nameToIndex, toParse); List <string> parsedImplicationExpressions = parseImplicationExpressions(nameToIndex, toParse); List <string> parsedAlternativeGroupExpressions = parseAlternativeGroupExpression(nameToIndex, toParse); List <string> parsedBooleanConstraints = parseBooleanConstraint(nameToIndex, toParse); int numberOfClauses = parsedNonOptionNonExclusive.Count + parsedParentExpressions.Count + parsedImplicationExpressions.Count + parsedAlternativeGroupExpressions.Count + parsedBooleanConstraints.Count; parsedModel.Append("p cnf " + toParse.BinaryOptions.Count + " " + numberOfClauses + System.Environment.NewLine); parsedNonOptionNonExclusive.ForEach(expression => parsedModel.Append(expression)); parsedParentExpressions.ForEach(expression => parsedModel.Append(expression)); parsedImplicationExpressions.ForEach(expression => parsedModel.Append(expression)); parsedAlternativeGroupExpressions.ForEach(expression => parsedModel.Append(expression)); parsedBooleanConstraints.ForEach(expression => parsedModel.Append(expression)); return(parsedModel.ToString()); }
private void initializeMinMaxObjective(VariabilityModel vm, Cplex plex, bool minimize, List <BinaryOption> wanted, List <BinaryOption> unwanted) { INumVar[] variables = new INumVar[vm.BinaryOptions.Count]; double[] weights = new double[vm.BinaryOptions.Count]; for (int i = 0; i < vm.BinaryOptions.Count; i++) { BinaryOption curr = vm.BinaryOptions.ElementAt(i); variables[i] = binOptsToCplexVars[curr]; if (wanted != null && wanted.Contains(curr)) { weights[i] = -100.0; } else if (unwanted != null && unwanted.Contains(curr)) { weights[i] = 1000.0; } else { weights[i] = minimize ? 100.0 : -100.0; } } ILinearNumExpr weightedVariables = plex.ScalProd(variables, weights); IObjective objective = plex.Minimize(weightedVariables); plex.Add(objective); }
private void initializeNumericVariables(Cplex plex, VariabilityModel vm) { foreach (NumericOption numOpt in vm.NumericOptions) { // Initialize with the numeric options as numeric variables with a range from min to max INumVar curr = plex.NumVar(numOpt.Min_value, numOpt.Max_value, NumVarType.Float); /* plex.IfThen( * plex.Eq(binOptsToCplexVars[vm.Root], 1), * plex.Or(new IConstraint[] { plex.Ge(curr, numOpt.Min_value), * plex.Le(curr, numOpt.Max_value)} * ) * ); */ numOptsToCplexVars[numOpt] = curr; List <double> values = numOpt.getAllValues(); IConstraint[] valueSet = new IConstraint[values.Count]; // Limit the values numeric options can have to the precomputed valid values for (int i = 0; i < values.Count; i++) { valueSet[i] = plex.Eq(curr, values.ElementAt(i)); } plex.Add(plex.Or(valueSet)); } }
/// <summary> /// Parse string representation of a learning round to a LearningRound object. /// </summary> /// <param name="learningRoundAsString">LearningRound as string.</param> /// <param name="vm">Variability model the LearningRound belongs to.</param> /// <returns>LearningRound object that has the data of the string representation.</returns> public static LearningRound FromString(string learningRoundAsString, VariabilityModel vm) { LearningRound learningRound = new LearningRound(); string[] data = learningRoundAsString.Split(new char[] { ';' }); learningRound.round = int.Parse(data[0].Trim()); List<Feature> featureSetFromString = new List<Feature>(); string[] featureExpressions = data[1].Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries); foreach (string featureExpression in featureExpressions) { Feature toAdd = new Feature(featureExpression.Split(new char[] { '*' }, 2)[1], vm); toAdd.Constant = double.Parse(featureExpression.Split(new char[] { '*' }, 2)[0].Trim(), System.Globalization.CultureInfo.GetCultureInfo("en-us")); featureSetFromString.Add(toAdd); } learningRound.featureSet = featureSetFromString; learningRound.learningError = double.Parse(data[2].Trim(), System.Globalization.CultureInfo.GetCultureInfo("en-us")); learningRound.learningError_relative = double.Parse(data[3].Trim(), System.Globalization.CultureInfo.GetCultureInfo("en-us")); learningRound.validationError = double.Parse(data[4].Trim(), System.Globalization.CultureInfo.GetCultureInfo("en-us")); learningRound.validationError_relative = double.Parse(data[5].Trim(), System.Globalization.CultureInfo.GetCultureInfo("en-us")); learningRound.elapsedTime = TimeSpan.FromSeconds(double.Parse(data[6].Trim(), System.Globalization.CultureInfo.GetCultureInfo("en-us"))); Feature bestCandidateFromString = new Feature(data[8], vm); learningRound.bestCandidate = bestCandidateFromString; learningRound.bestCandidateSize = int.Parse(data[9].Trim()); try { learningRound.bestCandidateScore = double.Parse(data[10].Trim(), System.Globalization.CultureInfo.GetCultureInfo("en-us")); } catch (OverflowException overF) { GlobalState.logError.logLine("Error in analysing of the learning round."); GlobalState.logError.logLine(overF.Source + " -> " + overF.Message); learningRound.bestCandidateScore = Double.MaxValue; } return learningRound; }
private Cplex initCplex(VariabilityModel vm) { Cplex cplex = new Cplex(); one = cplex.Constant(1); initializeBinaryVariables(cplex, vm); return(cplex); }
public static bool testOptionalNumSample() { VariabilityModel withOptional = SampleUtil.loadOptionalVM(); List <Configuration> sampledWithOptional = SampleUtil.sampleWholePopulation(withOptional); return(7 == sampledWithOptional.Count && sampledWithOptional.Exists(x => x.BinaryOptions.ContainsKey(withOptional.AbrstactOptions[0]))); }
public static List <Configuration> sampleWholePopulation(VariabilityModel vm) { List <SamplingStrategies> binStrat = new List <SamplingStrategies>(); binStrat.Add(SamplingStrategies.ALLBINARY); List <ExperimentalDesign> expDesign = new List <ExperimentalDesign>(); expDesign.Add(new FullFactorialDesign()); return(ConfigurationBuilder.buildConfigs(vm, binStrat, expDesign, new List <HybridStrategy>())); }
private static void transformMixedConstraints(VariabilityModel transformed, VariabilityModel vm) { foreach (MixedConstraint constraint in vm.MixedConstraints) { List <NumericOption> numOpts = constraint.leftHandSide.participatingNumOptions .Union(constraint.rightHandSide.participatingNumOptions).Distinct().ToList(); string unparsedExpression = constraint.leftHandSide + " " + constraint.comparator + " " + constraint.rightHandSide; foreach (NumericOption numOpt in numOpts) { List <String> allValues = new List <string>(); numOpt.getAllValues().ForEach(val => allValues.Add("( " + numOpt.Name + "_" + val + " * " + val + " )") ); string replacement = "( " + String.Join(" + ", allValues) + " )"; unparsedExpression = unparsedExpression.Replace(numOpt.ToString(), replacement); } // If the source constraints always evaluates to true in case of at least one of the present configuration options is // deselected we have to do apply appropriate transformations to retain that meaning if (constraint.requirement == "all") { List <BinaryOption> leftBinOpts = constraint.leftHandSide.participatingBoolOptions.Distinct().ToList(); List <BinaryOption> rightBinOpts = constraint.leftHandSide.participatingBoolOptions.Distinct().ToList(); string[] tmp = unparsedExpression.Split(new string[] { constraint.comparator }, StringSplitOptions.None); string lhs = tmp[0]; string rhs = tmp[1]; // First we add a term to each side that always evaluates to // 0, in case one of the configuration options is deselected, and otherwise has no impact on the actually meaning // of the constraint // Added will be: prod(Binary options in source VM on the left) * (lhs) op prod(Binary options in source VM on the right) * (rhs) // In case the constraint includes equality this is enough lhs = "( " + (leftBinOpts.Count == 0 ? "" : (String.Join(" * ", leftBinOpts.Select(opt => opt.Name)) + " * ")) + " 1 * (" + lhs + " ) " + " )"; rhs = "( " + "( " + rhs + " ) * 1 " + (rightBinOpts.Count == 0 ? "" : (" * " + String.Join(" * ", rightBinOpts.Select(opt => opt.Name)))) + " ) "; // If the constraint includes inequality we additionally shift one side by 1 and add/subtract 1 to the other side in case all configurations are present. // So this constraint will always be true of one option is missing and have no impact on the meaning of the constraint in case // configuration options are missing // The result will be: prod(BinOpts) + ((prod(left bin opts) * (lhs)) op (prod(right bin opts) * (rhs)) +/- 1 if (constraint.comparator == "!=" || constraint.comparator == "<" || constraint.comparator == ">") { string shiftOp = constraint.comparator == ">" ? " - " : " + "; lhs = (leftBinOpts.Count == 0 ? "" : (String.Join(" * ", leftBinOpts.Select(opt => opt.Name))) + shiftOp) + " (" + lhs + " ) "; rhs = "( " + rhs + " ) " + shiftOp + " 1 "; } unparsedExpression = lhs + constraint.comparator + rhs; } transformed.MixedConstraints.Add(new MixedConstraint(unparsedExpression, transformed, "none", constraint.negativeOrPositiveExpr)); } }
public List <Configuration> buildConfigs(VariabilityModel vm, List <BinaryOption> desiredOptions) { if (hybridStrategies.Count == 0) { throw new Exception("There must be at least one hybrid strategy!"); } List <Configuration> configurations = new List <Configuration>(); foreach (HybridStrategy hybrid in hybridStrategies) { hybrid.SetExistingConfigurations(existingConfigurations); string previousValue = hybrid.GetSamplingParameters(DistributionSensitive.NUM_CONFIGS); Dictionary <string, string> parameterValue = new Dictionary <string, string> { { DistributionSensitive.NUM_CONFIGS, "1" } }; hybrid.SetSamplingParameters(parameterValue); hybrid.SetExistingConfigurations(existingConfigurations); hybrid.ComputeSamplingStrategy(desiredOptions); if (hybrid.selectedConfigurations.Any(config => existingConfigurations.Contains(config))) { throw new Exception("configuration already exists"); } configurations.AddRange(hybrid.selectedConfigurations); parameterValue = new Dictionary <string, string> { { DistributionSensitive.NUM_CONFIGS, previousValue } }; hybrid.SetSamplingParameters(parameterValue); } if (vm.MixedConstraints.Count == 0) { return(replaceReference(configurations.Distinct().ToList())); } List <Configuration> unfilteredList = configurations.Distinct().ToList(); List <Configuration> filteredConfiguration = new List <Configuration>(); foreach (Configuration toTest in unfilteredList) { bool isValid = true; foreach (MixedConstraint constr in vm.MixedConstraints) { if (!constr.configIsValid(toTest)) { isValid = false; } } if (isValid) { filteredConfiguration.Add(toTest); } } return(replaceReference(filteredConfiguration)); }