using System; namespace Microsoft.Msagl.Routing.Visibility { /// /// For our purposes, it suffices to define a bimodal function as /// one for which there is an r in [ 0, n-1] such that f(r), f(r + I), . . . , f(n), f( l), . . . , /// f(r - 1) is unimodal. In our case no three sequential elements have the same value /// internal class BimodalSequence { internal BimodalSequence(Func sequence, int length) { this.sequence = sequence; this.length = length; } Func sequence; /// /// the sequence values /// internal Func Sequence { get { return sequence; } } int length; /// /// the length of the sequence: the sequence starts from 0 /// internal int Length { get { return length; } } //following Chazelle, Dobkin internal int FindMinimum(){ if (sequence(0) == sequence(Length - 1)) //we have a unimodal function return (new UnimodalSequence(sequence,Length)).FindMinimum(); return (new UnimodalSequence(GetAdjustedSequenceForMinimum(), Length)).FindMinimum(); } Func GetAdjustedSequenceForMinimum() { double leftVal=Sequence(0); double rightVal=Sequence(Length-1); double k=(rightVal-leftVal)/(Length-1); return delegate(int i) { return Math.Min(this.Sequence(i), leftVal + k * i); }; } internal int FindMaximum() { if (sequence(0) == sequence(Length - 1)) //we have a unimodal function return (new UnimodalSequence(sequence, Length)).FindMaximum(); return (new UnimodalSequence(GetAdjustedSequenceForMaximum(), Length)).FindMaximum(); } Func GetAdjustedSequenceForMaximum() { double leftVal = Sequence(0); double rightVal = Sequence(Length - 1); double k = (rightVal - leftVal) / (Length - 1); return delegate(int i) { return Math.Max(this.Sequence(i), leftVal + k * i); }; } } }