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();
}