/// <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 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())));
        }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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);
            }
        }
示例#5
0
 /// <summary>
 /// This constructor creates a new <see cref="ConstraintSystemCache"/> with the given parameters.
 /// </summary>
 /// <param name="cs">The <see cref="ConstraintSystem"/> to store.</param>
 /// <param name="variables">The variables used in the <see cref="ConstraintSystem"/>.</param>
 /// <param name="elemToTerm">The mapping from <see cref="BinaryOption"/> to <see cref="CspTerm"/>.</param>
 /// <param name="termToElem">The mapping from <see cref="CspTerm"/> to <see cref="BinaryOption"/>.</param>
 public ConstraintSystemCache(ConstraintSystem cs, List <CspTerm> variables, Dictionary <BinaryOption, CspTerm> elemToTerm, Dictionary <CspTerm, BinaryOption> termToElem)
 {
     this._cs         = cs;
     this._variables  = variables;
     this._elemToTerm = elemToTerm;
     this._termToElem = termToElem;
 }
        /// <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);
        }
示例#7
0
        public ComprehensionData(Node node, ConstraintSystem owner, int depth)
        {
            Contract.Requires(node != null && owner != null && depth > 0);
            Contract.Requires(node.NodeKind == NodeKind.Compr);

            Node  = node;
            Owner = owner;
            Depth = depth;
        }
示例#8
0
        public ZebraPuzzleConstraints(ConstraintSystem solver)
        {
            Solver       = solver;
            HouseNumbers = ThereAreFiveHouses();

            ColourMatrix      = CreateConstrainSystemMatrix(Solver);
            DrinkMatrix       = CreateConstrainSystemMatrix(Solver);
            NationalityMatrix = CreateConstrainSystemMatrix(Solver);
            SmokeMatrix       = CreateConstrainSystemMatrix(Solver);
            PetMatrix         = CreateConstrainSystemMatrix(Solver);
        }
示例#9
0
        static void Main()
        {
            var solver      = ConstraintSystem.CreateSolver();
            var constraints = new ZebraPuzzleConstraints(solver);

            solver = AddConstraintsToSolver(solver, constraints);

            var solution      = solver.Solve(new ConstraintSolverParams());
            var solutionTable = ConvertToSolutionTable(solution, constraints);

            WriteZebraSolutionToConsole(solutionTable);
            WriteSolutionForAllTheHousesToConsole(solutionTable);
        }
示例#10
0
        public void Solve(int?[,] field)
        {
            ConstraintSystem S = ConstraintSystem.CreateSolver();
            CspDomain        Z = S.CreateIntegerInterval(1, 9);

            CspTerm[][] sudoku = S.CreateVariableArray(Z, "cell", 9, 9);
            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    if (field[row, col] > 0)
                    {
                        S.AddConstraints(S.Equal(field[row, col] ?? 0, sudoku[row][col]));
                    }
                }
                S.AddConstraints(S.Unequal(GetSlice(sudoku, row, row, 0, 8)));
            }
            for (int col = 0; col < 9; col++)
            {
                S.AddConstraints(S.Unequal(GetSlice(sudoku, 0, 8, col, col)));
            }
            for (int a = 0; a < 3; a++)
            {
                for (int b = 0; b < 3; b++)
                {
                    S.AddConstraints(S.Unequal(GetSlice(sudoku, a * 3, a * 3 + 2, b * 3, b * 3 + 2)));
                }
            }
            ConstraintSolverSolution soln = S.Solve();

            if (!soln.HasFoundSolution)
            {
                throw new NoSolutionException("Для поставленной цифры нет решение!");
            }


            object[] h = new object[9];
            for (int row = 0; row < 9; row++)
            {
                if ((row % 3) == 0)
                {
                    System.Console.WriteLine();
                }
                for (int col = 0; col < 9; col++)
                {
                    soln.TryGetValue(sudoku[row][col], out h[col]);
                }
                System.Console.WriteLine("{0}{1}{2} {3}{4}{5} {6}{7}{8}", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8]);
            }
        }
        /// <summary>
        /// Generates all valid combinations of all configuration options in the given model.
        /// </summary>
        /// <param name="vm">the variability model containing the binary options and their constraints</param>
        /// <param name="optionsToConsider">the options that should be considered. All other options are ignored</param>
        /// <returns>Returns a list of <see cref="Configuration"/></returns>
        public List <Configuration> GenerateAllVariants(VariabilityModel vm, List <ConfigurationOption> optionsToConsider)
        {
            List <Configuration>       allConfigurations = new List <Configuration>();
            Dictionary <CspTerm, bool> variables;
            Dictionary <ConfigurationOption, CspTerm> optionToTerm;
            Dictionary <CspTerm, ConfigurationOption> termToOption;
            ConstraintSystem S = CSPsolver.GetGeneralConstraintSystem(out variables, out optionToTerm, out termToOption, vm);

            ConstraintSolverSolution soln = S.Solve();

            while (soln.HasFoundSolution)
            {
                Dictionary <BinaryOption, BinaryOption.BinaryValue> binOpts = new Dictionary <BinaryOption, BinaryOption.BinaryValue>();
                Dictionary <NumericOption, double> numOpts = new Dictionary <NumericOption, double>();

                foreach (CspTerm ct in variables.Keys)
                {
                    // Ignore all options that should not be considered.
                    if (!optionsToConsider.Contains(termToOption[ct]))
                    {
                        continue;
                    }

                    // If it is a binary option
                    if (variables[ct])
                    {
                        BinaryOption.BinaryValue isSelected = soln.GetIntegerValue(ct) == 1 ? BinaryOption.BinaryValue.Selected : BinaryOption.BinaryValue.Deselected;
                        if (isSelected == BinaryOption.BinaryValue.Selected)
                        {
                            binOpts.Add((BinaryOption)termToOption[ct], isSelected);
                        }
                    }
                    else
                    {
                        numOpts.Add((NumericOption)termToOption[ct], soln.GetIntegerValue(ct));
                    }
                }

                Configuration c = new Configuration(binOpts, numOpts);

                // Check if the non-boolean constraints are satisfied
                if (vm.configurationIsValid(c) && !IsInConfigurationFile(c, allConfigurations) && FulfillsMixedConstraints(c, vm))
                {
                    allConfigurations.Add(c);
                }
                soln.GetNext();
            }

            return(allConfigurations);
        }
示例#12
0
        /// <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="exact">Checks also the number of selected options such that it returns only true if exactly the given configuration is valid
        /// (e.g., if we need to select more features to get a valid config, it returns false if exact is set to true).
        /// <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 exact)
        {
            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 (exact)
                    {
                        S.AddConstraints(S.Implies(S.True, S.Not(term)));
                    }
                }
            }

            ConstraintSolverSolution sol = S.Solve();

            if (sol.HasFoundSolution)
            {
                int count = 0;
                foreach (CspTerm cT in variables)
                {
                    if (sol.GetIntegerValue(cT) == 1)
                    {
                        count++;
                    }
                }
                //Needs testing TODO
                if (count != config.Count && exact == true)
                {
                    return(false);
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#13
0
        internal Action(
            Node head,
            ConstraintSystem body,
            TypeEnvironment typeEnv,
            ComprehensionData comprData = null,
            Node configurationContext   = null)
        {
            Head        = head;
            Body        = body;
            myComprData = comprData;
            this.configurationContext = configurationContext;

            typeEnvironment = typeEnv;
            theUnnSymbol    = body.Index.SymbolTable.GetOpSymbol(ReservedOpKind.TypeUnn);
            theRngSymbol    = body.Index.SymbolTable.GetOpSymbol(ReservedOpKind.Range);
        }
示例#14
0
        public override void AddConstaint()
        {
            ConstraintSystem solver     = ConstraintSystemSolver.Instance.Solver;
            CspTerm          constraint = null;

            CspTerm inputTerm  = Input1.CspTerm;
            CspTerm outputTerm = Output.CspTerm;


            Type consType = type;

            if (IsNotHealthy)
            {
                // In case the gate is Broken (Not Healthy) - we don't want to add any constraint!!!
                return;

                /*
                 * switch (type)
                 * {
                 *  case Type.buffer:
                 *      consType = Type.not;
                 *      break;
                 *  case Type.not:
                 *      consType = Type.buffer;
                 *      break;
                 * }
                 */
            }

            lock (ConstraintSystemSolver.Instance.Locker)
            {
                //Debug.WriteLine("SAT IN!");
                switch (consType)
                {
                case Type.buffer:
                    constraint = solver.Equal(inputTerm, outputTerm);
                    break;

                case Type.not:
                    constraint = solver.Equal(inputTerm, solver.Not(outputTerm));
                    break;
                }

                solver.AddConstraints(constraint);
                //Debug.WriteLine("SAT OUT!");
            }
        }
示例#15
0
        static void Main(string[] args)
        {
            ConstraintSystem s1 = ConstraintSystem.CreateSolver();

            // () and ()
            CspTerm p1 = s1.CreateBoolean("p1");
            CspTerm p2 = s1.CreateBoolean("p2");
            CspTerm p3 = s1.CreateBoolean("p3");
            CspTerm p4 = s1.CreateBoolean("p4");

            var x = new CspDomain();

            CspTerm test = s1.And(s1.Or(p1, s1.And(s1.Neg(p3)), s1.Neg(p1)), s1.And(p2, s1.Neg(s1.Difference(p1, p2))));

            CspTerm tOr12 = s1.Or(s1.Neg(t1), s1.Neg(t2));
            CspTerm tOr13 = s1.Or(s1.Neg(t1), s1.Neg(t3));
            CspTerm tOr14 = s1.Or(s1.Neg(t1), s1.Neg(t4));

            CspTerm tOr23 = s1.Or(s1.Neg(t2), s1.Neg(t3));
            CspTerm tOr24 = s1.Or(s1.Neg(t2), s1.Neg(t4));

            CspTerm tOr34 = s1.Or(s1.Neg(t3), s1.Neg(t4));

            CspTerm tOr = s1.Or(t1, t2, t3, t4);

            s1.AddConstraints(tOr12);
            s1.AddConstraints(tOr13);
            s1.AddConstraints(tOr14);
            s1.AddConstraints(tOr23);
            s1.AddConstraints(tOr24);
            s1.AddConstraints(tOr34);
            s1.AddConstraints(tOr);

            ConstraintSolverSolution solution1 = s1.Solve();

            if (solution1.HasFoundSolution)
            {
                Console.WriteLine("Is Satisfiable");
            }
            else
            {
                Console.WriteLine("Not satisfiable");
            }

            Console.ReadKey();
        }
示例#16
0
        private List <List <BinaryOption> > generateTilSize(int i1, int size, int timeout, VariabilityModel vm)
        {
            var            foundSolutions = 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);

            CspTerm t = S.ExactlyMofN(i1, variables.ToArray());

            S.AddConstraints(new CspTerm[] { t });
            var csp = new ConstraintSolverParams
            {
                TimeLimitMilliSec = timeout * 1000,
            };
            ConstraintSolverSolution soln = S.Solve(csp);

            int counter = 0;

            while (soln.HasFoundSolution)
            {
                List <BinaryOption> tempConfig = (
                    from cT
                    in variables
                    where soln.GetIntegerValue(cT) == 1
                    select termToElem[cT]).ToList();

                if (tempConfig.Contains(null))
                {
                    tempConfig.Remove(null);
                }

                foundSolutions.Add(tempConfig);
                counter++;
                if (counter == size)
                {
                    break;
                }
                soln.GetNext();
            }
            //Console.WriteLine(i1 + "\t" + foundSolutions.Count);
            return(foundSolutions);
        }
        /// <summary>
        /// Creates a sample of configurations, by iteratively adding a configuration that has the maximal manhattan distance
        /// to the configurations that were previously selected.
        /// </summary>
        /// <param name="vm">The domain for sampling.</param>
        /// <param name="minimalConfiguration">A minimal configuration that will be used as starting point.</param>
        /// <param name="numberToSample">The number of configurations that should be sampled.</param>
        /// <param name="optionWeight">Weight assigned to optional binary options.</param>
        /// <returns>A list of distance maximized configurations.</returns>
        public List <List <BinaryOption> > DistanceMaximization(VariabilityModel vm, List <BinaryOption> minimalConfiguration, int numberToSample, int optionWeight)
        {
            List <Configuration>        sample          = new List <Configuration>();
            List <List <BinaryOption> > convertedSample = new List <List <BinaryOption> >();

            sample.Add(new Configuration(minimalConfiguration));
            convertedSample.Add(minimalConfiguration);

            List <CspTerm> variables = new List <CspTerm>();
            Dictionary <BinaryOption, CspTerm> elemToTerm = new Dictionary <BinaryOption, CspTerm>();
            Dictionary <CspTerm, BinaryOption> termToElem = new Dictionary <CspTerm, BinaryOption>();


            while (sample.Count < numberToSample)
            {
                ConstraintSystem S = CSPsolver.getConstraintSystem(out variables, out elemToTerm, out termToElem, vm);
                addDistanceMaximiationGoal(sample, vm, elemToTerm, S, optionWeight);
                ConstraintSolverSolution sol = S.Solve();
                if (sol.HasFoundSolution)
                {
                    List <BinaryOption> solution = new List <BinaryOption>();
                    foreach (CspTerm cT in variables)
                    {
                        if (sol.GetIntegerValue(cT) == 1)
                        {
                            solution.Add(termToElem[cT]);
                        }
                    }
                    S.ResetSolver();
                    convertedSample.Add(solution);
                    sample.Add(new Configuration(solution));
                }
                else
                {
                    GlobalState.logInfo.logLine("No more solutions available.");
                    return(convertedSample);
                }
            }

            return(convertedSample);
        }
示例#18
0
        CspTerm[][] CreateConstrainSystemMatrix(ConstraintSystem system)
        {
            var size   = HouseNumbers.Count;
            var matrix = system.CreateBooleanArray(new object(), size, size);

            Enumerable.Range(0, size).ToList().ForEach(i =>
            {
                var row    = system.CreateBooleanVector(new object(), size);
                var column = system.CreateBooleanVector(new object(), size);

                Enumerable.Range(0, size).ToList().ForEach(j =>
                {
                    row[j]    = matrix[i][j];
                    column[j] = matrix[j][i];
                });

                system.AddConstraints(system.Equal(1, system.Sum(row)));
                system.AddConstraints(system.Equal(1, system.Sum(column)));
            });

            return(matrix);
        }
示例#19
0
        /* public List<List<string>> generateDimacsPseudoRandom(string[] lines,int features, int randomsize, BackgroundWorker worker)
         * {
         *   var cts = new CancellationTokenSource();
         *   var erglist = new List<List<string>>();
         *
         *   var tasks = new Task[features];
         *   var mylock = new object();
         *
         *   for (var i = 0; i < features; i++)
         *   {
         *       var i1 = i;
         *       tasks[i] = Task.Factory.StartNew(() =>
         *       {
         *           Console.WriteLine("Starting: " + i1);
         *           var sw = new Stopwatch();
         *           sw.Start();
         *           var result = generateDimacsSize(lines, i1, randomsize);
         *           sw.Stop();
         *           Console.WriteLine("Done: " + i1 + "\tDuration: " + sw.ElapsedMilliseconds + "\tResults: " + result.Count);
         *           return result;
         *
         *       }, cts.Token).ContinueWith(task =>
         *       {
         *           lock (mylock)
         *           {
         *
         *               erglist.AddRange(task.Result);
         *
         *               Console.WriteLine("Added results: " + i1 + "\tResults now: " + erglist.Count);
         *               counter++;
         *               //worker.ReportProgress((int)(counter * 100.0f / (double)features), erglist.Count);
         *           }
         *       });
         *
         *       if (Task.WaitAny(new[] { tasks[i] }, TimeSpan.FromMilliseconds(60 * 1000)) < 0)
         *       {
         *           cts.Cancel();
         *       }
         *   }
         *
         *   Task.WaitAll(tasks);
         *
         *   return erglist;
         * } */



        /// <summary>
        /// Simulates a simple method to get valid configurations of binary options of a variability model. The randomness is simulated by the modulu value.
        /// We take only the modulu'th configuration into the result set based on the CSP solvers output. If modulu is larger than the number of valid variants, the result set is empty.
        /// </summary>
        /// <param name="vm">The variability model containing the binary options and their constraints.</param>
        /// <param name="treshold">Maximum number of configurations</param>
        /// <param name="modulu">Each configuration that is % modulu == 0 is taken to the result set. Can be less than the maximal (i.e. threshold) specified number of configurations.</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> > generateRandomVariants(VariabilityModel vm, int treshold, int modulu)
        {
            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);
            List <List <BinaryOption> > erglist = new List <List <BinaryOption> >();
            ConstraintSolverSolution    soln    = S.Solve();
            int mod = 0;

            while (soln.HasFoundSolution)
            {
                mod++;
                if (mod % modulu != 0)
                {
                    soln.GetNext();
                    continue;
                }
                List <BinaryOption> tempConfig = new List <BinaryOption>();
                foreach (CspTerm cT in variables)
                {
                    if (soln.GetIntegerValue(cT) == 1)
                    {
                        tempConfig.Add(termToElem[cT]);
                    }
                }
                if (tempConfig.Contains(null))
                {
                    tempConfig.Remove(null);
                }
                erglist.Add(tempConfig);
                if (erglist.Count == treshold)
                {
                    break;
                }
                soln.GetNext();
            }
            return(erglist);
        }
        /// <summary>
        /// Simulates a simple method to get valid configurations of binary options of a variability model. The randomness is simulated by the modulu value.
        /// We take only the modulu'th configuration into the result set based on the CSP solvers output. If modulu is larger than the number of valid variants, the result set is empty.
        /// </summary>
        /// <param name="vm">The variability model containing the binary options and their constraints.</param>
        /// <param name="treshold">Maximum number of configurations</param>
        /// <param name="modulu">Each configuration that is % modulu == 0 is taken to the result set</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> > GenerateRandomVariants(VariabilityModel vm, int treshold, int modulu)
        {
            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);
            List <List <BinaryOption> > erglist = new List <List <BinaryOption> >();
            ConstraintSolverSolution    soln    = S.Solve();

            List <List <BinaryOption> > allConfigs = new List <List <BinaryOption> >();

            while (soln.HasFoundSolution)
            {
                soln.GetNext();
                List <BinaryOption> tempConfig = new List <BinaryOption>();
                foreach (CspTerm cT in variables)
                {
                    if (soln.GetIntegerValue(cT) == 1)
                    {
                        tempConfig.Add(termToElem[cT]);
                    }
                }
                if (tempConfig.Contains(null))
                {
                    tempConfig.Remove(null);
                }
                allConfigs.Add(tempConfig);
            }

            Random r = new Random(modulu);

            for (int i = 0; i < treshold; i++)
            {
                erglist.Add(allConfigs[r.Next(allConfigs.Count)]);
            }
            return(erglist);
        }
示例#21
0
        private static ConstraintSystem AddConstraintsToSolver(
            ConstraintSystem solver, ZebraPuzzleConstraints constraints)
        {
            solver.AddConstraints(
                constraints.TheEnglishManLivesInTheRedHouse());
            solver.AddConstraints(
                constraints.TheSwedeHasADog());
            solver.AddConstraints(
                constraints.TheDaneDrinksTea());
            solver.AddConstraints(
                constraints.TheGreenHouseIsImmediatelyLeftOfTheWhiteHouse());
            solver.AddConstraints(
                constraints.TheyDrinkCoffeeInTheGreenHouse());
            solver.AddConstraints(
                constraints.TheManWhoSmokesPallMallHasBirds());
            solver.AddConstraints(
                constraints.InTheYellowHouseTheySmokeDunhill());
            solver.AddConstraints(
                constraints.InTheMiddleHouseTheyDrinkMilk());
            solver.AddConstraints(
                constraints.TheNorwegianLivesInTheFirstHouse());
            solver.AddConstraints(
                constraints.TheManWhoSmokesBlendInHouseNextToHouseWithCats());
            solver.AddConstraints(
                constraints.InHouseNextToHouseWhereHaveAHorseSmokeDunhill());
            solver.AddConstraints(
                constraints.TheManWhoSmokesBlueMasterDrinksBeer());
            solver.AddConstraints(
                constraints.TheGermanSmokesPrince());
            solver.AddConstraints(
                constraints.TheNorwegianLivesNextToTheBlueHouse());
            solver.AddConstraints(
                constraints.TheyDrinkWaterInHouseNextToHouseWhereSmokeBlend());

            return(solver);
        }
        /// <summary>
        /// Generates a constraint system based on a variability model. The constraint system can be used to check for satisfiability of configurations as well as optimization.
        /// </summary>
        /// <param name="variables">Empty input, outputs a list of CSP terms that correspond to the configuration options of the variability model</param>
        /// <param name="optionToTerm">A map to get for a given configuration option the corresponding CSP term of the constraint system</param>
        /// <param name="termToOption">A map that gives for a given CSP term the corresponding configuration option of the variability model</param>
        /// <param name="vm">The variability model for which we generate a constraint system</param>
        /// <returns>The generated constraint system consisting of logical terms representing configuration options as well as their boolean constraints.</returns>
        internal static ConstraintSystem getConstraintSystem(out List<CspTerm> variables, out Dictionary<BinaryOption, CspTerm> optionToTerm, out Dictionary<CspTerm, BinaryOption> termToOption, VariabilityModel vm)
        {
            //Reusing seems to not work correctely. The problem: configurations are realized as additional constraints for the system.
            //however, when checking for the next config, the old config's constraints remain in the solver such that we have a wrong result.
            /*
            if (csystem != null && variables_global != null && optionToTerm_global != null && termToOption_global != null && vm != null)
            {//For optimization purpose
                if (vm.BinaryOptions.Count == vm_global.BinaryOptions.Count && vm.Name.Equals(vm_global.Name))
                {
                    variables = variables_global;
                    optionToTerm = optionToTerm_global;
                    termToOption = termToOption_global;
                    return csystem;
                }
            }*/

            ConstraintSystem S = ConstraintSystem.CreateSolver();

            optionToTerm = new Dictionary<BinaryOption, CspTerm>();
            termToOption = new Dictionary<CspTerm, BinaryOption>();
            variables = new List<CspTerm>();
            foreach (BinaryOption binOpt in vm.BinaryOptions)
            {
                CspDomain domain = S.DefaultBoolean;
                CspTerm temp = S.CreateVariable(domain, binOpt);
                optionToTerm.Add(binOpt, temp);
                termToOption.Add(temp, binOpt);
                variables.Add(temp);
            }

            List<List<ConfigurationOption>> alreadyHandledAlternativeOptions = new List<List<ConfigurationOption>>();

            //Constraints of a single configuration option
            foreach (BinaryOption current in vm.BinaryOptions)
            {
                CspTerm cT = optionToTerm[current];
                if (current.Parent == null || current.Parent == vm.Root)
                {
                    if (current.Optional == false && current.Excluded_Options.Count == 0)
                        S.AddConstraints(S.Implies(S.True, cT));
                    else
                        S.AddConstraints(S.Implies(cT, optionToTerm[vm.Root]));
                }

                if (current.Parent != null && current.Parent != vm.Root)
                {
                    CspTerm parent = optionToTerm[(BinaryOption)current.Parent];
                    S.AddConstraints(S.Implies(cT, parent));
                    if (current.Optional == false && current.Excluded_Options.Count == 0)
                        S.AddConstraints(S.Implies(parent, cT));//mandatory child relationship
                }

                //Alternative or other exclusion constraints
                if (current.Excluded_Options.Count > 0)
                {
                    List<ConfigurationOption> alternativeOptions = current.collectAlternativeOptions();
                    if (alternativeOptions.Count > 0)
                    {
                        //Check whether we handled this group of alternatives already
                        foreach (var alternativeGroup in alreadyHandledAlternativeOptions)
                            foreach (var alternative in alternativeGroup)
                                if (current == alternative)
                                    goto handledAlternative;

                        //It is not allowed that an alternative group has no parent element
                        CspTerm parent = null;
                        if (current.Parent == null)
                            parent = S.True;
                        else
                            parent = optionToTerm[(BinaryOption)current.Parent];

                        CspTerm[] terms = new CspTerm[alternativeOptions.Count + 1];
                        terms[0] = cT;
                        int i = 1;
                        foreach (BinaryOption altEle in alternativeOptions)
                        {
                            CspTerm temp = optionToTerm[altEle];
                            terms[i] = temp;
                            i++;
                        }
                        S.AddConstraints(S.Implies(parent, S.ExactlyMofN(1, terms)));
                        alreadyHandledAlternativeOptions.Add(alternativeOptions);
                        handledAlternative: { }
                    }

                    //Excluded option(s) as cross-tree constraint(s)
                    List<List<ConfigurationOption>> nonAlternative = current.getNonAlternativeExlcudedOptions();
                    if(nonAlternative.Count > 0) {
                        foreach(var excludedOption in nonAlternative){
                            CspTerm[] orTerm = new CspTerm[excludedOption.Count];
                            int i = 0;
                            foreach (var opt in excludedOption)
                            {
                                CspTerm target = optionToTerm[(BinaryOption)opt];
                                orTerm[i] = target;
                                i++;
                            }
                            S.AddConstraints(S.Implies(cT, S.Not(S.Or(orTerm))));
                        }
                    }
                }
                //Handle implies
                if (current.Implied_Options.Count > 0)
                {
                    foreach (List<ConfigurationOption> impliedOr in current.Implied_Options)
                    {
                        CspTerm[] orTerms = new CspTerm[impliedOr.Count];
                        //Possible error: if a binary option impies a numeric option
                        for (int i = 0; i < impliedOr.Count; i++)
                            orTerms[i] = optionToTerm[(BinaryOption)impliedOr.ElementAt(i)];
                        S.AddConstraints(S.Implies(optionToTerm[current], S.Or(orTerms)));
                    }
                }
            }

            //Handle global cross-tree constraints involving multiple options at a time
            // the constraints should be in conjunctive normal form
            foreach (string constraint in vm.BooleanConstraints)
            {
                bool and = false;
                string[] terms;
                if (constraint.Contains("&"))
                {
                    and = true;
                    terms = constraint.Split('&');
                }
                else
                    terms = constraint.Split('|');

                CspTerm[] cspTerms = new CspTerm[terms.Count()];
                int i = 0;
                foreach (string t in terms)
                {
                    string optName = t.Trim();
                    if (optName.StartsWith("-") || optName.StartsWith("!"))
                    {
                        optName = optName.Substring(1);
                        BinaryOption binOpt = vm.getBinaryOption(optName);
                        CspTerm cspElem = optionToTerm[binOpt];
                        CspTerm notCspElem = S.Not(cspElem);
                        cspTerms[i] = notCspElem;
                    }
                    else
                    {
                        BinaryOption binOpt = vm.getBinaryOption(optName);
                        CspTerm cspElem = optionToTerm[binOpt];
                        cspTerms[i] = cspElem;
                    }
                    i++;
                }
                if (and)
                    S.AddConstraints(S.And(cspTerms));
                else
                    S.AddConstraints(S.Or(cspTerms));
            }
            csystem = S;
            optionToTerm_global = optionToTerm;
            vm_global = vm;
            termToOption_global = termToOption;
            variables_global = variables;
            return S;
        }
        /// <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 expaned 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 <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
            if (config != null)
            {
                foreach (BinaryOption binOpt in config)
                {
                    CspTerm term = elemToTerm[binOpt];
                    S.AddConstraints(S.Implies(S.True, term));
                }
            }
            //Defining Goals
            CspTerm[] finalGoals = new CspTerm[variables.Count];
            for (int r = 0; r < variables.Count; r++)
            {
                if (minimize == true)
                {
                    BinaryOption binOpt = termToElem[variables[r]];
                    if (unwantedOptions != null && (unwantedOptions.Contains(binOpt) && !config.Contains(binOpt)))
                    {
                        finalGoals[r] = variables[r] * 10000;
                    }
                    else
                    {
                        // Element is part of an altnerative Group  ... we want to select always the same option of the group, so we give different weights to the member of the group
                        //Functionality deactivated... todo needs further handling

                        /*if (binOpt.getAlternatives().Count != 0)
                         * {
                         *  finalGoals[r] = variables[r] * (binOpt.getID() * 10);
                         * }
                         * else
                         * {*/
                        finalGoals[r] = variables[r] * 1;
                        //}

                        // wenn in einer alternative, dann bekommt es einen wert nach seiner reihenfolge
                        // id mal 10
                    }
                }
                else
                {
                    finalGoals[r] = variables[r] * -1;   // dynamic cost map
                }
            }
            S.TryAddMinimizationGoals(S.Sum(finalGoals));

            ConstraintSolverSolution    soln          = S.Solve();
            List <string>               erg2          = new List <string>();
            List <BinaryOption>         tempConfig    = new List <BinaryOption>();
            List <List <BinaryOption> > resultConfigs = new List <List <BinaryOption> >();

            while (soln.HasFoundSolution && soln.Quality == ConstraintSolverSolution.SolutionQuality.Optimal)
            {
                tempConfig.Clear();
                foreach (CspTerm cT in variables)
                {
                    if (soln.GetIntegerValue(cT) == 1)
                    {
                        tempConfig.Add(termToElem[cT]);
                    }
                }
                if (minimize && tempConfig != null)
                {
                    resultConfigs.Add(tempConfig);
                    break;
                }
                if (!Configuration.containsBinaryConfiguration(resultConfigs, tempConfig))
                {
                    resultConfigs.Add(tempConfig);
                }
                soln.GetNext();
            }
            return(resultConfigs);
        }
        private void addDistanceMaximiationGoal(List <Configuration> sample, VariabilityModel vm,
                                                Dictionary <BinaryOption, CspTerm> elemToTerm, ConstraintSystem cs, int weight)
        {
            List <CspTerm> goals = new List <CspTerm>();

            foreach (Configuration config in sample)
            {
                List <CspTerm>      sum            = new List <CspTerm>();
                List <BinaryOption> configInSample = convertToBinaryOptionList(config);

                foreach (BinaryOption binOpt in vm.BinaryOptions)
                {
                    if (!configInSample.Contains(binOpt))
                    {
                        if (binOpt.Optional)
                        {
                            sum.Add(weight * elemToTerm[binOpt]);
                        }
                        else
                        {
                            sum.Add(elemToTerm[binOpt]);
                        }
                    }
                    else
                    {
                        if (binOpt.Optional)
                        {
                            sum.Add(weight * (cs.Abs(elemToTerm[binOpt] - cs.Constant(1))));
                        }
                        else
                        {
                            sum.Add(cs.Abs(elemToTerm[binOpt] - cs.Constant(1)));
                        }
                    }
                }
                // negate term because we search for the biggest distance
                goals.Add(-1 * cs.Sum(sum.ToArray()));
            }
            cs.TryAddMinimizationGoals(cs.Sum(goals.ToArray()));
        }
        /// <summary>
        /// This method searches for a corresponding methods in the dynamically loaded assemblies and calls it if found. It prefers due to performance reasons the Microsoft Solver Foundation implementation.
        /// </summary>
        /// <param name="config">The (partial) configuration which needs to be expaned 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>The valid configuration (or null if there is none) that satisfies the VM and the goal.</returns>
        public List <BinaryOption> MinimizeConfig(List <BinaryOption> config, VariabilityModel vm, bool minimize, List <BinaryOption> unWantedOptions)
        {
            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 binOpt in config)
            {
                CspTerm term = elemToTerm[binOpt];
                S.AddConstraints(S.Implies(S.True, term));
            }

            //Defining Goals
            CspTerm[] finalGoals = new CspTerm[variables.Count];
            for (int r = 0; r < variables.Count; r++)
            {
                if (minimize == true)
                {
                    if (unWantedOptions != null && (unWantedOptions.Contains(termToElem[variables[r]]) && !config.Contains(termToElem[variables[r]])))
                    {
                        finalGoals[r] = variables[r] * 100;
                    }
                    else
                    {
                        finalGoals[r] = variables[r] * 1;
                    }
                }
                else
                {
                    finalGoals[r] = variables[r] * -1;   // dynamic cost map
                }
            }

            S.TryAddMinimizationGoals(S.Sum(finalGoals));

            ConstraintSolverSolution soln       = S.Solve();
            List <string>            erg2       = new List <string>();
            List <BinaryOption>      tempConfig = new List <BinaryOption>();

            while (soln.HasFoundSolution)
            {
                tempConfig.Clear();
                foreach (CspTerm cT in variables)
                {
                    if (soln.GetIntegerValue(cT) == 1)
                    {
                        tempConfig.Add(termToElem[cT]);
                    }
                }

                if (minimize && tempConfig != null)
                {
                    break;
                }
                soln.GetNext();
            }
            return(tempConfig);
        }
示例#26
0
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Seleccione el método por el que desea resolver el problema:\n1 Programación por restricciones\n2 Programación Lineal");
                switch (int.Parse(Console.ReadLine()))
                {
                case 1:
                    SolverContext context = new SolverContext();
                    Model         model   = context.CreateModel();
                    // Creación de variables
                    Decision x1 = new Decision(Domain.Integer, "x1");
                    model.AddDecision(x1);
                    Decision x2 = new Decision(Domain.Integer, "x2");
                    model.AddDecision(x2);
                    Decision x3 = new Decision(Domain.Integer, "x3");
                    model.AddDecision(x3);
                    // Creación de limites
                    model.AddConstraint("limitX1", 50 <= x1 <= 300);
                    model.AddConstraint("limitX2", 100 <= x2 <= 200);
                    model.AddConstraint("limitX3", 20 <= x3 <= 1000);
                    // Creación de restricciones
                    model.AddConstraint("restriccion1", 200 <= (x1 + x2 + x3) <= 280);
                    model.AddConstraint("restriccion2", 100 <= (x1 + (3 * x3)) <= 2000);
                    model.AddConstraint("restriccion3", 50 <= ((2 + x1) + (4 * x3)) <= 1000);
                    // Función objetivo
                    model.AddGoal("maximo", GoalKind.Maximize, -(4 * x1) - (2 * x2) + x3);
                    // Solucion
                    Solution solucion = context.Solve(new SimplexDirective());
                    Report   reporte  = solucion.GetReport();
                    // Imprimir
                    Console.WriteLine(reporte);
                    Console.ReadLine();
                    break;

                case 2:
                    //Solucionador específico
                    ConstraintSystem csp = ConstraintSystem.CreateSolver();
                    // Creacíón de variables
                    CspTerm sx1 = csp.CreateVariable(csp.CreateIntegerInterval(50, 300), "x1");
                    CspTerm sx2 = csp.CreateVariable(csp.CreateIntegerInterval(100, 200), "x2");
                    CspTerm sx3 = csp.CreateVariable(csp.CreateIntegerInterval(20, 1000), "x3");
                    // Creación de restricciones
                    csp.AddConstraints(200 <= (sx1 + sx2 + sx3) <= 280,
                                       100 <= sx1 + (3 * sx2) <= 2000,
                                       50 <= (2 * sx1) + (4 * sx3) <= 1000);

                    // Solución
                    ConstraintSolverSolution cspSolucion = csp.Solve();
                    int numero = 1;
                    while (cspSolucion.HasFoundSolution)
                    {
                        object rx1, rx2, rx3;
                        if (!cspSolucion.TryGetValue(sx1, out rx1) || !cspSolucion.TryGetValue(sx2, out rx2) || !cspSolucion.TryGetValue(sx3, out rx3))
                        {
                            throw new InvalidProgramException("No se encontro solución");
                        }
                        Console.WriteLine(String.Format("Solución {0} :\nx1={1}\nx2={2}\nx3={3}", numero, rx1, rx2, rx3));
                        numero += 1;
                        cspSolucion.GetNext();
                    }

                    /*
                     * //Solucionador específico
                     * SimplexSolver sSolver = new SimplexSolver();
                     * //Creación de variables
                     * int sx1, sx2, sx3;
                     * sSolver.AddVariable("x1", out sx1);
                     * sSolver.SetBounds(sx1, 50, 300);
                     * sSolver.AddVariable("x2", out sx2);
                     * sSolver.SetBounds(sx2, 100, 200);
                     * sSolver.AddVariable("x3", out sx3);
                     * sSolver.SetBounds(sx3,20,1000);
                     * //Creación de restricciones
                     * int r1, r2, r3, goal;
                     * sSolver.AddRow("restriccion1", out r1);
                     * sSolver.SetCoefficient(r1, sx1, 1);
                     * sSolver.SetCoefficient(r1, sx2, 1);
                     * sSolver.SetCoefficient(r1, sx3, 1);
                     * sSolver.SetBounds(r1, 200, 280);
                     * sSolver.AddRow("restriccion2", out r2);
                     * sSolver.SetCoefficient(r2, sx1, 1);
                     * sSolver.SetCoefficient(r2, sx2, 3);
                     * sSolver.SetBounds(r2, 100, 2000);
                     * sSolver.AddRow("restriccion3", out r3);
                     * sSolver.SetCoefficient(r3, sx1, 2);
                     * sSolver.SetCoefficient(r3, sx3, 4);
                     * sSolver.SetBounds(r3, 50, 1000);
                     * //Función objetivo
                     * sSolver.AddRow("objetivo", out goal);
                     * sSolver.SetCoefficient(goal, sx1, -4);
                     * sSolver.SetCoefficient(goal, sx2, -2);
                     * sSolver.SetCoefficient(goal, sx3, 1);
                     * sSolver.SetBounds(goal, Rational.NegativeInfinity,Rational.PositiveInfinity);
                     * sSolver.AddGoal(goal, 1, false);
                     * //Solución
                     * sSolver.Solve(new SimplexSolverParams());
                     * sSolver.GetReport();
                     */
                    break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                Console.ReadLine();
            }
        }
示例#27
0
        public List <List <BinaryOption> > generateRandomVariantsUntilSeconds(VariabilityModel vm, int seconds,
                                                                              int treshold, int modulu)
        {
            List <List <BinaryOption> > erglist = new List <List <BinaryOption> >();
            var cts = new CancellationTokenSource();

            var task = Task.Factory.StartNew(() =>
            {
                #region task

                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();
                int mod = 0;
                while (soln.HasFoundSolution)
                {
                    if (cts.IsCancellationRequested)
                    {
                        return(erglist);
                    }
                    mod++;
                    if (mod % modulu != 0)
                    {
                        soln.GetNext();
                        continue;
                    }
                    List <BinaryOption> tempConfig = new List <BinaryOption>();
                    foreach (CspTerm cT in variables)
                    {
                        if (soln.GetIntegerValue(cT) == 1)
                        {
                            tempConfig.Add(termToElem[cT]);
                        }
                    }
                    if (tempConfig.Contains(null))
                    {
                        tempConfig.Remove(null);
                    }
                    erglist.Add(tempConfig);
                    if (erglist.Count == treshold)
                    {
                        break;
                    }
                    soln.GetNext();
                }
                return(erglist);

                #endregion
            }, cts.Token);

            if (Task.WaitAny(new[] { task }, TimeSpan.FromMilliseconds(seconds * 1000)) < 0)
            {
                Console.WriteLine("configsize: " + erglist.Count);
                cts.Cancel();
                return(erglist);
            }

            return(erglist);
        }
示例#28
0
 public ConstraintSystemSolver()
 {
     Solver = ConstraintSystem.CreateSolver();
 }
示例#29
0
        /// <summary>
        /// Knapsack enumerator -- enumerate up to "numAnswers" combinations of "weights" such that the sum of the weights is less than the weight limit.
        /// It places the patterns of items inside the list of patterns.  The efficiency parameter ensures that we don't output any which use less than "efficiency" percent
        /// off the weightlimit.
        /// </summary>
        /// <param name="maxAnswers">maximum number of combinations to get out.  Limits runtime.  If zero return all.</param>
        /// <param name="weights">weight of each item to go into the knapsack</param>
        /// <param name="weightLimit">knapsack weight limit</param>
        /// <param name="efficiency">limit patterns to use at least this % of the weight limit (between 0.0 and 1.0) </param>
        /// <param name="patterns">output list of patterns of inclusion of the weights.</param>
        public static void SolveKnapsack(int maxAnswers, int[] weights, int weightLimit, double efficiency, out List <int[]> patterns)
        {
            // convenience value.
            int NumItems            = weights.Length;
            ConstraintSystem solver = ConstraintSystem.CreateSolver();
            CspDomain        dom    = solver.CreateIntegerInterval(0, weightLimit);

            CspTerm knapsackSize = solver.Constant(weightLimit);

            // these represent the quantity of each item.
            CspTerm[] itemQty     = solver.CreateVariableVector(dom, "Quantity", NumItems);
            CspTerm[] itemWeights = new CspTerm[NumItems];

            for (int cnt = 0; cnt < NumItems; cnt++)
            {
                itemWeights[cnt] = solver.Constant(weights[cnt]);
            }

            // contributors to the weight (weight * variable value)
            CspTerm[] contributors = new CspTerm[NumItems];
            for (int cnt = 0; cnt < NumItems; cnt++)
            {
                contributors[cnt] = itemWeights[cnt] * itemQty[cnt];
            }

            // single constraint
            CspTerm knapSackCapacity = solver.GreaterEqual(knapsackSize, solver.Sum(contributors));

            solver.AddConstraints(knapSackCapacity);

            // must be efficient
            CspTerm knapSackAtLeast = solver.LessEqual(knapsackSize * efficiency, solver.Sum(contributors));

            solver.AddConstraints(knapSackAtLeast);

            // start counter and allocate a list for the results.
            int nanswers = 0;

            patterns = new List <int[]>();

            ConstraintSolverSolution sol = solver.Solve();

            while (sol.HasFoundSolution)
            {
                int[] pattern = new int[NumItems];
                // extract this pattern from the enumeration.
                for (int cnt = 0; cnt < NumItems; cnt++)
                {
                    object val;
                    sol.TryGetValue(itemQty[cnt], out val);
                    pattern[cnt] = (int)val;
                }
                // add it to the output.
                patterns.Add(pattern);
                nanswers++;
                // stop if we reach the limit of results.
                if (maxAnswers > 0 && nanswers >= maxAnswers)
                {
                    break;
                }
                sol.GetNext();
            }
        }
示例#30
0
        public override void AddConstaint()
        {
            ConstraintSystem solver     = ConstraintSystemSolver.Instance.Solver;
            CspTerm          constraint = null;

            CspTerm[] inputTerms = new CspTerm[Input.Count];
            for (int i = 0; i < Input.Count; i++)
            {
                inputTerms[i] = Input[i].CspTerm;
            }

            CspTerm outputTerm = Output.CspTerm;

            Type consType = type;

            if (IsNotHealthy)
            {
                // In case the gate is Broken (Not Healthy) - we don't want to add any constraint!!!
                return;

                /*
                 * switch (type)
                 * {
                 *  case Type.and:
                 *      consType = Type.nand;
                 *      break;
                 *  case Type.nand:
                 *      consType = Type.and;
                 *      break;
                 *  case Type.or:
                 *      consType = Type.nor;
                 *      break;
                 *  case Type.nor:
                 *      consType = Type.or;
                 *      break;
                 *  case Type.xor:
                 *      consType = Type.nxor;
                 *      break;
                 *  case Type.nxor:
                 *      consType = Type.xor;
                 *      break;
                 * }
                 */
            }

            lock (ConstraintSystemSolver.Instance.Locker)
            {
                //Debug.WriteLine("SAT IN!");
                switch (consType)
                {
                case Type.and:
                    CspTerm allAndInputs = solver.And(inputTerms);
                    constraint = solver.Equal(allAndInputs, outputTerm);
                    break;

                case Type.nand:
                    CspTerm allNandInputs = solver.And(inputTerms);
                    constraint = solver.Equal(allNandInputs, solver.Not(outputTerm));
                    break;

                case Type.nor:
                    CspTerm allNorInputs = solver.Or(inputTerms);
                    constraint = solver.Equal(allNorInputs, solver.Not(outputTerm));
                    break;

                case Type.or:
                    CspTerm allOrInputs = solver.Or(inputTerms);
                    constraint = solver.Equal(allOrInputs, outputTerm);
                    break;

                case Type.xor:
                    //XOR is also:
                    //http://en.wikipedia.org/wiki/XOR_gate#/media/File:254px_3gate_XOR.jpg

                    CspTerm firstNand = solver.Not(solver.And(inputTerms));
                    CspTerm firstOr   = solver.Or(inputTerms);
                    CspTerm secendAnd = solver.And(firstNand, firstOr);

                    constraint = solver.Equal(secendAnd, outputTerm);
                    break;

                case Type.nxor:
                    //XOR is also:
                    //http://en.wikipedia.org/wiki/XOR_gate#/media/File:254px_3gate_XOR.jpg

                    CspTerm firstNand2 = solver.Not(solver.And(inputTerms));
                    CspTerm firstOr2   = solver.Or(inputTerms);
                    CspTerm secendAnd2 = solver.And(firstNand2, firstOr2);

                    constraint = solver.Equal(secendAnd2, solver.Not(outputTerm));
                    break;
                }

                solver.AddConstraints(constraint);
                //Debug.WriteLine("SAT OUT!");
            }
        }
示例#31
0
        /// <summary>
        /// Generates a constraint system based on a variability model. The constraint system can be used to check for satisfiability of configurations as well as optimization.
        /// </summary>
        /// <param name="variables">Empty input, outputs a list of CSP terms that correspond to the configuration options of the variability model</param>
        /// <param name="optionToTerm">A map to get for a given configuration option the corresponding CSP term of the constraint system</param>
        /// <param name="termToOption">A map that gives for a given CSP term the corresponding configuration option of the variability model</param>
        /// <param name="vm">The variability model for which we generate a constraint system</param>
        /// <returns>The generated constraint system consisting of logical terms representing configuration options as well as their boolean constraints.</returns>
        internal static ConstraintSystem getConstraintSystem(out List <CspTerm> variables, out Dictionary <BinaryOption, CspTerm> optionToTerm, out Dictionary <CspTerm, BinaryOption> termToOption, VariabilityModel vm)
        {
            //Reusing seems to not work correctely. The problem: configurations are realized as additional constraints for the system.
            //however, when checking for the next config, the old config's constraints remain in the solver such that we have a wrong result.

            /*
             * if (csystem != null && variables_global != null && optionToTerm_global != null && termToOption_global != null && vm != null)
             * {//For optimization purpose
             *  if (vm.BinaryOptions.Count == vm_global.BinaryOptions.Count && vm.Name.Equals(vm_global.Name))
             *  {
             *      variables = variables_global;
             *      optionToTerm = optionToTerm_global;
             *      termToOption = termToOption_global;
             *      return csystem;
             *  }
             * }*/

            ConstraintSystem S = ConstraintSystem.CreateSolver();

            optionToTerm = new Dictionary <BinaryOption, CspTerm>();
            termToOption = new Dictionary <CspTerm, BinaryOption>();
            variables    = new List <CspTerm>();
            foreach (BinaryOption binOpt in vm.BinaryOptions)
            {
                CspDomain domain = S.DefaultBoolean;
                CspTerm   temp   = S.CreateVariable(domain, binOpt);
                optionToTerm.Add(binOpt, temp);
                termToOption.Add(temp, binOpt);
                variables.Add(temp);
            }

            List <List <ConfigurationOption> > alreadyHandledAlternativeOptions = new List <List <ConfigurationOption> >();

            //Constraints of a single configuration option
            foreach (BinaryOption current in vm.BinaryOptions)
            {
                CspTerm cT = optionToTerm[current];
                if (current.Parent == null || current.Parent == vm.Root)
                {
                    if (current.Optional == false && current.Excluded_Options.Count == 0)
                    {
                        S.AddConstraints(S.Implies(S.True, cT));
                    }
                    else
                    {
                        S.AddConstraints(S.Implies(cT, optionToTerm[vm.Root]));
                    }
                }

                if (current.Parent != null && current.Parent != vm.Root)
                {
                    CspTerm parent = optionToTerm[(BinaryOption)current.Parent];
                    S.AddConstraints(S.Implies(cT, parent));
                    if (current.Optional == false && current.Excluded_Options.Count == 0)
                    {
                        S.AddConstraints(S.Implies(parent, cT));//mandatory child relationship
                    }
                }

                //Alternative or other exclusion constraints
                if (current.Excluded_Options.Count > 0)
                {
                    List <ConfigurationOption> alternativeOptions = current.collectAlternativeOptions();
                    if (alternativeOptions.Count > 0)
                    {
                        //Check whether we handled this group of alternatives already
                        foreach (var alternativeGroup in alreadyHandledAlternativeOptions)
                        {
                            foreach (var alternative in alternativeGroup)
                            {
                                if (current == alternative)
                                {
                                    goto handledAlternative;
                                }
                            }
                        }

                        //It is not allowed that an alternative group has no parent element
                        CspTerm parent = null;
                        if (current.Parent == null)
                        {
                            parent = S.True;
                        }
                        else
                        {
                            parent = optionToTerm[(BinaryOption)current.Parent];
                        }

                        CspTerm[] terms = new CspTerm[alternativeOptions.Count + 1];
                        terms[0] = cT;
                        int i = 1;
                        foreach (BinaryOption altEle in alternativeOptions)
                        {
                            CspTerm temp = optionToTerm[altEle];
                            terms[i] = temp;
                            i++;
                        }
                        S.AddConstraints(S.Implies(parent, S.ExactlyMofN(1, terms)));
                        alreadyHandledAlternativeOptions.Add(alternativeOptions);
                        handledAlternative : { }
                    }

                    //Excluded option(s) as cross-tree constraint(s)
                    List <List <ConfigurationOption> > nonAlternative = current.getNonAlternativeExlcudedOptions();
                    if (nonAlternative.Count > 0)
                    {
                        foreach (var excludedOption in nonAlternative)
                        {
                            CspTerm[] orTerm = new CspTerm[excludedOption.Count];
                            int       i      = 0;
                            foreach (var opt in excludedOption)
                            {
                                CspTerm target = optionToTerm[(BinaryOption)opt];
                                orTerm[i] = target;
                                i++;
                            }
                            S.AddConstraints(S.Implies(cT, S.Not(S.Or(orTerm))));
                        }
                    }
                }
                //Handle implies
                if (current.Implied_Options.Count > 0)
                {
                    foreach (List <ConfigurationOption> impliedOr in current.Implied_Options)
                    {
                        CspTerm[] orTerms = new CspTerm[impliedOr.Count];
                        //Possible error: if a binary option impies a numeric option
                        for (int i = 0; i < impliedOr.Count; i++)
                        {
                            orTerms[i] = optionToTerm[(BinaryOption)impliedOr.ElementAt(i)];
                        }
                        S.AddConstraints(S.Implies(optionToTerm[current], S.Or(orTerms)));
                    }
                }
            }

            //Handle global cross-tree constraints involving multiple options at a time
            // the constraints should be in conjunctive normal form
            foreach (string constraint in vm.BinaryConstraints)
            {
                bool     and = false;
                string[] terms;
                if (constraint.Contains("&"))
                {
                    and   = true;
                    terms = constraint.Split('&');
                }
                else
                {
                    terms = constraint.Split('|');
                }

                CspTerm[] cspTerms = new CspTerm[terms.Count()];
                int       i        = 0;
                foreach (string t in terms)
                {
                    string optName = t.Trim();
                    if (optName.StartsWith("-") || optName.StartsWith("!"))
                    {
                        optName = optName.Substring(1);
                        BinaryOption binOpt     = vm.getBinaryOption(optName);
                        CspTerm      cspElem    = optionToTerm[binOpt];
                        CspTerm      notCspElem = S.Not(cspElem);
                        cspTerms[i] = notCspElem;
                    }
                    else
                    {
                        BinaryOption binOpt  = vm.getBinaryOption(optName);
                        CspTerm      cspElem = optionToTerm[binOpt];
                        cspTerms[i] = cspElem;
                    }
                    i++;
                }
                if (and)
                {
                    S.AddConstraints(S.And(cspTerms));
                }
                else
                {
                    S.AddConstraints(S.Or(cspTerms));
                }
            }
            csystem             = S;
            optionToTerm_global = optionToTerm;
            vm_global           = vm;
            termToOption_global = termToOption;
            variables_global    = variables;
            return(S);
        }