Detecting Conflicts on a Scheduler Timeline (Algorithm)

99封情书 提交于 2019-12-31 03:50:09

问题


Suppose I am plotting events with a (StartTime,EndTime) on a 24-hr Calendar similar to Outlook. My goal is to detect overlaps (conflicts) and split them up such that each column occupies N% of the width of the window, where N = total number of conflicts in that time frame.

My problem is, my algorithm

1) first, sort all events by StartTime
2) LOOP: looks at neighbors: CurrentEvent and NextEvent (n+1):

   if NextEvent exists {

      if (CurrentEvent EndTime > NextEvent StartTime) { // CONFLICT!
         overlappingMode = true;
         overlappingEvents.add(currentEvent); // Add to array
      }
      else {  // NO CONFLICT
         if (overlappingMode is TRUE) {
            // Resolve Now
            redrawOverlappingEvents(overlappingEvents);
            // Reset
            overlappingMode = false;
            EMPTY overlappingEvents;
         }
      }
   }

3) After the loop, also for the last element, 

   if (Overlap Mode is still TRUE) {
      overlappingEvents.add(currentEvent); // Add to array also
      // Now Resolve
      redrawOverlappingEvents(overlappingStartTimes);
      // Reset
      overlappingMode = false;
      EMPTY overlappingEvents;    
   }

This works most of the time but introduces a problem of some kind with EndTimes. For instance, consider the image below:

The last event should be part of the Split-Group of 4 (not 3). It didn't get included in the Conflict Split because the previous Event's EndTime doesn't conflict with its StartTime.

In the Sorted array of StartTimes, the next-to-last event's EndTime (4:30) doesn't conflict with the last event's StartTime (4:45). So the final event 4:45 - 6:00 didn't get included in the overall Split Group. I should have gotten a 4-column split layout for the time area spanning 02:30 - 06:00.

Am I doing this algorithm correctly or is there a better way?


回答1:


The issue is that the "conflicts" relation isn't transitive, hence not an equivalence relation, but you want an equivalence relation so you can put them into equivalence classes that have the horizontal width shared. For this to work, we have to define a new relationship which is an equivalence relation (hence transitive) and then figure out how to compute it.

Getting an equivalence relation could be as easy as taking the transitive closure of your "conflicts" relation. That is, we can "add" all the missing members to make the relation transitive. One way to do this would be to keep your code largely the same, but instead of remembering the last start/end times, remember the first (hence earliest; we still need sorting) start time and the latest stop time, and to use that to detect "conflicts":

   // first event is the current event
   lastMaxEndTime = CurrentEvent EndTime

   if NextEvent exists {

      // if the maximum end time considered in
      // the conflicting component currently
      // under consideration extends beyond the
      // the next event's start time, then this
      // and everything that "conflicts" with it
      // is also defined to "conflict" with NextEvent
      if (lastMaxEndTime > NextEvent StartTime) { // CONFLICT!
         overlappingMode = true;
         overlappingEvents.add(currentEvent); // Add to array
         lastMaxEndTime = max(lastMaxEndTime, NextEvent EndTime)
      }
      else {  // NO CONFLICT
         if (overlappingMode is TRUE) {
            // Resolve Now
            redrawOverlappingEvents(overlappingEvents);
            // Reset
            overlappingMode = false;
            EMPTY overlappingEvents;
         }

         // everything that starts earlier than me,
         // ends before I start. so start over
         lastMaxEndTime = NextEvent EndTime
      }
   }

In your example, the algorithm does this:

lastMaxEndTime = 2:00
lastMaxEndTime > 2:30? no, so
    lastMaxEndTime = 3:30
lastMaxEndTime > 3:00? yes, so
    lastMaxEndTime = max(3:30, 5:00) = 5:00
lastMaxEndTime > 3:15? yes, so
    lastMaxEndTime = max(5:00, 4:30) = 5:00 <--- this fixed it
lastMaxEndTime > 4:45? yes, so
    lastMaxEndTime = max(5:00, 6:00) = 6:00


来源:https://stackoverflow.com/questions/46778439/detecting-conflicts-on-a-scheduler-timeline-algorithm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!