我正在为家庭护理公司开发一个PHP应用程序。他们每周安排x个护理人员参加x个服务用户(客户)的住宿。每个服务用户都有一个“时间表”,其中包括访问时间和时间以及以分钟为单位的访问持续时间。
例如,服务用户可以拥有以下计划。
AM Lunch Tea Late Night Respite
Mon 30m - 30m 60m - -
Tue 30m - - 60m - -
Wed 20m 25m 30m 60m 120m -
Thu - - 30m - - -
Fri 30m 25m - - - -
Sat - - - - - -
Sun 20m 25m - - - -
这些期间目前以下列格式存储在数据库中:
Table: Service_user_schedules
id service_user_id day period duration
护理人员每周都会填写一份表格,列出他们可以上班的时间。然后将该数据输入系统并以下列格式存储在数据库中:
Table: Carer_available_shifts
id carer_id day period
现在的问题是,我需要创建一个控制器来获取这些数据,并根据他们提供的可用性自动将护理者分配给服务用户。这需要是可编辑的,以便在没有人可用于特定照顾者的情况下,用户可以选择一个不可用的,并且它们仍将被添加到数据库中。
目前,我有一堆乱七八糟的循环,功能和回声,以检查护理人员是否可用于特定服务用户并使其可编辑。
之前有没有人执行过这种任务,如果有的话,你找到了一种简单的方法来完成它。我宁愿让它面向对象,所以我可以重用相同的泛型类,但此刻,我完全失去了!
编辑:我现在已经为这个问题增加了一笔赏金。我目前正在研究遗传算法(我从来没有听说过,更不用说了!)作为基于一些答案的这个问题的解决方案。我想知道你是否有人使用其他方法来解决这类问题,或者你是否使用过遗传算法,你能不能就如何将它们应用于这个特定问题提供一般性的解释。
我认为这个障碍在许多“人员配备”类型的应用程序中相当普遍,并且对网上任何地方的讨论很少感到惊讶!
更新
对于这个特定的项目,我想我最终可能会使用Tak所描述的数据库方法,但如果我有更多的开发时间,将来可能转换为使用GA。
我现在对谁给予赏金奖励感到有点失落。 duedl0r为他(或她)的答案付出了很多努力。它让我对遗传算法的世界有了深刻的了解 - 这是一种我以前从未遇到过的问题解决方法。但是,Tak提供的答案提供了我将用于此项目的解决方案。因此,我已将此奖励给了Tak。
答案 0 :(得分:3)
听起来像the employee shift rostering problem,这是NP完全的。
如果您认为元启发式(例如遗传算法,禁忌搜索,模拟退火......)过度,那就去simple First Fit Decreasing algorithm。
答案 1 :(得分:2)
也许你可以使用遗传算法。这样做的好处是你可以做一些非常疯狂的事情(如果你已经设置了基础知识),例如:您还可以说护理人员应该优先访问他以前访问过的服务用户,或者最小化访问之间的距离:)
这样做即使没有可用的时间表,每个服务用户都会得到一个看护人。 该算法只是试图创建一个最优解决方案..
可能它有点矫枉过正,但这是一个有趣的话题.. :)我想提一下,因为它可能是一种解决问题的新方法。至少值得一想;)
一些链接: Genetic Algorithm Resource,Genetic Algorithm Tutorial,Wikipedia
编辑:更具体的遗传算法解释。
遗传算法包括对进化发展理论进行建模。进化发展需要一群生物。然后你使用某些生物效应模拟人口的发展,如变异,选择,交叉等。就像darwin几年前发现的那样:)
现在你必须将你的问题映射到这样的生物(或DNA)。这意味着每个生物都代表着你问题空间的解决方案(每个DNA都是你问题的解决方案)。
因此,“适者生存”这句话只是意味着“我得到了一个可能是最优的问题的解决方案”(尽管不能保证)。
从您的问题到这样的DNA的映射可以完全不同。首先,您需要一个数组来表示您的DNA。您可以指定例如:
您为每个服务用户创建了42个元素的块(每天6个插槽,每周7天)。然后,您在阵列中的第一个条目是服务用户1的“AM”/ Mon插槽。您的第二个条目是服务用户1的“午餐”/周一插槽。您的第43个条目是服务用户2的“AM”/ Mon插槽这定义了你的生物的DNA。然后你让他们互相驼背,这样他们就可以发展:)
为了找出合适的生物,你还需要一个计算合身度的公式。您创建一个公式,其中DNA为输入,数字为输出。这取决于您的规则。例如,如果存在或不存在某些规则,您可以给出一些加号或减号。如果护理员同时用于两个不同的服务用户,你会给出一些减分,如果护理人员实际上有时间用于一个插槽并且他真的是为服务用户安排的,你可以给予加分。
您还可以说:遗传算法试图找出如何使用遗传方法最大化这个公式。
非常简短的遗传算法介绍..如果你有足够的时间,如果你也对这个话题感兴趣,那么它真的值得深入研究......你可以用它来制作一些非常酷的东西。但请记住,它也会变得混乱和复杂:)
答案 2 :(得分:1)
Table schedules_shifts
id service_user_schedules_id carer_available_shifts_id
现在有一个功能可以将可用的护理人员与所需的计划时间段相匹配并填充表格......
* Fetch service_user_schedules for the next week
* For each service_user_schedules row
* Fetch carer_available_shifts that match the schedule slot
* For each carer_available_shift row
* If results
* Fetch schedules_shifts rows where carer_available_shifts_id is already used
* If no results
* Insert a row in the schedules_shifts table for each carer
* Otherwise carer is busy, do nothing and continue
* If no results, flag for review or trigger e-mail to manager, or other action
* Trigger e-mail or save log of completion for peace of mind
新表现在可以为计划槽提供护理者匹配,而无需重复分配护理者的时间。然而,它确实将多个护理者的班次与计划时段相匹配。这可能是一个功能!保持原样并在confirmed
上添加schedules_shifts
列,以便经理可以手动分配工作,或者护理人员可以自愿,或自动将第一场比赛标记为confirmed
并保留另一个如果第一个护理人员无法成功,则行作为替代方案。
这一切都可以由cron每周触发,或者最终职业生涯更新本周的时间表。可能是第一个,因为用户通常是不可预测的。
现在,自动数据位于表格中,您可以打开它进行编辑。创建一个普通的管理控制台,就像根据需要更改schedules_shifts
中的行一样,或者标记不同的行“已确认”。
将其翻译成通用类应该不会太困难 - 只需使用通用术语。现在已经很晚了,我想不出任何事情:)
可以在PHP数组中进行所有数据筛选,而不是上面创建的数据库舞蹈,但我认为SQL更适合于对数据进行排序和修改。
遗传算法听起来很有趣,如果你有时间研究它们^ _ ^
希望有帮助吗?