Cream.DefaultSolver.GetValueWithSoftConstraint C# (CSharp) Method

GetValueWithSoftConstraint() public method

gets value from soft constraints
public GetValueWithSoftConstraint ( Variable v0 ) : int
v0 Variable /// The v0 (which is a of type variable). ///
return int
        public int GetValueWithSoftConstraint(Variable v0)
        {
            if (Random == null)
            {
                Random = new Random();
            }
            // get V0's domain
            var d0 = (IntDomain)v0.Domain;

            // if there are soft constraints
            if (_softConstraints.Count() > 0)
            {
                // get the distinct values of the variables associated with all
                // Equal soft constraints with V0
                var equalSoftConstraintsWithV0 =
                    _softConstraints
                        .Where(soft => soft is Equals).Cast<Equals>()
                        .Where(cons => (cons.Vars[0] == v0))
                        .Where(vars => vars.Vars[0].Domain.Size() > 1)
                        .Where(cons => v0.Domain.Contains(((IntDomain)cons.Vars[1].Domain).Minimum()))
                        .Select(doms => ((IntDomain)doms.Vars[1].Domain).Minimum())
                        .Distinct().ToArray();

                // if there are only one just return it
                if (equalSoftConstraintsWithV0.Count() == 1)
                {
                    return equalSoftConstraintsWithV0.ElementAt(0);
                }

                // get variables that are alreay assigned
                var varsDomainAlreadyAssigned = network.Variables.Cast<Variable>()
                    .Where(vars => vars.Domain.Size() == 1 && !vars.IsValueType)

                    // Size == 1 means already assigned
                    // Where(vars => ((IntDomain) vars.Domain).Min() != 0)  ///???
                    .Select(vars => ((IntDomain)vars.Domain).Minimum())
                    .Where(vars => equalSoftConstraintsWithV0.Contains(vars)).ToArray();

                var counter = new int[equalSoftConstraintsWithV0.Count()];

                // if there are values assoiciated with v0 that already assigned
                if (varsDomainAlreadyAssigned.Count() > 0)
                {
                    var counterForAssigned = 0;
                    foreach (var cd in equalSoftConstraintsWithV0)
                    {
                        var cd1 = cd;
                        for (var i = 0; i < varsDomainAlreadyAssigned.Where(vr => vr == cd1).Count(); i++)
                        {
                            counter[counterForAssigned]++;
                        }
                        counterForAssigned++;
                    }
                }

                // to choose the value that least has been assigned from preferences with v0
                if (counter.Count() > 0)
                {
                    IList<int> minIndexes = new List<int> { 0 };

                    // int minIndex = 0;
                    var minValue = counter[0];
                    for (var i = 1; i < counter.Length; i++)
                    {
                        if (counter[i] < minValue)
                        {
                            minIndexes = new List<int> { i };
                            minValue = counter[i];
                        }
                        else if (counter[i] == minValue)
                        {
                            minIndexes.Add(i);
                        }
                    }
                    var index = Random.Next(0, minIndexes.Count);
                    return equalSoftConstraintsWithV0.ElementAt(minIndexes[index]);
                }

                // Don't return values that have preferences
                // if they are minimum in domain
                // as they will be needed later or the preference is not equal
                // which is not desirable anyway
                // unless nothing left in domain except those values
                var domainValues = d0.GetElements();
                IList<int> tempDomainValues = new List<int>(domainValues);
                foreach (var domainValue in from domainValue in tempDomainValues
                                            let value = domainValue
                                            where _valuesWhichHavePreferences.Any(val => value == val)
                                            select domainValue)
                {
                    domainValues.Remove(domainValue);
                }

                if (domainValues.Count != 0)
                {
                    // return domainValues.First();

                    return domainValues[Random.Next(0, domainValues.Count)];
                }
            }

            // return one of the domain values randomly if there are no equal soft constrians
            // or you reached here by flow
            var elements = d0.GetElements();
            return elements[Random.Next(0, elements.Count)];

            // return d0.Min();
        }