/// <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-funcitonal 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; }
/// <summary> /// Clears the global state. This mehtod should be used after performing all experiments of one case study. /// </summary> public static void clear() { varModel = null; currentNFP = null; allMeasurements = new ResultDB(); evalutionSet = new ResultDB(); infModel = null; nfProperties = new Dictionary <string, NFProperty>(); }
/// <summary> /// Clears the global state. This mehtod should be used after performing all experiments of one case study. /// </summary> public static void clear() { varModel = null; currentNFP = null; allMeasurements = new ResultDB(); evaluationSet = new ResultDB(); nfProperties = new Dictionary <string, NFProperty>(); optionOrder = new List <ConfigurationOption>(); }
/// <summary> /// Clears the global state. This mehtod should be used after performing all experiments of one case study. /// </summary> public static void clear() { varModel = null; currentNFP = null; allMeasurements = new ResultDB(); evalutionSet = new ResultDB(); infModel = null; nfProperties = new Dictionary<string,NFProperty>(); optionOrder = new List<ConfigurationOption>(); }
/// <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="nfp">The non-funcitonal 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) { foreach (Lazy<ISolverLP, ISolverType> solver in solvers) { if (solver.Metadata.SolverType.Equals("MSSolverFoundation")) return solver.Value.computeOptionInfluences(nfp, infModel, db); } //If not MS Solver, take any solver. Should be changed when supporting more than 2 solvers here foreach (Lazy<ISolverLP, ISolverType> solver in solvers) { return solver.Value.computeOptionInfluences(nfp, infModel, db); } return null; }
/// <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="nfp">The non-funcitonal 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 the variability model, all configuration options and interactions.</param> /// <param name="db">The result database containing the measurements.</param> /// <param name="evaluateFeatureInteractionsOnly">Only interactions are learned.</param> /// <param name="withDeviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <param name="deviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <returns>Returns the learned infleunces of each option in a map whereas the String (Key) is the name of the option / interaction.</returns> public Dictionary<string, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db, bool evaluateFeatureInteractionsOnly, bool withDeviation, double deviation) { foreach (Lazy<ISolverLP, ISolverType> solver in solvers) { if (solver.Metadata.SolverType.Equals("MSSolverFoundation")) return solver.Value.computeOptionInfluences(nfp, infModel, db, evaluateFeatureInteractionsOnly, withDeviation, deviation); } //If not MS Solver, take any solver. Should be changed when supporting more than 2 solvers here foreach (Lazy<ISolverLP, ISolverType> solver in solvers) { return solver.Value.computeOptionInfluences(nfp, infModel, db, evaluateFeatureInteractionsOnly, withDeviation, deviation); } return null; }
/// <summary> /// Computes the influence of all configuration options and interactions 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-funcitonal 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 the variability model, all configuration options and interactions.</param> /// <param name="db">The result database containing the measurements.</param> /// <param name="evaluateFeatureInteractionsOnly">Only interactions are learned.</param> /// <param name="withDeviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <param name="deviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <returns>Returns the learned infleunces of each option in a map whereas the String (Key) is the name of the option / interaction.</returns> public Dictionary<String, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db, bool evaluateFeatureInteractionsOnly, bool withDeviation, double deviation) { //Initialization List<List<BinaryOption>> configurations = new List<List<BinaryOption>>(); this.evaluateInteractionsOnly = evaluateFeatureInteractionsOnly; this.withStandardDeviation = withDeviation; this.standardDeviation = deviation; List<double> results = new List<double>(); 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<BinaryOption> variables = new List<BinaryOption>(); Dictionary<String, double> featureValues = new Dictionary<string, double>(); Dictionary<String, double> faultRates = new Dictionary<string, double>(); List<int> indexOfErrorMeasurements = new List<int>(); if (configurations.Count == 0) return null; //For the case there is an empty base if (configurations.Count != 0) { if (configurations[0].Count == 0) {//Should never occur that we get a configuration with no option selected... at least the root must be there BinaryOption root = infModel.Vm.Root; //Element baseElement = new Element("base_gen", infModel.getID(), infModel); //variables.Add(baseElement); // featureValues.Add(baseElement.getName(), 0); foreach (List<BinaryOption> config in configurations) if(!config.Contains(root)) config.Insert(0, root); } } //Building the variable list foreach (var elem in infModel.Vm.BinaryOptions) { variables.Add(elem); featureValues.Add(elem.Name, 0); } //First run featureValues = solve(variables, results, configurations, null); //if (evaluateFeatureInteractionsOnly == false) return featureValues; /* //We might have some interactions here and cannot compute all values //1. identify options that are only present in these equations Dictionary<Element, int> featureCounter = new Dictionary<Element, int>(); for (int i = 0; i < indexOfErrorMeasurements.Count; i++) { } */ /*Todo: get compute interactins from deviations / errors of the LP results if (errorEqs != null) { foreach (string eq in errorEqs) { double value = Double.Parse(eq.Substring(eq.IndexOf("==") + 2)); StringBuilder sb = new StringBuilder(); List<Element> derivativeParents = new List<Element>(); sb.Append("derivate_"); string[] splittedEQ = eq.Split('+'); foreach (string element in splittedEQ) { string name = element; if (name.Contains("==")) name = name.Substring(0, name.IndexOf("==")); if (name.Contains("yp") && name.Contains("-yn")) continue; // string featureName = name.Substring(0, name.IndexOf("_p-")); Element elem = infModel.getElementByNameUnsafe(name); if (elem == null) continue; sb.Append("_" + name); derivativeParents.Add(elem); } Element interaction = new Element(sb.ToString(), infModel.getID(), infModel); interaction.setType("derivative"); interaction.addDerivativeParents(derivativeParents); infModel.addElement(interaction); this.featureValues.Add(interaction, value); } } return featureValues;*/ }