PHP 移位调度 - 按顺序循环遍历具有众多子数组的多维数组



我正在尝试设计一个轮班调度程序。大约有十几个潜在用户(+/- 几个(,他们都有特定的假期要求。有 4 种类型的班次(角色 1、角色 2、角色 3、角色 4(;每个角色必须由一个人负责,一个人不能涵盖多个角色,并且一些用户更喜欢某些班次序列(例如角色 1-角色 2-角色 4-角色 3 与角色 1-角色 2-角色3-角色 4(,尽管最终如果无法在时间表内适应,则可以重新排列班次序列。有些用户根本无法在某些班次中工作。每个用户也有最大轮班次数 - 总体而言,系统内没有太多灵活性,因此我怀疑只有有限数量的可能有效解决方案。

我创建了一个考虑到强制用户假期的数组,因此对于每个日历日期,我知道理论上哪些用户可用于该班次(基线(:

[2020-07-21] => Array
(
[0] => Array
(
[role1] => userA
[role2] => userB
[role3] => userC
[role4] => userD
)
[1] => Array
(
[role1] => userA
[role2] => userB
[role3] => userD
[role4] => userC
)
[2] => Array
(
[role1] => userA
[role2] => userC
[role3] => userB
[role4] => userD
)

数组是由(但这段代码没有问题 - 当我尝试调用print_r(笛卡尔($solutionsArray((时; 内存不足。

// Use cartesian product to pick one value from each role array, and then exclude arrays that don't have at least 4 unique users
foreach ($globalAvailabilityCalendarArray[$globalAvailabilityCalendarDate] as $role => $availableUsersArray) {
$cartesianProducts = $utilities->cartesian($globalAvailabilityCalendarArray[$globalAvailabilityCalendarDate]);
foreach ($cartesianProducts as $cartesianProduct) {
if(count(array_unique(array_values($cartesianProduct))) !== count($this->roles)) {
continue;
} else {
$solutions[] = $cartesianProduct;
}
}
}
$solutionsArray[$globalAvailabilityCalendarDate] = array_unique($solutions, SORT_REGULAR);

不过我有几个问题:

  • 对于此时间段,需要考虑 63 个工作日。有些日子只有 4 人可用,因此可能的组合很小,但有些日子可能有 10+ 可用人员,这意味着数百种可能的有效组合。但是,每天的计划要求取决于为前几天选择的组合,因此它不会超过单个工作人员的最大班次数。因此,我正在尝试按顺序迭代每个子数组,直到找到第一个可能的有效解决方案(如果可能的话,其他有效的解决方案供用户比较( - (例如。[2020-07-01][0] ...[2020-07-02][1]...然后 [2020-07-01][0] ...[2020][07-02][2](. 我尝试计算笛卡尔积(使用 PHP 关联数组查找笛卡尔乘积(,它用于查找一天的可用组合,但是我的脚本在将其应用于整个日历时内存不足,因为可能的序列太多了。是否有内存消耗较少的替代方案?

  • 使用我的数组结构,我如何确定班次序列的优先级,以便用户具有良好的班次比率(目标是角色 1+角色 2+角色4/角色 3 = 2.5(和首选班次序列(例如角色 1-角色 2-角色 3-角色 4 并避免顺序繁忙班次,如角色 2-角色 2-角色 2-角色 2-角色 1(?

如果您遇到的唯一问题是使用cartesian函数时的内存使用情况,那么您可以搜索另一种方法来执行笛卡尔乘积而不消耗那么多内存。快速搜索后,我找到了您可以使用的可能解决方案。https://github.com/bpolaszek/cartesian-product

根据其文档,您可以像这样使用它:

print_r(cartesian_product($solutionsArray)->asArray());

最新更新