在一个生成随机学生组的程序中,我向用户提供强制将特定学生组合在一起的选项,并阻止学生配对。我已经尝试了两天来制作我自己的算法来实现这一点,但是我在所有的递归中都迷失了。我正在Lua中创建程序,但我将能够理解任何类型的伪代码。以下是学生如何分类的示例:
students = {
Student1 = {name=Student1, force={"Student2"}, deny={}};
Student2 = {name=Student2, force={"Student1","Student3"}, deny={}};
Student3 = {name=Student3, force={"Student2"}, deny={}};
}-- A second name property is given in the case that the student table needs to be accessed by students[num] to retrieve a name
然后我创建临时表:
forced = {}--Every student who has at least 1 entry in their force table is placed here, even if they have 1 or more in the deny table
denied = {}--Every student with 1 entry for the deny table and none in the force table is placed here
leftovers = {}--Every student that doesn't have any entries in the force nor deny tables is placed here
unsortable = {}--None are placed here yet -- this is to store students that are unable to be placed according to set rules(i.e. a student being forced to be paired with someone in a group that also contains a student that they can't be paired with
SortStudentsIntoGroups()--predefined; sorts students into above groups
每个学生都被安排在这些小组之后(注意他们还留在学生桌上),我首先插入被迫在小组中配对的学生(好吧,我已经尝试过),插入学生谁将deny表中的一个或多个条目放入可以放置它们的组中,并用剩余的组填充剩余的组。
有几件事情会有所帮助:
numGroups--predefined number of groups
maxGroupSize--automatically calculated; quick reference to largest amount of students allowed in a group
groups = {}--number of entries is equivalent to numGroups(i.e. groups = {{},{},{}} in the case of three groups). This is for storing students in so that the groups may be displayed to the end user after the algorithm is complete.
sortGroups()--predefined function that sorts the groups from smallest to largest; will sort largest to smallest if supplied a true boolean as a parameter)
正如我之前所说,我不知道如何为此设置递归算法。每当我尝试将强迫学生插入到一起时,我最终会将同一个学生分成多个组,强制配对没有配对,等等。还要注意格式。在每个学生的强制/拒绝表中,给出了目标学生的姓名 - 而不是直接参考学生。我应该使用什么样的算法(如果这种情况存在的话)?任何帮助是极大的赞赏。
答案 0 :(得分:3)
我觉得你在这里遇到了 NP-Hard 问题。
这相当于k
问题Given a graph G=(V,E), and an integer `k`, create coloring function f:V->{1,2,..,k} such that:
f(v) = f(u) -> (v,u) is NOT in E
颜色,其中edge是拒绝列表。
图表着色:
(G,k)
从图表着色到问题的减少:
鉴于图表着色问题G=(V,E)
students = V
for each student: student.denial = { student' | for each edge (student,student')}
#groups = k
,请使用以下方法创建问题实例:
k
直观地,每个顶点由学生表示,并且学生否认所有学生在表示它们的顶点之间存在边缘。 组的数量是给定的颜色数。
现在,考虑到您的问题的解决方案 - 我们会收到u
个小组,如果学生v
拒绝学生u
- 他们不属于同一群组,但这与以不同颜色着色v
和u
,因此对于原始图表中的每个边缘(u,v),v
和k
具有不同的颜色。
另一种方式是类似的
所以,我们从图形着色问题到达graph-coloring,因此找到问题的最佳解决方案是NP-Hard,并且没有已知的有效解决此问题的方法,而且大多数人认为一个不存在。
一些替代方案正在使用诸如polynomial reduction之类的启发式方法,这种方法不能提供最佳解决方案,或者使用耗时的Genetic Algorithms方法(对于大量学生来说不可行)。 蛮力只会产生对{{1}}组的所有可能分裂,并检查它是否是可行的解决方案,最后 - 将选择找到的最佳解决方案。