/// <summary> /// Computes the quotient of two multi-intervals /// </summary>. public static MultiInterval Divide(MultiInterval dividend, MultiInterval divisor) { List <Interval> aIntervals = dividend._intervals; List <Interval> bIntervals = divisor._intervals; MultiInterval multiInterval = new MultiInterval(); for (int i = 0; i < aIntervals.Count; i++) { for (int j = 0; j < bIntervals.Count; j++) { Interval intervalDivisor = bIntervals[j]; if (intervalDivisor.Contains(0)) { multiInterval.Add(Interval.Divide(aIntervals[i], new Interval(0, intervalDivisor.UpperBound))); multiInterval.Add(Interval.Divide(aIntervals[i], new Interval(intervalDivisor.LowerBound, 0))); } else { multiInterval.Add(Interval.Divide(aIntervals[i], intervalDivisor)); } } } return(multiInterval); }
/// <summary> /// MultiIntervals are equal if they contain the same values /// </summary> public bool Equals(MultiInterval other) { if (ReferenceEquals(null, other)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } if (_intervals.Count != other._intervals.Count) { return(false); } // this is an O(n^2)... for (int i = 0; i < _intervals.Count; i++) { if (!other._intervals.Contains(_intervals[i])) { return(false); } } return(true); }
public MultiInterval[] Split() { MultiInterval[] splits; // more than 1 interval -> just split up the intervals if (_intervals.Count > 1) { splits = new MultiInterval[_intervals.Count]; for (int i = 0; i < _intervals.Count; i++) { splits[i] = _intervals[i]; } return(splits); } else if (_intervals.Count == 1) { splits = new MultiInterval[2]; Interval upper; Interval lower; Interval interval = _intervals[0]; interval.Split(interval.Center, out upper, out lower); splits[0] = upper; splits[1] = lower; return(splits); } throw new InvalidOperationException("Can't split an empty interval!"); }
/// <summary> /// Constrains <paramref name="variable"/> to never take values in <paramref name="multiInterval"/> /// </summary> public static void Exclude(RealVariable variable, MultiInterval multiInterval) { foreach (var interval in multiInterval) { Exclude(variable, interval); } }
public MultiInterval Clone() { MultiInterval multiInterval = new MultiInterval(); foreach (var interval in _intervals) { multiInterval._intervals.Add(interval); } return(multiInterval); }
/// <summary> /// Computes the union of two multi-intervals /// </summary> public static MultiInterval Union(MultiInterval a, MultiInterval b) { MultiInterval multiInterval = a.Clone(); foreach (var interval in b._intervals) { multiInterval.Add(interval); } return(multiInterval); }
/// <summary> /// Creates and returns a real variable which represents the minimum of <paramref name="a"/> and <paramref name="b"/> /// </summary> public static RealVariable Minimize(RealVariable a, RealVariable b) { RealVariable min = new RealVariable(a.ConstraintThingySolver, null, RealVariable.DefaultRange); // calculate the possible range for the sum so we improve the speed of the search Constraint.InRange(min, MultiInterval.Min(a.AllowableValues.First, b.AllowableValues.First)); Min(min, a, b); return(min); }
/// <summary> /// Extends the multi-interval to contain the specified value. /// </summary> public MultiInterval Extend(double value) { MultiInterval multiInterval = new MultiInterval(); for (int i = 0; i < _intervals.Count; i++) { Interval extended = _intervals[i].Extend(value); multiInterval.Add(extended); } return(multiInterval); }
private UInt64 FindPlausibleFiniteDomainValues() { MultiInterval score = Score.AllowableValues.First; int[] setBits = FiniteDomainVariable.AllowableValues.GetSetIndices(); UInt64 mask = 0UL; for (int i = 0; i < setBits.Length; i++) { if (MultiInterval.Intersects(score, _scoreMapping[setBits[i]])) { mask = mask.SetBit(setBits[i]); } } return(mask); }
/// <summary> /// Computes the product of two multi-intervals /// </summary> public static MultiInterval Multiply(MultiInterval a, MultiInterval b) { List <Interval> aIntervals = a._intervals; List <Interval> bIntervals = b._intervals; MultiInterval multiInterval = new MultiInterval(); for (int i = 0; i < aIntervals.Count; i++) { for (int j = 0; j < bIntervals.Count; j++) { Interval product = Interval.Multiply(aIntervals[i], bIntervals[j]); multiInterval.Add(product); } } return(multiInterval); }
/// <summary> /// Subtracts two multi-intervals /// </summary> public static MultiInterval Subtract(MultiInterval a, MultiInterval b) { List <Interval> aIntervals = a._intervals; List <Interval> bIntervals = b._intervals; MultiInterval multiInterval = new MultiInterval(); for (int i = 0; i < aIntervals.Count; i++) { for (int j = 0; j < bIntervals.Count; j++) { Interval difference = Interval.Subtract(aIntervals[i], bIntervals[j]); multiInterval.Add(difference); } } return(multiInterval); }
/// <summary> /// True if the two multi-intervals intersect /// </summary> public static bool Intersects(MultiInterval a, MultiInterval b) { List <Interval> aIntervals = a._intervals; List <Interval> bIntervals = b._intervals; for (int i = 0; i < aIntervals.Count; i++) { for (int j = 0; j < bIntervals.Count; j++) { Interval intersection = Interval.Intersection(aIntervals[i], bIntervals[j]); if (!intersection.IsEmpty) { return(true); } } } return(false); }
/// <summary> /// Computes and returns the intersection between <paramref name="a"/> and <paramref name="b"/> /// </summary> public static MultiInterval Intersection(MultiInterval a, MultiInterval b) { List <Interval> aIntervals = a._intervals; List <Interval> bIntervals = b._intervals; MultiInterval multiInterval = new MultiInterval(); for (int i = 0; i < aIntervals.Count; i++) { for (int j = 0; j < bIntervals.Count; j++) { Interval intersection = Interval.Intersection(aIntervals[i], bIntervals[j]); if (!intersection.IsEmpty) { multiInterval.Add(intersection); } } } return(multiInterval); }
protected internal override void UpdateVariable(RealVariable variable, out bool success) { MultiInterval result; if (variable == Max) { result = Variables[1].AllowableValues.First; for (int i = 2; i < Variables.Length; i++) { result = MultiInterval.Max(result, Variables[i].AllowableValues.First); } } else { // we can't be greater than the 'max', so we bound ourselves to the range (-infinity, max] result = Max.AllowableValues.First.Extend(double.NegativeInfinity); } variable.NarrowTo(result, out success); return; }
/// <summary> /// Constrains <paramref name="variable"/> to be in <paramref name="multiInterval"/> /// </summary> public static void InRange(RealVariable variable, MultiInterval multiInterval) { variable.BackdoorSet(variable.AllowableValues.Rest.AddFront(MultiInterval.Intersection(variable.AllowableValues.First, multiInterval))); }