我正在编写一个C#程序来处理调度。现在每个员工都需要能力限制他们的日程安排:
Sally只能在周一,周三,周五上午9点至下午3点工作
比利只能在周二,周四,周日下午5点到9点工作莎莉只能在周一,周三,周五上午9点至下午3点工作 直到某某日期,然后她可以工作不同的时间和日期。
这些是我需要应用于每个员工对象的一些限制示例。我想要的是关于如何尽可能高效和通用地构建它的一些建议。显然,我必须能够访问这些数据并能够应用这些限制。例如,当经理试图制定时间表时,他需要能够看到当他在星期二4点安排Sally时他们是个问题。另外我应该如何存储每个员工的这些数据?
答案 0 :(得分:1)
类似的东西:
public class Employee
{
public string Name { get; set; }
// other important info
private List<WorkTime> _availability = new List<WorkTime>();
public List<WorkTime> Availability
{
get { return _availability; }
internal set { _availability = value; }
}
}
public class WorkTime
{
public DayOfWeek Day { get; private set; }
public int StartHour { get; private set; }
public int EndHour { get; private set; }
public WorkTime(DayOfWeek day, int startHour, int endHour)
{
// validation here (e.g. day and time range during store hours, start<end, etc.)
Day = day;
StartHour = startHour;
EndHour = endHour;
}
}
并使用LINQ(或foreach)查询员工集合,并使用每个员工的可用性查找有时间来满足某些班次的人。
创建一些实用程序函数(扩展)以根据业务规则比较WorkTime对象也很有用(例如,IsAvailable比较两个WorkTime对象,如果它是相同的DoW并且至少重叠4小时则返回true)
并且您可能会将其存储在数据库中,因此使用类中的属性等字段对表进行建模。
答案 1 :(得分:1)
我会使用strategy pattern与Rules
一起使用。
public interface Rule
{
bool Satisfies(Employee employee);
}
public class ScheduleRule : Rule
{
ScheduleRule(Schedule schedule)
{ ... }
bool Satisfies(Employee employee)
{
// Ensure the employee is available
}
}
public class HolidayRule : Rule
{
HolidayRule(Datetime date)
{ ... }
bool Satisfies(Employee employee)
{
// Checks if the employee as volunteered for this holiday
}
}
此模式允许轻松扩展和可维护性。
可以与员工保持可用性信息(以及其他与规则相关的信息)(参见Mike Jacob的回答)。但是,它可以与员工一起存储,也可以存储在单独的表格中。
如果您希望获得与规则相关的大量信息,您还可以将此可用性信息与员工区分开来。在这种情况下,Rules
可以定位另一个类:
...
bool Satisfies(RuleInfo info)
...
答案 2 :(得分:0)
我建议将'休假'作为特定日期与时间范围或模式存储。我已经开发了几个调度系统,这些系统具有处理联合规则和员工可用性的非常复杂的方法,这就是我们处理它的方式。
任何一个员工说我希望从y到z的日X从容易检查,或者他们可以定义他们想要或不想要的模式(例如,我不想工作周五)然后在安排时你可以检查是否将它们应用于特定班次会破坏设定规则(休息日)或者是否与特定模式匹配。
另外,我应该如何存储每位员工的这些数据?
有一张表来存储员工的特定例外情况。我希望从Y到Z的日X。您的员工有日期和时间跨度。很简单。
至于模式,您需要提出某种类型的模式。并且有类型或什么。
所以你可以有一个类似'每周关闭模式'的类型,它可以存储一整天的休息日,可以存储为代表休假日的简单字符串:1000001。假设第一个位是星期日,这将代表缺乏周末休息。然后,您可以将模式存储为字符串或其他内容,然后根据定义的类型,您将知道如何处理字符串。
这可能是一个非常复杂或简单的问题,它只取决于您需要允许多少自定义。希望这能为您提供足够的想法让您入门。
根据您需要支持的例外/规则,自动计划生成要复杂得多。
答案 3 :(得分:0)
“尽可能有效和一般地设计这个”
这些并不是相互排斥的,但是有效的和通用的 真的 难以实现,特别是在日程安排上系统。调度是一个非常重要的问题。
您的问题可能更好地说明为“我应该阅读哪些书才能开始这个?”和/或使其成为社区维基。
答案 4 :(得分:0)
这类似于graph-matching问题,也可以建模为Constraint Satisfaction Problem。您可能会发现NSolver有用,或Cassowary.Net
答案 5 :(得分:0)
我做了类似的事情,我所做的是创建了一个通用接口,然后为不同的场景创建了单独的实现。接口可能会检查IsInSchedule(dateTime)。然后,您可以根据需要创建不同的实现。
答案 6 :(得分:0)
Martin Fowler有一篇关于重复日历活动的有趣文章以及你可以采取的各种方法;当我写类似的东西时,我发现它非常有用: