因此,最近我得到了一个问题,我一直在考虑这个问题,但仍然无法解决;我想知道这里是否有人能通过为我提供这个问题的psuedo代码(或至少一个伪代码的大致轮廓)来指出正确的方向。如果这有区别的话我会用PHP构建的PS ..。
规格
有50个人(在这个例子中,我只叫他们a,b,c.)用户将将它们分组为三组(组中的人可能重叠),最后将有50-100组(即{a,b,c};{d,e,f};{a,d,f};{b,c,l}.)。*
到目前为止,这是一个简单的问题,那就是构建html表单并将其处理为多维数组。
白天有15个时隙(如上午9:00,上午9:20,上午9:40)。这些小组中的每一个都需要在白天开会一次。在一段时间内,该人不能被双重预订(即“a”不能在上午9点40分分成两个不同的组)。
这里很棘手,但也不是不可能,我对如何做到这一点的最好的猜测是用蛮力(挑选一组没有重叠的组(如{a,b,c};{l,f,g};{q,n,d}.)然后把每一个都放进一个时隙
最后,我输出的日程需要‘优化’,我的意思是'a‘应该在两次会议之间有最少的时间(所以如果他的第一次会议是在上午9:20,那么他的第二次会议不应该是下午2:00)。
这里是我迷路的地方,我唯一的猜测是建立很多很多的时间表,然后根据一个人从一次会议到下一次会议的平均等待时间对它们进行排序。
然而,我的“解决方案”(我不愿称之为解决方案)需要太多的蛮力,而且要花很长时间才能创造出来。有没有更简单、更优雅的解决方案?
发布于 2011-06-19 05:04:01
这些是布置好的桌子,为你的风景做了修改。
+----User_Details------+ //You may or may not need this
| UID | Particulars... |
+----------------------+
+----User_Timeslots---------+ //Time slots per collumn
| UID | SlotNumber(bool)... | //true/false if the user is avaliable
+---------------------------+ //SlotNumber is replaced by s1, s2, etc
+----User_Arrangements--------+ //Time slots per collumn
| UID | SlotNumber(string)... | //Group session string
+-----------------------------+注意:排列表中的字符串采用以下格式: JSON
'12,15,32‘/从最小到最大!
因此,排列表中发生的情况是,脚本或EXCEL列公式将遍历每个会话的每个时隙,并随机创建一个可能的会话。检查所有以前的会话是否有冲突。
/**
* Randomise a session, in which data is not yet set
**/
function randomizeSession( sesionID ) {
for( var id = [lowest UID], id < [highest UID], id++ ) {
if( id exists ) {
randomizeSingleSession( id, sessionID );
} //else skips
}
}
/**
* Randomizes a single user in a session, without conflicts in previous sessions
**/
function randomizeSingleSession( id, sessionID ) {
convert sessionID to its collumns name =)
get the collumns name of all ther previous session
if( there is data, false, or JSON ) {
Does nothing (Already has data)
}
if( ID is avaliable in time slot table (for this session) ) {
Get all IDs who are avaliable, and contains no data this session
Get all the UID previous session
while( first time || not yet resolved ) {
Randomly chose 2
if( there was conflict in UID previous session ) {
try again (while) : not yet resolved
} else {
resolved
}
}
Registers all 3 users as a group in the session
} else {
Set session result to false (no attendance)
}
}你会意识到组分配的主要部分是通过随机化完成的。然而,随着会话数量的增加。将有越来越多的数据来检查冲突。导致性能要慢得多。无论多大,大得离谱,几乎是完美的排列/组合形式。
编辑:
此设置还将有助于确保,只要用户可用,它们将在一个组中。虽然你可能有很多用户,但是没有用户组(一个小数目)。通常通过重新计算(对于小的会话数)来补救这些问题。或者只是手动将它们组合在一起,即使是重复。(这里和那里都有几个并不伤人)。或者,在你的情况下,和剩下的人一起,加入几组3人,组成4. =组。)
如果这可以适用于EXCEL和大约100+ ppl,以及大约10个会话。我不明白这在SQL + PHP中是如何工作的。只是计算实际上可能需要相当长的时间,两者都是如此。
发布于 2011-06-19 05:21:19
好的,对于那些刚刚加入这个帖子的人,在考虑这个答案的内容之前,请阅读所有对这个问题的评论,因为这很可能会在你的头上飞过。
下面是一些PHP风格的伪代码:
/* Array with profs (this is one dimensional here for the show, but I assume
it will be multi-dimensional, filled with availability and what not;
For the sake of this example, let me say that the multi-dimensional array
contains the following keys: [id]{[avail_from],[avail_to],[last_ses],[name]}*/
$profs = array_fill(0, $prof_num, "assoc_ids");
// Array with time slots, let's say UNIX stamps of begin time
$times = array_fill(0, $slot_num, "time");
// First, we need to loop through all the time slots
foreach ($times as $slot) {
// See when session ends
$slot_end = $slot + $session_time;
// Now, run through the profs to see who's available
$avail_profs = array(); // Empty
foreach ($profs as $prof_id => $data) {
if (($data['avail_from'] >= $slot) && ($data['avail_to'] >= $slot_end)) {
$avail_prof[$prof_id] = $data['last_ses'];
}
}
/* Reverse sort the array so that the highest numbers (profs who have been
waiting the longest) will be up top */
arsort($avail_profs);
$profs_session = array_slice($avail_profs, 0, 3);
$profs_session_names = array(); // Empty
// Reset the last_ses counters on those profs
foreach ($profs_session as $prof_id => $last_ses) {
$profs[$prof_id]['last_ses'] = 0;
$profs_session_names[0] = $profs[$prof_id]['name'];
}
// Now, loop through all profs to add one to their waiting time
foreach ($profs as $prof_id = > $data) {
$profs[$prof_id]['last_ses']++;
}
print(sprintf('The %s session will be held by: %s, $s, and %s<br />', $slot,
$profs_session_names[0], $profs_session_names[1],
$profs_session_names[2]);
unset ($profs_session, $profs_session_names, $avail_prof);
}应该打印如下的内容:
The 9:40am session will be held by: C. Hicks, A. Hole, and B.E.N. Dover发布于 2011-06-19 05:28:03
我看到一个包括以下内容的对象模型:
case)
。
现在,正如您所观察到的,优化是关键。对我来说,问题是:“最优的准则是什么?”汤姆的最佳选择可能意味着他所在的小组没有很大的缺口。但哈利的面板可能到处都是。因此,对于给定的调度,我们计算类似于totalMemberDeadTime (=时间表中所有死时间成员间隙之和)的内容。最优调度是与此和相关的最小调度。
如果我们对在所有时间表的宇宙中计算一个技术上最优的时间表感兴趣,我看不出有什么替代蛮力的方法。
也许这一系列的时间表不需要像第一次看上去那么大。听起来,这些小组是先组成的,然后问题是把它们分配给构成会议时间表的会议。因此,我们去掉了小组组成中的可变性,整个可变性的范围都在会议和时间表中。尽管如此,看起来确实存在很大的可变性。
但是,就所有可能的时间表而言,最优的时间可能比我们真正需要的要多。
如果没有任何小组成员的总死亡时间超过X,我们可以将时间表定义为可以接受吗?或者失败,如果不超过X小组成员的死时间超过X(不能满足每个人,但保持最低限度)?然后,用户可以为包含更“重要”小组成员的小组安排会议,而不太重要的人只需接受他们得到的东西。那么我们所要做的就是做一个可以接受的时间表。
对任何两个附表进行比较,是否就足以达到您的目的?结合一个界面(我看到了一个拖放界面,但这显然超出了要点),它允许用户制定一个计划,将其克隆到第二个计划中,并对第二个计划进行调整,以减少总死时间,直到我们找到一个可以接受的时间。
不管怎样,不是一个完整的答案。只是大声地想出来。希望能帮上忙。
https://stackoverflow.com/questions/6400365
复制相似问题