许多学生想要进入课程的部分,有些已经注册了一个部分,但想要更改部分,所以他们都进入等候名单。只有当某人从该部分退出时,学生才能进入新的部分。没有学生愿意放弃他们已经在的部分,除非可以肯定进入他们正在等待的部分。每个部分的等待名单先到先得。
尽可能多的学生进入他们想要的部分。
陈述的问题很快就会转变为僵局情景。我的问题是;有这个问题的已知解决方案吗?
一个简单的解决方案是轮流拍摄每个部分,并强迫第一个学生从等待名单进入该部分,然后检查是否有人在事情解决时最终退出(O(n)或更多关于部分)。这适用于某些情况,但我认为可能有更好的选择,包括强制不止一个学生进入一个部分(学生数量为O(n)或更多)和/或一次操作多个部分(O (坏): - )
答案 0 :(得分:2)
那么,这仅仅是在有针对性的类图中寻找周期吗?每个链接都是一个想要从一个节点转到另一个节点的学生,每当你找到一个循环时,你就删除它,因为这些学生可以相互解决他们的需求。当你没有周期时,你就完成了。
答案 1 :(得分:2)
好的,试试吧。我们有8名学生(1..8)和4个部分。每个学生都在一个部分,每个部分都有2个学生的空间。大多数学生想要转换,但不是全部。
在下表中,我们会看到学生的当前部分,他们所需的部分以及队列中的位置(如果有的话)。
+------+-----+-----+-----+
| stud | now | req | que |
+------+-----+-----+-----+
| 1 | A | D | 2 |
| 2 | A | D | 1 |
| 3 | B | B | - |
| 4 | B | A | 2 |
| 5 | C | A | 1 |
| 6 | C | C | - |
| 7 | D | C | 1 |
| 8 | D | B | 1 |
+------+-----+-----+-----+
我们可以在图表中显示此信息:
+-----+ +-----+ +-----+
| C |---[5]--->1| A |2<---[4]---| B |
+-----+ +-----+ +-----+
1 | | 1
^ | | ^
| [1] [2] |
| | | |
[7] | | [8]
| V V |
| 2 1 |
| +-----+ |
\--------------| D |--------------/
+-----+
我们试图找到一个空缺的部分,但我们找不到。因为所有部分都已满,我们需要一个肮脏的技巧。因此,让我们采用非空队列的随机部分。在这种情况下,A部分假定它有一个额外的位置。这意味着学生5可以进入A部分,留下C部分由学生7录取的空缺。这留下D部分由学生2拍摄的空缺。我们现在在A部分有空缺。但我们假设该部分A有一个额外的位置,所以我们可以删除这个假设并获得一个更简单的图形。
如果路径从未返回到A部分,请撤消移动并将A标记为无效的起始点。重试其他部分。 如果没有剩下有效的部分,我们就完成了。
目前我们有以下情况:
+-----+ +-----+ +-----+
| C | | A |1<---[4]---| B |
+-----+ +-----+ +-----+
| 1
| ^
[1] |
| |
| [8]
V |
1 |
+-----+ |
| D |--------------/
+-----+
我们用另一个随机部分重复这个技巧,这解决了图形。
如果您从目前未分配的几名学生开始,则添加一个额外的虚拟部分作为他们的起点。当然,这意味着任何部分都必须有空缺,否则问题无法解决。
请注意,由于队列中的顺序,可能没有解决方案。
答案 2 :(得分:1)
这实际上是一个Graph问题。您可以将每个等待列表依赖关系视为有向图上的边。如果此图表有一个循环,那么您有一个您描述的情况。一旦你确定了一个循环,你可以通过“过度填充”其中一个类来选择任何一个“打破”循环的点,你就会知道事情会正确解决,因为图中有一个循环。