private List <List <BinaryOption> > generateConfig(BinaryOption toConfigure, Dictionary <BinaryOption, List <BinaryOption> > alternatives, List <BinaryOption> alreadyComputed, VariabilityModel vm) { List <List <BinaryOption> > configurations = new List <List <BinaryOption> >(); foreach (BinaryOption next in alternatives.Keys) { if (alreadyComputed.Contains(next)) { continue; } if (toConfigure.Parent == next.Parent) { continue; } foreach (BinaryOption k in alternatives[next]) { List <BinaryOption> config = new List <BinaryOption>(); config.Add(toConfigure); config.Add(k); List <List <BinaryOption> > temp = new List <List <BinaryOption> >(); temp = ConfigurationBuilder.vg.MaximizeConfig(config, vm, false, null); if (temp == null || temp.Count == 0) { continue; } config = temp[0]; if (config == null) { continue; } configurations.Add(config); } } return(configurations); }
/// <summary> /// Selects Random Features and adds them to a temporary configuration /// </summary> /// <param name="order"></param> private void CreateRandomInteraction(int order) { var rands = new List <int>(order); var options = new BinaryOption[order]; for (var i = 0; i < order; i++) { var randomVal = _rand.Next(0, FeatureValues.Length); if (rands.Contains(randomVal)) //we already have this random feature, try another { i--; continue; } rands.Add(randomVal); //add our found random val options[i] = _varModel.BinaryOptions[rands[i]]; //add to random config if we dont have it already if (_tempConfig.Contains(options[i])) { continue; } _tempConfig.Add(options[i]); _featuresInInteraction.Add(options[i]); //TODO check if we can unite FeatureInInteaction with TempConfig } }
public void ParseRelation(string binOpName, BinaryOption parentOption, bool childOf) { BinaryOption toAdd = null; if (binOpName.Contains(";")) { binOpName = binOpName.Replace(";", ""); } if (binOpName.Contains("[") && binOpName.Contains("]")) { //binOpName = binOpName.Remove(0, 1); //binOpName = binOpName.Remove(binOpName.Length - 1, 1); Console.WriteLine("Cardinality Group"); //Console.WriteLine("Added : " + binOpName + " optional with parent " + parentOption); //_varModel.addConfigurationOption(toAdd = new BinaryOption(_varModel, binOpName) { Optional = true }); } else { //Console.WriteLine("Added : " + binOpName + " with parent " + parentOption); _varModel.addConfigurationOption(toAdd = new BinaryOption(_varModel, binOpName)); } if (childOf) { toAdd.Parent = parentOption; } else { //Console.WriteLine("Setting Parent: " + toAdd + " " + tokens[j]); //parentOption = toAdd; } }
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); }
/// <summary> /// Invokes if the radio button for switching to a binary option has been pressed. /// </summary> /// <param name="sender">Sender</param> /// <param name="e">Event</param> private void optionTypeBinaryRadioButton_CheckedChanged(object sender, EventArgs e) { if (optionTypeBinaryRadioButton.Checked) { optionTypeNumericRadioButton.Checked = false; ConfigurationOption newOption = new BinaryOption(GlobalState.varModel, currentOption.Name); foreach (ConfigurationOption opt in currentOption.Children) { opt.Parent = newOption; newOption.Children.Add(opt); } currentOption.Children = new List <ConfigurationOption>(); newOption.Parent = currentOption.Parent; newOption.Prefix = currentOption.Prefix; newOption.Postfix = currentOption.Postfix; newOption.OutputString = currentOption.OutputString; newOption.Excluded_Options = currentOption.Excluded_Options; newOption.Implied_Options = currentOption.Implied_Options; GlobalState.varModel.deleteOption(currentOption); GlobalState.varModel.addConfigurationOption(newOption); currentOption = newOption; optionalCheckBox.Visible = true; optionalCheckBox.Checked = ((BinaryOption)currentOption).Optional; numericSettingsGroupBox.Enabled = false; rangeLabel.Text = NO_DATA; stepSizeLabel.Text = NO_DATA; } }
public VariabilityModel(String name) { this.name = name; if (root == null) root = new BinaryOption(this, "root"); this.BinaryOptions.Add(root); }
/// <summary> /// The method aims at finding a configuration which is similar to the given configuration, but does not contain the optionToBeRemoved. If further options need to be removed from the given configuration, they are outputed in removedElements. /// Idea: Encode this as a CSP problem. We aim at finding a configuration that maximizes a goal. Each option of the given configuration gets a large value assigned. All other options of the variability model gets a negative value assigned. /// We will further create a boolean constraint that forbids selecting the optionToBeRemoved. Now, we find an optimal valid configuration. /// </summary> /// <param name="optionToBeRemoved">The binary configuration option that must not be part of the new configuration.</param> /// <param name="originalConfig">The configuration for which we want to find a similar one.</param> /// <param name="removedElements">If further options need to be removed from the given configuration to build a valid configuration, they are outputed in this list.</param> /// <param name="vm">The variability model containing all options and their constraints.</param> /// <returns>A configuration that is valid, similar to the original configuration and does not contain the optionToBeRemoved.</returns> public List <BinaryOption> GenerateConfigWithoutOption(BinaryOption optionToBeRemoved, List <BinaryOption> originalConfig, out List <BinaryOption> removedElements, VariabilityModel vm) { 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); removedElements = new List <BinaryOption>(); //Forbid the selection of this configuration option CspTerm optionToRemove = elemToTerm[optionToBeRemoved]; S.AddConstraints(S.Implies(S.True, S.Not(optionToRemove))); //Defining Goals CspTerm[] finalGoals = new CspTerm[variables.Count]; int r = 0; foreach (var term in variables) { if (originalConfig.Contains(termToElem[term])) { finalGoals[r] = term * -1000; //Since we minimize, we put a large negative value of an option that is within the original configuration to increase chances that the option gets selected again } else { finalGoals[r] = variables[r] * 10000;//Positive number will lead to a small chance that an option gets selected when it is not in the original configuration } r++; } S.TryAddMinimizationGoals(S.Sum(finalGoals)); ConstraintSolverSolution soln = S.Solve(); List <BinaryOption> tempConfig = new List <BinaryOption>(); if (soln.HasFoundSolution && soln.Quality == ConstraintSolverSolution.SolutionQuality.Optimal) { tempConfig.Clear(); foreach (CspTerm cT in variables) { if (soln.GetIntegerValue(cT) == 1) { tempConfig.Add(termToElem[cT]); } } //Adding the options that have been removed from the original configuration foreach (var opt in originalConfig) { if (!tempConfig.Contains(opt)) { removedElements.Add(opt); } } return(tempConfig); } return(null); }
/// <summary> /// The method aims at finding a configuration which is similar to the given configuration, but does not contain the optionToBeRemoved. If further options need to be removed from the given configuration, they are outputed in removedElements. /// </summary> /// <param name="optionToBeRemoved">The binary configuration option that must not be part of the new configuration.</param> /// <param name="originalConfig">The configuration for which we want to find a similar one.</param> /// <param name="removedElements">If further options need to be removed from the given configuration to build a valid configuration, they are outputed in this list.</param> /// <param name="vm">The variability model containing all options and their constraints.</param> /// <returns>A configuration that is valid, similar to the original configuration and does not contain the optionToBeRemoved.</returns> public List <BinaryOption> GenerateConfigWithoutOption(BinaryOption optionToBeRemoved, List <BinaryOption> originalConfig, out List <BinaryOption> removedElements, VariabilityModel vm) { removedElements = new List <BinaryOption>(); var originalConfigWithoutRemoved = originalConfig.Where(x => !x.Equals(optionToBeRemoved)); List <BoolExpr> variables; Dictionary <BoolExpr, BinaryOption> termToOption; Dictionary <BinaryOption, BoolExpr> optionToTerm; Tuple <Context, BoolExpr> z3Tuple = Z3Solver.GetInitializedBooleanSolverSystem(out variables, out optionToTerm, out termToOption, vm, this.henard); Context z3Context = z3Tuple.Item1; BoolExpr z3Constraints = z3Tuple.Item2; List <BoolExpr> constraints = new List <BoolExpr>(); constraints.Add(z3Constraints); constraints.Add(z3Context.MkNot(optionToTerm[optionToBeRemoved])); ArithExpr[] minGoals = new ArithExpr[variables.Count]; for (int r = 0; r < variables.Count; r++) { BinaryOption currOption = termToOption[variables[r]]; ArithExpr numericVariable = z3Context.MkIntConst(currOption.Name); int weight = -1000; if (!originalConfigWithoutRemoved.Contains(currOption)) { weight = 1000; } else if (currOption.Equals(optionToBeRemoved)) { weight = 100000; } constraints.Add(z3Context.MkEq(numericVariable, z3Context.MkITE(variables[r], z3Context.MkInt(weight), z3Context.MkInt(0)))); minGoals[r] = numericVariable; } Optimize optimizer = z3Context.MkOptimize(); optimizer.Assert(constraints.ToArray()); optimizer.MkMinimize(z3Context.MkAdd(minGoals)); if (optimizer.Check() != Status.SATISFIABLE) { return(null); } else { Model model = optimizer.Model; List <BinaryOption> similarConfig = RetrieveConfiguration(variables, model, termToOption); removedElements = originalConfigWithoutRemoved.Except(similarConfig).ToList(); return(similarConfig); } }
public static LPBinaryOperator Create(BinaryOption option, LPUser operand1, LPUser operand2) { var lpbo = new LPBinaryOperator { Option = option }; lpbo.operand.Add(operand1); lpbo.operand.Add(operand2); return(lpbo); }
public void CommodityBinaryEuropeanOptionTest() { var goldOption = new BinaryOption( new Date(2015, 03, 20), new Date(2015, 06, 16), OptionExercise.European, OptionType.Put, 231.733, InstrumentType.Futures, BinaryOptionPayoffType.CashOrNothing, 10.0, CalendarImpl.Get("chn"), new Act365(), CurrencyCode.CNY, CurrencyCode.CNY, new[] { new Date(2015, 06, 16) }, new[] { new Date(2015, 06, 16) }, 5.5 ); var market = GetMarket(); IMarketCondition marketCondition = new MarketCondition( x => x.ValuationDate.Value = market.ReferenceDate, x => x.DiscountCurve.Value = market.GetData <CurveData>("Fr007").YieldCurve, x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> { { "", market.GetData <CurveData>("Fr007").YieldCurve } }, x => x.SpotPrices.Value = new Dictionary <string, double> { { "", 240.6 } }, x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> { { "", market.GetData <VolSurfMktData>("goldVolSurf").ToImpliedVolSurface(market.ReferenceDate) } } ); var engine = new AnalyticalBinaryEuropeanOptionEngine(); var result = engine.Calculate(goldOption, marketCondition, PricingRequest.All); Assert.AreEqual(0.615985804, result.Pv, 1e-8); Assert.AreEqual(-0.409184000310747, result.Delta, 1e-8); Assert.AreEqual(0.239395655872165, result.Gamma, 1e-8); Assert.AreEqual(0.265082040475919, result.Vega, 1e-8); Assert.AreEqual(-8.43816170E-07, result.Rho, 1e-8); var engine2 = new AnalyticalBinaryEuropeanOptionReplicationEngine(2.0, BinaryOptionReplicationStrategy.Up); result = engine2.Calculate(goldOption, marketCondition, PricingRequest.All); Assert.AreEqual(1.25655313, result.Pv, 1e-8); Assert.AreEqual(-0.745647330608376, result.Delta, 1e-8); Assert.AreEqual(0.377738685022888, result.Gamma, 1e-8); Assert.AreEqual(0.417379971819684, result.Vega, 1e-8); Assert.AreEqual(-1.72130447839702E-06, result.Rho, 1e-8); }
public VariabilityModel Parse() { Mode current = Mode.Start; lastAddition = model.Root; ParentOnLevel = new Dictionary <int, BinaryOption>(); ExcludesOnLevel = new Dictionary <int, List <BinaryOption> >(); //ParentOnLevel.Add(1, model.Root); string[] lines = File.ReadAllLines(FileName); foreach (var t in lines) { if (t.Contains("<feature_tree>")) { current = Mode.FeatureTree; continue; } if (t.Contains("</feature_tree>")) { current = Mode.FeatureEnd; continue; } if (t.Contains("<constraints>")) { current = Mode.Constraint; continue; } if (t.Contains("</constraints>")) { current = Mode.ConstraintEnd; continue; } if (t.Contains("<meta>")) { current = Mode.MetaData; continue; } if (t.Contains("</meta>")) { current = Mode.MetaEnd; continue; } else { } ParseLine(t, current); } model.saveXML("model.xml"); return(model); }
/// <summary> /// Invokes if the 'Add option'-button was pressed. /// /// This method will add the option the the current variability model and /// will dispose this form. /// </summary> /// <param name="sender">Sender</param> /// <param name="e">Event</param> private void addOptionButton_Click(object sender, EventArgs e) { ConfigurationOption newOption = null; if (numericRadioButton.Checked) { newOption = new NumericOption(GlobalState.varModel, this.featureNameTextBox.Text); ((NumericOption)newOption).Min_value = Convert.ToDouble(minValueTextBox.Text); ((NumericOption)newOption).Max_value = Convert.ToDouble(maxValueTextBox.Text); if (stepSizeCheckBox.Checked) { ((NumericOption)newOption).StepFunction = new InfluenceFunction( stepSizeTextBox.Text == "" ? "n + 1" : stepSizeTextBox.Text, (NumericOption)newOption); } else { ((NumericOption)newOption).StepFunction = new InfluenceFunction("n + 1", (NumericOption)newOption); } if (numOptionalCheckBox.Checked) { ((NumericOption)newOption).Optional = true; int flag; if (!int.TryParse(deselectedFlagTextBox.Text, out flag)) { MessageBox.Show("Invalid deselection flag. Value must be integer."); return; } else { ((NumericOption)newOption).setOptional(true, flag); } } } else { newOption = new BinaryOption(GlobalState.varModel, this.featureNameTextBox.Text); ((BinaryOption)newOption).Optional = optionalCheckBox.Checked; } if (prePostCheckBox.Checked) { newOption.Prefix = prefixTextBox.Text; newOption.Postfix = postfixTextBox.Text; } newOption.OutputString = outputStringTextBox.Text; newOption.Parent = GlobalState.varModel.getOption(this.parentComboBox.Text); GlobalState.varModel.addConfigurationOption(newOption); this.Close(); }
private void initializeExclusionConstraint(Cplex cplex, BinaryOption currentBinOpt, INumVar current, List <ConfigurationOption> notAllowed, INumExpr trigger) { INumVar[] excluded = populateArray(current, notAllowed); // If there is some kind of exclusiion then the sum of the group has to be one if the // trigger(either the parent for alternative groups or the current option for cross tree exclusions) // is selected cplex.Add(cplex.IfThen( cplex.Eq(one, trigger), cplex.Eq(one, cplex.Sum(excluded)) )); }
/// <summary> /// Based on a given (partial) configuration and a variability, we aim at finding all optimally maximal or minimal (in terms of selected binary options) configurations. /// </summary> /// <param name="config">The (partial) configuration which needs to be expanded to be valid.</param> /// <param name="vm">Variability model containing all options and their constraints.</param> /// <param name="minimize">If true, we search for the smallest (in terms of selected options) valid configuration. If false, we search for the largest one.</param> /// <param name="unwantedOptions">Binary options that we do not want to become part of the configuration. Might be part if there is no other valid configuration without them</param> /// <returns>A list of configurations that satisfies the VM and the goal (or null if there is none).</returns> public List <List <BinaryOption> > MaximizeConfig(List <BinaryOption> config, VariabilityModel vm, bool minimize, List <BinaryOption> unwantedOptions) { List <BoolExpr> variables; Dictionary <BoolExpr, BinaryOption> termToOption; Dictionary <BinaryOption, BoolExpr> optionToTerm; Tuple <Context, BoolExpr> z3Tuple = Z3Solver.GetInitializedBooleanSolverSystem(out variables, out optionToTerm, out termToOption, vm, this.henard); Context z3Context = z3Tuple.Item1; BoolExpr z3Constraints = z3Tuple.Item2; List <BoolExpr> constraints = new List <BoolExpr>(); constraints.Add(z3Constraints); List <BoolExpr> requireConfigs = new List <BoolExpr>(); if (config != null) { foreach (BinaryOption option in config) { requireConfigs.Add(optionToTerm[option]); } constraints.Add(z3Context.MkAnd(requireConfigs.ToArray())); } ArithExpr[] optimizationGoals = new ArithExpr[variables.Count]; for (int r = 0; r < variables.Count; r++) { BinaryOption currOption = termToOption[variables[r]]; ArithExpr numericVariable = z3Context.MkIntConst(currOption.Name); constraints.Add(z3Context.MkEq(numericVariable, z3Context.MkITE(variables[r], z3Context.MkInt(1), z3Context.MkInt(0)))); optimizationGoals[r] = numericVariable; } Optimize optimizer = z3Context.MkOptimize(); optimizer.Assert(constraints.ToArray()); optimizer.MkMaximize(z3Context.MkAdd(optimizationGoals)); if (optimizer.Check() != Status.SATISFIABLE) { return(null); } List <BinaryOption> solution = RetrieveConfiguration(variables, optimizer.Model, termToOption); return(new List <List <BinaryOption> > { solution }); }
private void initializeImpliedOptions(Cplex cplex, INumVar currentOption, BinaryOption currentBinOpt) { List <List <ConfigurationOption> > impliedOptions = currentBinOpt.Implied_Options; foreach (List <ConfigurationOption> impliedGroup in impliedOptions) { INumVar[] implVars = populateArray(currentOption, impliedGroup); // For implication groups the sum of the options has to be the number of implied options // if the current options is selected cplex.Add(cplex.IfThen( cplex.Eq(one, currentOption), cplex.Eq(cplex.Sum(implVars), cplex.Constant(implVars.Count())) )); } }
private Dictionary <BinaryOption, ArithExpr> generateIntConstants(Context z3Context, List <BoolExpr> constraints, List <BoolExpr> variables, Dictionary <BoolExpr, BinaryOption> termToOption) { Dictionary <BinaryOption, ArithExpr> optionToInt = new Dictionary <BinaryOption, ArithExpr>(); for (int r = 0; r < variables.Count; r++) { BinaryOption currOption = termToOption[variables[r]]; ArithExpr numericVariable = z3Context.MkIntConst(currOption.Name); optionToInt.Add(currOption, numericVariable); constraints.Add(z3Context.MkEq(numericVariable, z3Context.MkITE(variables[r], z3Context.MkInt(1), z3Context.MkInt(0)))); } return(optionToInt); }
private static void AssertVariabilityModelProperties(List <List <BinaryOption> > partialConfigurations) { // Assert that every partial configurations contains the root and mandatory options Assert.True(partialConfigurations.TrueForAll(partialConf => partialConf.Contains(GlobalState.varModel.Root))); BinaryOption mandatory = GlobalState.varModel.getBinaryOption("binOpt1"); Assert.True(partialConfigurations.TrueForAll(partialConf => partialConf.Contains(mandatory))); // Assert that no partial configuration has exactly one member of an alternative group selected BinaryOption alternative1 = GlobalState.varModel.getBinaryOption("member21"); BinaryOption alternative2 = GlobalState.varModel.getBinaryOption("member22"); BinaryOption alternative3 = GlobalState.varModel.getBinaryOption("member23"); Assert.True(partialConfigurations.TrueForAll(partialConf => { return((partialConf.Contains(alternative1) && !partialConf.Contains(alternative2) && !partialConf.Contains(alternative3)) || (!partialConf.Contains(alternative1) && partialConf.Contains(alternative2) && !partialConf.Contains(alternative3)) || (!partialConf.Contains(alternative1) && !partialConf.Contains(alternative2) && partialConf.Contains(alternative3))); })); // Assert that there exists at least one partial configuration that has a optional option selected // and one that has a option option selected BinaryOption optional = GlobalState.varModel.getBinaryOption("binOpt6"); Assert.True(partialConfigurations.Any(partialConf => partialConf.Contains(optional)) && partialConfigurations.Any(partialConf => !partialConf.Contains(optional))); // Assert that implication constraints are not violated, i.e. if binOpt5 is selected then // binOpt6 also has to be selected BinaryOption implicant = GlobalState.varModel.getBinaryOption("binOpt5"); Assert.True(partialConfigurations.TrueForAll(partialConf => { return(!partialConf.Contains(implicant) || (partialConf.Contains(implicant) && partialConf.Contains(optional))); })); // Assert that exclusion constraints are not violated, i.e if binOpt3 is selected then // binOpt2 is not selected BinaryOption exclusionTrigger = GlobalState.varModel.getBinaryOption("binOpt3"); BinaryOption excluded = GlobalState.varModel.getBinaryOption("binOpt2"); Assert.True(partialConfigurations.TrueForAll(partialConf => { return(!partialConf.Contains(exclusionTrigger) || !partialConf.Contains(excluded)); })); }
private void HandleGroupedFeatureExcludes(int lineLevel, BinaryOption opt) { if (exlusiveMode) { opt.Optional = false; if (ExcludesOnLevel.ContainsKey(lineLevel)) { ExcludesOnLevel[lineLevel].Add(opt); } else { List <BinaryOption> excludes = new List <BinaryOption>(); excludes.Add(opt); ExcludesOnLevel.Add(lineLevel, excludes); } } }
/// <summary> /// Returns all possible buckets using the <see cref="HybridStrategy.optionsToConsider"/>. /// </summary> /// <returns>a <see cref="List"/> containing the sum of all value combinations of the features</returns> private List <double> ComputeBuckets() { List <List <double> > allValueSets = new List <List <double> >(); foreach (ConfigurationOption o in this.optionsToConsider) { if (o is NumericOption) { NumericOption numOpt = (NumericOption)o; List <double> distances = new List <double>(); List <double> valuesOfNumericOption = numOpt.getAllValues(); foreach (double numOptValue in valuesOfNumericOption) { distances.Add(this.metric.ComputeDistanceOfNumericFeature(numOptValue, numOpt.Min_value, numOpt.Max_value)); } allValueSets.Add(distances); } else { BinaryOption binOpt = (BinaryOption)o; if (!binOpt.Optional && CountChildren(binOpt, GlobalState.varModel) > 0) { allValueSets.Add(new List <double> { this.metric.ComputeDistanceOfBinaryFeature(1) }); } else { allValueSets.Add(new List <double> { this.metric.ComputeDistanceOfBinaryFeature(0), this.metric.ComputeDistanceOfBinaryFeature(1) }); } } } List <double> result = ComputeSumOfCartesianProduct(allValueSets); // Sort the list result.Sort(delegate(double x, double y) { return(x.CompareTo(y)); }); return(result); }
public static VariabilityModel transformVarModelAllbinary(VariabilityModel vm) { VariabilityModel transformedVarModel = new VariabilityModel(vm.Name); vm.BinaryOptions.ForEach(x => transformedVarModel.addConfigurationOption(x)); foreach (NumericOption currNumOpt in vm.NumericOptions) { BinaryOption parent = new BinaryOption(vm, currNumOpt.Name); transformedVarModel.addConfigurationOption(parent); // Create Binary Options for each numeric Option( #Steps) List <ConfigurationOption> allChildren = new List <ConfigurationOption>(); foreach (double step in currNumOpt.getAllValues()) { BinaryOption toAdd = new BinaryOption(vm, currNumOpt.Name + "_" + step); toAdd.Optional = false; toAdd.OutputString = currNumOpt.Prefix + step + currNumOpt.Postfix; toAdd.Parent = parent; allChildren.Add(toAdd); transformedVarModel.addConfigurationOption(toAdd); } // Add a exclude statement so that it isnt possible to select 2 values for a numeric option at the same time foreach (ConfigurationOption currentOption in allChildren) { List <List <ConfigurationOption> > excluded = new List <List <ConfigurationOption> >(); List <ConfigurationOption> currentOptionWrapper = new List <ConfigurationOption>(); currentOptionWrapper.Add(currentOption); allChildren.Except(currentOptionWrapper).ToList() .ForEach(x => excluded.Add(new ConfigurationOption[] { x }.ToList())); currentOption.Excluded_Options = excluded; } } transformedVarModel.BinaryConstraints.AddRange(vm.BinaryConstraints); foreach (NonBooleanConstraint constraint in vm.NonBooleanConstraints) { var newConstraints = transformToBooleanConstraints(constraint); transformedVarModel.BinaryConstraints.AddRange(newConstraints); } foreach (MixedConstraint constraint in vm.MixedConstraints) { var newConstraints = transformToBooleanConstraints(constraint); transformedVarModel.BinaryConstraints.AddRange(newConstraints); } return(transformedVarModel); }
/// <summary> /// /// </summary> /// <param name="vm"></param> /// <returns></returns> public List <List <BinaryOption> > generateNegativeFWAllCombinations(VariabilityModel vm) { this.configurations.Clear(); List <List <BinaryOption> > maxConfigs = new List <List <BinaryOption> >(); maxConfigs = getMaxConfigurations(vm, true); configurations.AddRange(maxConfigs); //Compute negative feature-wise for all maximum configurations foreach (List <BinaryOption> config in maxConfigs) { bool abort = false; List <BinaryOption> currentConfig = new List <BinaryOption>(); foreach (BinaryOption e in config) { currentConfig.Add(e); } List <BinaryOption> removedElements = new List <BinaryOption>(); while (abort == false) { abort = true; BinaryOption currentElementUnderConsdiration = null; foreach (BinaryOption e in currentConfig) { currentElementUnderConsdiration = e; //Constructing new Configuration without the current element List <BinaryOption> configToMeasure = new List <BinaryOption>(); configToMeasure = ConfigurationBuilder.vg.GenerateConfigWithoutOption(e, currentConfig, out removedElements, vm); if (configToMeasure == null) { abort = true; continue; } else if (!Configuration.containsBinaryConfiguration(configurations, configToMeasure)) { configurations.Add(configToMeasure); } } } } return(this.configurations); }
private void HandleNewOption(string line, int lineLevel, bool optional) { var name = line.Split('(')[0]; name = name.Remove(0, 3); var id = (line.Split('(')[1]); id = id.Remove(id.Length - 1, 1); BinaryOption opt = new BinaryOption(model, id); opt.OutputString = name; opt.Optional = optional; opt.Parent = ParentOnLevel[lineLevel]; model.addConfigurationOption(opt); lastAddition = opt; }
/// <summary> /// This method searches for a corresponding methods in the dynamically loadeda assemblies and calls it if found. It prefers due to performance reasons the Microsoft Solver Foundation implementation. /// </summary> /// <param name="optionToBeRemoved">The binary configuration option that must not be part of the new configuration.</param> /// <param name="originalConfig">The configuration for which we want to find a similar one.</param> /// <param name="removedElements">If further options need to be removed from the given configuration to build a valid configuration, they are outputed in this list.</param> /// <param name="vm">The variability model containing all options and their constraints.</param> /// <returns>A configuration that is valid, similar to the original configuration and does not contain the optionToBeRemoved.</returns> public List <BinaryOption> generateConfigWithoutOption(BinaryOption optionToBeRemoved, List <BinaryOption> originalConfig, out List <BinaryOption> removedElements, VariabilityModel vm) { foreach (Lazy <IVariantGenerator, ISolverType> solver in solvers) { if (solver.Metadata.SolverType.Equals("MSSolverFoundation")) { return(solver.Value.generateConfigWithoutOption(optionToBeRemoved, originalConfig, out removedElements, vm)); } } //If not MS Solver, take any solver. Should be changed when supporting more than 2 solvers here foreach (Lazy <IVariantGenerator, ISolverType> solver in solvers) { return(solver.Value.generateConfigWithoutOption(optionToBeRemoved, originalConfig, out removedElements, vm)); } removedElements = null; return(null); }
internal static void generateVariabilityModel(Dictionary <string, List <string> > resultsByVariabilityPoints) { VariabilityModel varModel = new VariabilityModel("DuneCaseStudy"); foreach (KeyValuePair <String, List <String> > resultForOne in resultsByVariabilityPoints) { BinaryOption alternativeParent = new BinaryOption(varModel, "group" + resultForOne.Key); alternativeParent.Optional = false; alternativeParent.Parent = varModel.Root; alternativeParent.OutputString = "NoOutput"; varModel.addConfigurationOption(alternativeParent); List <BinaryOption> elementsOfGroup = new List <BinaryOption>(); foreach (String alternative in resultForOne.Value) { BinaryOption oneAlternative = new BinaryOption(varModel, alternative); oneAlternative.Optional = false; oneAlternative.OutputString = alternative; oneAlternative.Parent = alternativeParent; varModel.addConfigurationOption(oneAlternative); elementsOfGroup.Add(oneAlternative); } foreach (BinaryOption alternative in elementsOfGroup) { foreach (BinaryOption other in elementsOfGroup) { if (alternative.Equals(other)) { continue; } alternative.Excluded_Options.Add(new List <ConfigurationOption>() { other }); } } } varModel.saveXML(DEBUG_PATH + varModel.Name + ".xml"); }
public void initVariabilityModel() { VariabilityModel vm = new VariabilityModel("test"); NumericOption numOpt = new NumericOption(vm, "testNum"); numOpt.SetValues(new double[] { 0, 5, 10, 15, 20, 25 }); numOpt.Min_value = 0; numOpt.Max_value = 25; numOpt.Parent = vm.Root; BinaryOption binOpt = new BinaryOption(vm, "testBin"); binOpt.Optional = true; binOpt.Parent = vm.Root; vm.addConfigurationOption(numOpt); vm.addConfigurationOption(binOpt); vm.NonBooleanConstraints.Add(new NonBooleanConstraint("testNum > 0", vm)); GlobalState.varModel = vm; this.vm = vm; }
private bool newOptionIsValidForCandidate(List <BinaryOption> candidates, BinaryOption binaryOption) { for (int i = 0; i < candidates.Count; i++) { BinaryOption inList = candidates[i]; //Check parent-child relationship if (inList.isAncestor(binaryOption) || binaryOption.isAncestor(inList) || inList == binaryOption) { return(false); } //Check if one option implies the presence of the other option bool impliedOption = false; foreach (var implied in inList.Implied_Options) { if (implied.Count == 1 && implied[0] == binaryOption) { impliedOption = true; break; } } if (impliedOption) { return(false); } //vice versa foreach (var implied in binaryOption.Implied_Options) { if (implied.Count == 1 && implied[0] == inList) { impliedOption = true; break; } } if (impliedOption) { return(false); } } return(true); }
private void HandleNewGroupedFeature(string line, int lineLevel) { var name = line.Split('(')[0]; name = name.Remove(0, 2); var id = (line.Split('(')[1]); id = id.Remove(id.Length - 1, 1); BinaryOption opt = new BinaryOption(model, id); opt.OutputString = name; opt.Optional = true; opt.Parent = ParentOnLevel[lineLevel - 1]; model.addConfigurationOption(opt); lastAddition = opt; HandleGroupedFeatureExcludes(lineLevel, opt); }
/// <summary> /// Invokes if the 'Add option'-button was pressed. /// /// This method will add the option the the current variability model and /// will dispose this form. /// </summary> /// <param name="sender">Sender</param> /// <param name="e">Event</param> private void addOptionButton_Click(object sender, EventArgs e) { ConfigurationOption newOption = null; if (numericRadioButton.Checked) { newOption = new NumericOption(GlobalState.varModel, this.featureNameTextBox.Text); ((NumericOption)newOption).Min_value = Convert.ToDouble(minValueTextBox.Text); ((NumericOption)newOption).Max_value = Convert.ToDouble(maxValueTextBox.Text); if (stepSizeCheckBox.Checked) { ((NumericOption)newOption).StepFunction = new InfluenceFunction( stepSizeTextBox.Text == "" ? "n + 1": stepSizeTextBox.Text, (NumericOption)newOption); } else { ((NumericOption)newOption).StepFunction = new InfluenceFunction("n + 1", (NumericOption)newOption); } } else { newOption = new BinaryOption(GlobalState.varModel, this.featureNameTextBox.Text); ((BinaryOption)newOption).Optional = optionalCheckBox.Checked; } if (prePostCheckBox.Checked) { newOption.Prefix = prefixTextBox.Text; newOption.Postfix = postfixTextBox.Text; } newOption.OutputString = outputStringTextBox.Text; newOption.Parent = GlobalState.varModel.getOption(this.parentComboBox.Text); newOption.Parent.Children.Add(newOption); GlobalState.varModel.addConfigurationOption(newOption); this.Close(); }
/// <summary> /// Computes the influence of all configuration options based on the measurements of the given result db. It uses linear programming (simplex) and is an exact algorithm. /// </summary> /// <param name="nfp">The non-functional property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing options and interactions. The state of the model will be changed by the result of the process</param> /// <param name="db">The result database containing the measurements.</param> /// <returns>A map of binary options to their computed influences.</returns> public Dictionary <BinaryOption, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db) { List <BinaryOption> variables = infModel.Vm.BinaryOptions; List <double> results = new List <double>(); List <List <BinaryOption> > configurations = new List <List <BinaryOption> >(); foreach (Configuration c in db.Configurations) { configurations.Add(c.getBinaryOptions(BinaryOption.BinaryValue.Selected)); if (nfp != null) { results.Add(c.GetNFPValue(nfp)); } else { results.Add(c.GetNFPValue()); } } List <String> errorEqs = new List <string>(); Dictionary <String, double> faultRates = new Dictionary <string, double>(); List <int> indexOfErrorMeasurements = new List <int>(); Dictionary <String, double> featureValuedAsStrings = solve(variables, results, configurations, infModel.InteractionInfluence.Keys.ToList()); foreach (String current in featureValuedAsStrings.Keys) { BinaryOption temp = infModel.Vm.getBinaryOption(current); this.featureValues[temp] = featureValuedAsStrings[current]; InfluenceFunction influence = new InfluenceFunction(temp.Name + " + " + featureValuedAsStrings[current].ToString(), infModel.Vm); if (infModel.BinaryOptionsInfluence.Keys.Contains(temp)) { infModel.BinaryOptionsInfluence[temp] = influence; } else { infModel.BinaryOptionsInfluence.Add(temp, influence); } } return(this.featureValues); }
private static VariabilityModel transformVarModel() { VariabilityModel transformedVarModel = new VariabilityModel(GlobalState.varModel.Name); GlobalState.varModel.BinaryOptions.ForEach(x => transformedVarModel.addConfigurationOption(x)); GlobalState.varModel.BinaryConstraints.ForEach(constraint => convertToCNF(constraint).ForEach(convertedConstraint => transformedVarModel.BinaryConstraints.Add(convertedConstraint))); foreach (NumericOption currNumOpt in GlobalState.varModel.NumericOptions) { BinaryOption parent = new BinaryOption(GlobalState.varModel, currNumOpt.Name); transformedVarModel.addConfigurationOption(parent); // Create Binary Options for each numeric Option( #Steps) List <ConfigurationOption> allChildren = new List <ConfigurationOption>(); foreach (double step in currNumOpt.getAllValues()) { BinaryOption toAdd = new BinaryOption(GlobalState.varModel, currNumOpt.Name + "_" + step); toAdd.Optional = false; toAdd.OutputString = currNumOpt.Prefix + step + currNumOpt.Postfix; toAdd.Parent = parent; allChildren.Add(toAdd); transformedVarModel.addConfigurationOption(toAdd); } parent.Children = allChildren; // Add a exclude statement so that it isnt possible to select 2 values for a numeric option at the same time foreach (ConfigurationOption currentOption in allChildren) { List <List <ConfigurationOption> > excluded = new List <List <ConfigurationOption> >(); List <ConfigurationOption> currentOptionWrapper = new List <ConfigurationOption>(); currentOptionWrapper.Add(currentOption); allChildren.Except(currentOptionWrapper).ToList() .ForEach(x => excluded.Add(new ConfigurationOption[] { x }.ToList())); currentOption.Excluded_Options = excluded; } } transformNumericConstraintsToBoolean(transformedVarModel); return(transformedVarModel); }
public void ParseRelationLine(string[] tokens) { BinaryOption parentOption = null; bool childOf = false; for (int j = 0; j < tokens.Length; j++) { //next binOps are Children if (tokens[j].Equals(":")) { childOf = true; continue; //next token } if (tokens[j].Equals(";")) { Debug.Assert(j == tokens.Length - 1); continue; //last token, get next line } if (tokens[j].Equals("")) { continue; //divider token, continue with next token } else { if (!childOf) { parentOption = tokens[j] == "root" ? _varModel.Root : _varModel.getBinaryOption(tokens[j]); } else { ParseRelation(tokens[j], parentOption, childOf); } } } }
private List<List<BinaryOption>> generateConfig(BinaryOption toConfigure, Dictionary<BinaryOption, List<BinaryOption>> alternatives, List<BinaryOption> alreadyComputed, VariabilityModel vm) { List<List<BinaryOption>> configurations = new List<List<BinaryOption>>(); foreach (BinaryOption next in alternatives.Keys) { if (alreadyComputed.Contains(next)) continue; if (toConfigure.Parent == next.Parent) continue; foreach (BinaryOption k in alternatives[next]) { List<BinaryOption> config = new List<BinaryOption>(); config.Add(toConfigure); config.Add(k); List<List<BinaryOption>> temp = new List<List<BinaryOption>>(); temp = generator.maximizeConfig(config, vm, false, null); if (temp == null || temp.Count == 0) continue; config = temp[0]; if (config == null) continue; configurations.Add(config); } } return configurations; }
public VariabilityModel createVarModel() { VariabilityModel varMod = new VariabilityModel("testModel_1"); // -------------------- BINARY OPTIONS ---------------- BinaryOption binOp1 = new BinaryOption(varMod, "binOpt1"); binOp1.Optional = false; binOp1.Prefix = "--"; varMod.addConfigurationOption(binOp1); BinaryOption binOp2 = new BinaryOption(varMod, "binOpt2"); binOp2.Optional = true; binOp2.Prefix = "-?"; binOp2.Postfix = "kg"; binOp2.Parent = binOp1; binOp2.OutputString = "binOpt2"; varMod.addConfigurationOption(binOp2); BinaryOption binOp3 = new BinaryOption(varMod, "binOpt3"); binOp3.Optional = true; binOp3.Prefix = ""; binOp3.Postfix = ""; binOp3.Parent = binOp1; List<List<ConfigurationOption>> exclude = new List<List<ConfigurationOption>>(); List<ConfigurationOption> subExclude = new List<ConfigurationOption>(); subExclude.Add(binOp2); exclude.Add(subExclude); binOp3.Excluded_Options = exclude; varMod.addConfigurationOption(binOp3); BinaryOption binOp4 = new BinaryOption(varMod, "binOpt4"); binOp4.Optional = true; binOp4.Prefix = "4_"; binOp4.Postfix = "_4"; binOp4.Parent = binOp1; List<List<ConfigurationOption>> implied = new List<List<ConfigurationOption>>(); List<ConfigurationOption> subimplied = new List<ConfigurationOption>(); subimplied.Add(binOp2); implied.Add(subimplied); binOp4.Implied_Options = implied; varMod.addConfigurationOption(binOp4); // -------------------- NUMERIC OPTIONS ---------------- NumericOption numOpt1 = new NumericOption(varMod, "numOpt1"); numOpt1.DefaultValue = 0.0; numOpt1.Prefix = "num1-"; numOpt1.Postfix = "--"; numOpt1.Min_value = 0; numOpt1.Max_value = 10; numOpt1.StepFunction = new InfluenceFunction("n + 2"); varMod.addConfigurationOption(numOpt1); NumericOption numOpt2 = new NumericOption(varMod, "numOpt2"); numOpt2.DefaultValue = 0.8; numOpt2.Prefix = ""; numOpt2.Postfix = ""; numOpt2.Min_value = 0.1; numOpt2.Max_value = 5; numOpt2.StepFunction = new InfluenceFunction("n * 2"); varMod.addConfigurationOption(numOpt2); return varMod; }
/// <summary> /// Generates configurations based on the feature-wise heuristic: The method utilizes the structure of the variability model by first determining the set of options that are always selected. /// In each iteration, it starts from this set of options (partial configuration) and adds a single option to this partial configurations. /// It then checks whether configuration is valid and if not calls a CSP solver to make this configuration valid with as few selected options as possible. /// </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>> generateFeatureWiseConfigurations(VariabilityModel vm) { configurations.Clear(); List<BinaryOption> optionalFirstLevelElements = new List<BinaryOption>(); List<BinaryOption> binOptions = vm.BinaryOptions; //First: Add options that are present in all configurations List<BinaryOption> firstLevelMandatoryFeatures = new List<BinaryOption>(); foreach (BinaryOption binOpt in binOptions) { if (binOpt.Parent == null || binOpt.Parent == vm.Root) { if (!binOpt.Optional) { if (!binOpt.hasAlternatives()) { firstLevelMandatoryFeatures.Add(binOpt); //Todo: Recursive down search /*List<BinaryOption> tmpList = (List<BinaryOption>)vm.getMandatoryChildsRecursive(binOpt); if (tmpList != null && tmpList.Count > 0) firstLevelMandatoryFeatures.AddRange(tmpList);*/ } } else optionalFirstLevelElements.Add(binOpt); } } Solver.CheckConfigSAT checkSAT = new Solver.CheckConfigSAT(null); Solver.VariantGenerator generator = new Solver.VariantGenerator(null); //Generating new configurations: one per option if (checkSAT.checkConfigurationSAT(firstLevelMandatoryFeatures, vm, false)) this.configurations.Add(firstLevelMandatoryFeatures); foreach (BinaryOption e in binOptions) { BinaryOption[] temp = new BinaryOption[firstLevelMandatoryFeatures.Count]; firstLevelMandatoryFeatures.CopyTo(temp); List<BinaryOption> tme = temp.ToList<BinaryOption>(); if (!tme.Contains(e)) { tme.Add(e); if (checkSAT.checkConfigurationSAT(tme, vm, false)) { if (!this.configurations.Contains(tme)) this.configurations.Add(tme); } else { tme = generator.minimizeConfig(tme, vm, true, null); if (tme != null && Configuration.containsBinaryConfiguration(this.configurations, tme) == false) this.configurations.Add(tme); } } else continue; } return this.configurations; }
private void button6_Click(object sender, EventArgs e) { if (this.optionName.Text != "") { if (this.optionName.Text.Contains("-")) { hintLabel.Text = ("No '-' in option name!"); return; } ConfigurationOption newOption = null; if (numericButton.Checked) { newOption = new NumericOption(GlobalState.varModel, this.optionName.Text); ((NumericOption)newOption).Min_value = Convert.ToDouble(minValue.Text); ((NumericOption)newOption).Max_value = Convert.ToDouble(maxValue.Text); ((NumericOption)newOption).StepFunction = new InfluenceFunction(stepSize.Text, (NumericOption)newOption); ((NumericOption)newOption).Prefix = prefix.Text; ((NumericOption)newOption).Postfix = suffix.Text; } else { newOption = new BinaryOption(GlobalState.varModel, this.optionName.Text); } if (this.parentBox.Text.Length > 0) newOption.Parent = GlobalState.varModel.getOption(this.parentBox.Text); if (!GlobalState.varModel.addConfigurationOption(newOption)) { hintLabel.Text = ("Option with the name already exists."); return; } this.Dispose(); GlobalState.varModel.addConfigurationOption(newOption); } else { hintLabel.Text = ("Some values are missing!"); } }
/// <summary> /// This method searches for a corresponding methods in the dynamically loadeda assemblies and calls it if found. It prefers due to performance reasons the Microsoft Solver Foundation implementation. /// </summary> /// <param name="optionToBeRemoved">The binary configuration option that must not be part of the new configuration.</param> /// <param name="originalConfig">The configuration for which we want to find a similar one.</param> /// <param name="removedElements">If further options need to be removed from the given configuration to build a valid configuration, they are outputed in this list.</param> /// <param name="vm">The variability model containing all options and their constraints.</param> /// <returns>A configuration that is valid, similar to the original configuration and does not contain the optionToBeRemoved.</returns> public List<BinaryOption> generateConfigWithoutOption(BinaryOption optionToBeRemoved, List<BinaryOption> originalConfig, out List<BinaryOption> removedElements, VariabilityModel vm) { foreach (Lazy<IVariantGenerator, ISolverType> solver in solvers) { if (solver.Metadata.SolverType.Equals("MSSolverFoundation")) return solver.Value.generateConfigWithoutOption(optionToBeRemoved, originalConfig, out removedElements, vm); } //If not MS Solver, take any solver. Should be changed when supporting more than 2 solvers here foreach (Lazy<IVariantGenerator, ISolverType> solver in solvers) { return solver.Value.generateConfigWithoutOption(optionToBeRemoved, originalConfig, out removedElements, vm); } removedElements = null; return null; }