コード例 #1
0
ファイル: Solver.Solution.cs プロジェクト: lmoodie/timetable
            public bool AddStream(Stream stream)
            {
                // if the stream clashes with another stream
                if (!Fits(stream))
                {
                    return(false);
                }

                // add to list of streams
                Combination_.Add(stream);

                // run through list of classes
                foreach (Session session in stream.Classes)
                {
                    // increase total time spent in classes
                    TimeInClasses_ += session.Length;

                    // if we're adding the class to an empty day
                    if (ClassesByDay_[session.Day].Count == 0)
                    {
                        // increment day count
                        Days_++;
                        // add start and ending times to totals
                        TotalStart_ += new TimeLength(session.StartTime.DayMinutes);
                        TotalEnd_   += new TimeLength(session.EndTime.DayMinutes);

                        // add length to total time at uni
                        TimeAtUni_ += session.Length;
                    }
                    else
                    {
                        // if it's earlier than the earliest class of that day
                        if (session.StartTime < ClassesByDay_[session.Day][0].StartTime)
                        {
                            TimeLength difference = ClassesByDay_[session.Day][0].StartTime - session.StartTime;
                            // remove the difference for total start
                            TotalStart_ -= difference;
                            // add the difference for total time at uni
                            TimeAtUni_ += difference;
                        }
                        // if it's later than the latest class
                        if (session.EndTime > ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].EndTime)
                        {
                            TimeLength difference = session.EndTime - ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].EndTime;
                            // add the difference for total end
                            TotalEnd_ += difference;
                            // add the difference for total time at uni
                            TimeAtUni_ += difference;
                        }
                    }
                    // update average day length
                    AverageDayLength_ = TimeAtUni_ / Days_;

                    // add new classes to day-indexed list
                    ClassesByDay_[session.Day].Add(session);
                    //ClassesByDay_[session.Day].Sort();

                    // check class start/end times against maxima/minima
                    if (session.StartTime < EarlyStart_)
                    {
                        EarlyStart_ = session.StartTime;
                    }
                    if (session.StartTime > LateStart_)
                    {
                        LateStart_ = session.StartTime;
                    }
                    if (session.EndTime < EarlyEnd_)
                    {
                        EarlyEnd_ = session.EndTime;
                    }
                    if (session.EndTime > LateEnd_)
                    {
                        LateEnd_ = session.EndTime;
                    }

                    // check day length
                    TimeLength dayLength = ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].EndTime -
                                           ClassesByDay_[session.Day][0].StartTime;
                    if (dayLength < MinDayLength_)
                    {
                        MinDayLength_ = dayLength;
                    }
                    if (dayLength > MaxDayLength_)
                    {
                        MaxDayLength_ = dayLength;
                    }
                }

                // clear break data
                NumberBreaks_ = 0;
                AverageBreak_ = new TimeLength(0, 0);
                ShortBreak_   = new TimeLength(24, 0);
                LongBreak_    = new TimeLength(0, 0);
                TimeInBreaks_ = new TimeLength(0, 0);
                // clear block data
                NumberBlocks_ = 0;
                AverageBlock_ = new TimeLength(0, 0);
                ShortBlock_   = new TimeLength(24, 0);
                LongBlock_    = new TimeLength(0, 0);
                // TODO: rewrite to avoid full sweep?
                // do a fresh sweep of all days to rebuild break/block data
                foreach (List <Session> daySessions in ClassesByDay_)
                {
                    // empty day - skip
                    if (daySessions.Count == 0)
                    {
                        continue;
                    }

                    // set up data for the start of the block
                    TimeOfDay  blockStart = daySessions[0].StartTime;
                    TimeLength blockLength, breakLength;

                    // compare adjacent classes
                    int i;
                    for (i = 1; i < daySessions.Count; i++)
                    {
                        breakLength = daySessions[i].StartTime - daySessions[i - 1].EndTime;

                        // if there is at least ~15 minutes between the classes, call it a break, otherwise skip
                        if (breakLength.TotalMinutes < MinBreak)
                        {
                            continue;
                        }

                        // find block length
                        blockLength = daySessions[i - 1].EndTime - blockStart;

                        // increment number of blocks
                        NumberBlocks_++;
                        // add block length to cumulative sum
                        AverageBlock_ += blockLength;
                        // set start of next block
                        blockStart = daySessions[i].StartTime;

                        // compare block against maxima/minima
                        if (blockLength < ShortBlock_)
                        {
                            ShortBlock_ = blockLength;
                        }
                        if (blockLength > LongBlock_)
                        {
                            LongBlock_ = blockLength;
                        }

                        // increment number of breaks
                        NumberBreaks_++;
                        // add break to cumulative sum
                        TimeInBreaks_ += breakLength;

                        // compare break length against maxima/minima
                        if (breakLength < ShortBreak_)
                        {
                            ShortBreak_ = breakLength;
                        }
                        // check if it's the longest break so far
                        if (breakLength > LongBreak_)
                        {
                            LongBreak_ = breakLength;
                        }
                    }

                    // also create a block at the end
                    // find block length
                    blockLength = daySessions[i - 1].EndTime - blockStart;
                    // compare block against maxima/minima
                    if (blockLength < ShortBlock_)
                    {
                        ShortBlock_ = blockLength;
                    }
                    if (blockLength > LongBlock_)
                    {
                        LongBlock_ = blockLength;
                    }
                    // increment number of blocks
                    NumberBlocks_++;
                    // add block length to cumulative sum
                    AverageBlock_ += blockLength;
                }

                if (NumberBreaks_ > 0)
                {
                    // divide the sum of breaks to find the mean
                    AverageBreak_ = TimeInBreaks_ / NumberBreaks_;
                }

                // divide the sum of blocks to find the mean
                AverageBlock_ /= NumberBlocks_;

                AverageStart_ = new TimeOfDay(TotalStart_.TotalMinutes / Days_);
                AverageEnd_   = new TimeOfDay(TotalEnd_.TotalMinutes / Days_);

                return(true);
            }
コード例 #2
0
ファイル: TimetableControl.cs プロジェクト: lmoodie/timetable
        protected override void OnDragOver(DragEventArgs drgevent)
        {
            TimeOfWeek time = FindClickTime(PointToClient(new Point(drgevent.X, drgevent.Y)));

            // outside of table bounds?
            if (TimeOfWeek.ReferenceEquals(time, null))
            {
                // clear current preview (at edge of timetable)
                EndPreviewStream();
                // cannot drag outside of the actual table
                drgevent.Effect = DragDropEffects.None;
                return;
            }

            // dragging a class
            if (drgevent.Data.GetDataPresent(typeof(Session)) || drgevent.Data.GetDataPresent(typeof(Type)))
            {
                drgevent.Effect = DragDropEffects.Move;
                Type dragType;
                if (drgevent.Data.GetDataPresent(typeof(Session)))
                {
                    dragType = ((Session)drgevent.Data.GetData(typeof(Session))).Stream.Type;
                }
                else
                {
                    dragType = (Type)drgevent.Data.GetData(typeof(Type));
                }

                Session session = Timetable.From(dragType).FindClassAt(time, false);
                if (session == null)
                {
                    EndPreviewStream();
                }
                else
                {
                    PreviewEquiv(session.Stream);
                }
            }
            // dragging an unavailability
            else if (drgevent.Data.GetDataPresent(typeof(Unavailability)))
            {
                Unavailability dragUnavail = (Unavailability)drgevent.Data.GetData(typeof(Unavailability));
                TimeLength     offset      = new TimeLength(dragUnavail.StartMinute);
                TimeOfWeek     start       = time - dragUnavail.Length / 2;
                start -= offset;
                start.RoundToNearestHour();
                start += offset;

                HoverUnavail_ = new Timeslot(start.Day, (TimeOfDay)start, (TimeOfDay)start + dragUnavail.Length);
                if (HoverUnavail_.StartTime < new TimeOfDay(HourStart_, 0) || HoverUnavail_.EndTime > new TimeOfDay(HourEnd_, 0))
                {
                    drgevent.Effect = DragDropEffects.None;
                    HoverUnavail_   = null;
                }
                else
                {
                    drgevent.Effect = DragDropEffects.Move;
                }
                Invalidate();
            }
            else
            {
                base.OnDragOver(drgevent);
            }
        }
コード例 #3
0
ファイル: Solver.Solution.cs プロジェクト: lmoodie/timetable
            public bool ReCompute()
            {
                ClearComputation();

                // check if each stream fits with the other streams

                /*for (int i = 0; i < Combination_.Count; i++)
                 * {
                 *  for (int j = i + 1; j < Combination_.Count; j++)
                 *  {
                 *      if (Timetable_.LookupClashTable(Combination_[i], Combination_[j]))
                 *          return false;
                 *  }
                 * }*/

                // for each stream
                foreach (Stream stream in Combination_)
                {
                    // for each session in each stream
                    foreach (Session session in stream.Classes)
                    {
                        // build day-indexed list of classes
                        ClassesByDay_[session.Day].Add(session);
                        // calculate total time spent in classes
                        TimeInClasses_ += session.Length;
                    }
                }

                // for each day of classes
                foreach (List <Session> daySessions in ClassesByDay_)
                {
                    // empty day - skip
                    if (daySessions.Count == 0)
                    {
                        continue;
                    }
                    // otherwise increment day count
                    Days_++;

                    #region Breaks and blocks

                    // set up data for the start of the block
                    TimeOfDay  blockStart = daySessions[0].StartTime;
                    TimeLength blockLength, breakLength;

                    // compare adjacent classes
                    int i;
                    for (i = 1; i < daySessions.Count; i++)
                    {
                        breakLength = daySessions[i].StartTime - daySessions[i - 1].EndTime;

                        // if there is at least ~15 minutes between the classes, call it a break, otherwise skip
                        if (breakLength.TotalMinutes < MinBreak)
                        {
                            continue;
                        }

                        // find block length
                        blockLength = daySessions[i - 1].EndTime - blockStart;

                        // increment number of blocks
                        NumberBlocks_++;
                        // add block length to cumulative sum
                        AverageBlock_ += blockLength;
                        // set start of next block
                        blockStart = daySessions[i].StartTime;

                        // compare block against maxima/minima
                        if (blockLength < ShortBlock_)
                        {
                            ShortBlock_ = blockLength;
                        }
                        if (blockLength > LongBlock_)
                        {
                            LongBlock_ = blockLength;
                        }

                        // increment number of breaks
                        NumberBreaks_++;
                        // add break to cumulative sum
                        TimeInBreaks_ += breakLength;

                        // compare break length against maxima/minima
                        if (breakLength < ShortBreak_)
                        {
                            ShortBreak_ = breakLength;
                        }
                        // check if it's the longest break so far
                        if (breakLength > LongBreak_)
                        {
                            LongBreak_ = breakLength;
                        }
                    }

                    // also create a block at the end
                    // find block length
                    blockLength = daySessions[i - 1].EndTime - blockStart;
                    // compare block against maxima/minima
                    if (blockLength < ShortBlock_)
                    {
                        ShortBlock_ = blockLength;
                    }
                    if (blockLength > LongBlock_)
                    {
                        LongBlock_ = blockLength;
                    }
                    // increment number of blocks
                    NumberBlocks_++;
                    // add block length to cumulative sum
                    AverageBlock_ += blockLength;

                    #endregion

                    TimeOfDay dayStart = daySessions[0].StartTime;
                    TimeOfDay dayEnd   = daySessions[i - 1].EndTime;

                    TimeLength dayLength = dayEnd - dayStart;
                    // add to total time at uni
                    TimeAtUni_ += dayLength;
                    // check max/min
                    if (dayLength > MaxDayLength_)
                    {
                        MaxDayLength_ = dayLength;
                    }
                    if (dayLength < MinDayLength_)
                    {
                        MinDayLength_ = dayLength;
                    }

                    // add to total time for start and end
                    TotalStart_.TotalMinutes += dayStart.DayMinutes;
                    TotalEnd_.TotalMinutes   += dayEnd.DayMinutes;

                    // check start/end min/max
                    if (dayStart < EarlyStart_)
                    {
                        EarlyStart_ = dayStart;
                    }
                    if (dayStart > LateStart_)
                    {
                        LateStart_ = dayStart;
                    }
                    if (dayEnd < EarlyEnd_)
                    {
                        EarlyEnd_ = dayEnd;
                    }
                    if (dayEnd > LateEnd_)
                    {
                        LateEnd_ = dayEnd;
                    }
                }

                // calculate averages using totals and counts
                if (NumberBreaks_ > 0)
                {
                    AverageBreak_ = TimeInBreaks_ / NumberBreaks_;
                }
                AverageBlock_    /= NumberBlocks_;
                AverageStart_     = new TimeOfDay(TotalStart_.TotalMinutes / Days_);
                AverageEnd_       = new TimeOfDay(TotalEnd_.TotalMinutes / Days_);
                AverageDayLength_ = TimeAtUni_ / Days_;



                /*
                 * // process all the streams
                 * foreach (Stream stream in Combination_)
                 * {
                 *  // run through list of classes
                 *  foreach (Session session in stream.Classes)
                 *  {
                 *      // increase total time spent in classes
                 *      TimeInClasses_ += session.Length;
                 *
                 *      // if we're adding the class to an empty day
                 *      if (ClassesByDay_[session.Day].Count == 0)
                 *      {
                 *          // increment day count
                 *          Days_++;
                 *          // add start and ending times to totals
                 *          TotalStart_ += new TimeLength(session.Start.TotalMinutes);
                 *          TotalEnd_ += new TimeLength(session.End.TotalMinutes);
                 *
                 *          // add length to total time at uni
                 *          TimeAtUni_ += session.Length;
                 *      }
                 *      else
                 *      {
                 *          // if it's earlier than the earliest class of that day
                 *          if (session.Start < ClassesByDay_[session.Day][0].Start)
                 *          {
                 *              TimeLength difference = ClassesByDay_[session.Day][0].Start - session.Start;
                 *              // remove the difference for total start
                 *              TotalStart_ -= difference;
                 *              // add the difference for total time at uni
                 *              TimeAtUni_ += difference;
                 *          }
                 *          // if it's later than the latest class
                 *          if (session.End > ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].End)
                 *          {
                 *              TimeLength difference = session.End - ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].End;
                 *              // add the difference for total end
                 *              TotalStart_ += difference;
                 *              // add the difference for total time at uni
                 *              TimeAtUni_ += difference;
                 *          }
                 *      }
                 *      // update average day length
                 *      AverageDayLength_ = TimeAtUni_ / Days_;
                 *
                 *      // add new classes to day-indexed list
                 *      ClassesByDay_[session.Day].Add(session);
                 *      ClassesByDay_[session.Day].Sort();
                 *
                 *      // check class start/end times against maxima/minima
                 *      if (session.Start < EarlyStart_)
                 *          EarlyStart_ = session.Start;
                 *      if (session.Start > LateStart_)
                 *          LateStart_ = session.Start;
                 *      if (session.End < EarlyEnd_)
                 *          EarlyEnd_ = session.End;
                 *      if (session.End > LateEnd_)
                 *          LateEnd_ = session.End;
                 *
                 *      // check day length
                 *      TimeLength dayLength = ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].End -
                 *          ClassesByDay_[session.Day][0].Start;
                 *      if (dayLength < MinDayLength_)
                 *          MinDayLength_ = dayLength;
                 *      if (dayLength > MaxDayLength_)
                 *          MaxDayLength_ = dayLength;
                 *  }
                 * }
                 *
                 * // clear break data
                 * NumberBreaks_ = 0;
                 * AverageBreak_ = new TimeLength(0, 0);
                 * ShortBreak_ = new TimeLength(24, 0);
                 * LongBreak_ = new TimeLength(0, 0);
                 * TimeInBreaks_ = new TimeLength(0, 0);
                 * // clear block data
                 * NumberBlocks_ = 0;
                 * AverageBlock_ = new TimeLength(0, 0);
                 * ShortBlock_ = new TimeLength(24, 0);
                 * LongBlock_ = new TimeLength(0, 0);
                 * // TODO: rewrite to avoid full sweep?
                 * // do a fresh sweep of all days to rebuild break/block data
                 * foreach (List<Session> daySessions in ClassesByDay_)
                 * {
                 *  // set up data for the start of the block
                 *  TimeOfDay blockStart;
                 *  if (daySessions.Count > 0)
                 *      blockStart = daySessions[0].Start;
                 *  else
                 *      blockStart = new TimeOfDay();
                 *
                 *  // compare adjacent classes
                 *  for (int i = 1; i < daySessions.Count; i++)
                 *  {
                 *      TimeLength breakLength = daySessions[i].Start - daySessions[i - 1].End;
                 *
                 *      // if there's a break between classes, make a block
                 *      if (breakLength.TotalMinutes >= MinBreak)
                 *      {
                 *          // find block length
                 *          TimeLength blockLength = daySessions[i - 1].End - blockStart;
                 *          // compare block against maxima/minima
                 *          if (blockLength < ShortBlock_)
                 *              ShortBlock_ = blockLength;
                 *          if (blockLength > LongBlock_)
                 *              LongBlock_ = blockLength;
                 *
                 *          // increment number of blocks
                 *          NumberBlocks_++;
                 *          // add block length to cumulative sum
                 *          AverageBlock_ += blockLength;
                 *          // set start of next block
                 *          blockStart = daySessions[i].Start;
                 *      }
                 *      // also create a block at the end
                 *      if (i == daySessions.Count - 1)
                 *      {
                 *          // find block length
                 *          TimeLength blockLength = daySessions[i].End - blockStart;
                 *          // compare block against maxima/minima
                 *          if (blockLength < ShortBlock_)
                 *              ShortBlock_ = blockLength;
                 *          if (blockLength > LongBlock_)
                 *              LongBlock_ = blockLength;
                 *
                 *          // increment number of blocks
                 *          NumberBlocks_++;
                 *          // add block length to cumulative sum
                 *          AverageBlock_ += blockLength;
                 *      }
                 *
                 *      // if there is at least ~15 minutes between the classes, call it a break, otherwise skip
                 *      if (breakLength.TotalMinutes < MinBreak)
                 *          continue;
                 *
                 *      // increment number of breaks
                 *      NumberBreaks_++;
                 *      // add break to cumulative sum
                 *      TimeInBreaks_ += breakLength;
                 *
                 *      // compare break length against maxima/minima
                 *      if (breakLength < ShortBreak_)
                 *          ShortBreak_ = breakLength;
                 *      // check if it's the longest break so far
                 *      if (breakLength > LongBreak_)
                 *          LongBreak_ = breakLength;
                 *  }
                 * }
                 * // divide the sum of breaks to find the mean
                 * AverageBreak_ = TimeInBreaks_ / NumberBreaks_;
                 * // divide the sum of blocks to find the mean
                 * AverageBlock_ /= NumberBlocks_;*/

                return(true);
            }
コード例 #4
0
ファイル: TimetableControl.cs プロジェクト: lmoodie/timetable
 public Rectangle TimeLengthRectangle(TimeLength t)
 {
     return(new Rectangle(0, 0, Cell_.Width, (int)(t.TotalMinutes / 60.0f * Cell_.Height)));
 }