java算法设计将一组学生分组

ycggw6v2  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(445)

我在学习算法设计,我看到了这个问题:问题:我们有n个学生在(从1到n)。学生需要分成小组进行课堂活动。每个学生都有一个偏好,即在他们的小组里有多少学生。具体来说,学生i希望他们组中的学生人数介于x[i]和y[i](包括在内)之间。换句话说,如果这个组(我被分配到的学生)有g个人,那么x[i]≤ 克≤ 你[我]必须坚持住。每个学生必须被分配到一个小组(即使小组只有一个学生)。给定n和x[],y[],算法应该确定这是否可行。
以下是一些例子:
例1:n=5,(x[],y[])={(1,2),(1,3),(2,3),(2,2),(3,3)}。
我们可以把学生1和学生4分到一个小组(这个小组的人数是2),另外三个学生分到另一个小组。这将满足每个人的约束。
例2:n=5,(x[],y[])={(1,2),(1,2),(2,3),(2,2),(3,3)}。
要满足学生5的约束是不可能的,因为只有两个学生对一组大小为3的学生“满意”(然而学生5只希望组中正好有3个学生)。
例3:n=5,(x[],y[])={(1,1),(2,2),(2,2),(2,5),(2,4)}。
学生1可以被分配到一个单独的小组。学生2-5可以任意分配到两组大小2(因为每个人都可以在他们的小组中有2个学生)。因此,存在许多解决方案。
我的第一个想法是按y[i]对数组排序,然后从第一个元素开始,根据y[i]的值将人分组。但是在例子2中会发生什么呢?
我的第二个想法是按x[i]+y[i]对数组进行排序,因为y[i]大于x[i],所以我们可以从第一个元素开始,并将人分组(但我认为第一个想法更好)
总的来说,我认为这两个算法是不够的,我正在寻找更充分的(如果有)

svujldwt

svujldwt1#

我认为您的第一个解决方案非常出色,示例2没有任何问题。
当然,首先要按y[i]对数组进行排序。然后你从最大的到最小的开始。
如果无法创建此大小的组-请确保可以移动到较小的大小(例如,没有一个组的“严格”条件是只有一个可能的大小)。例如,在案例2中-这是不可能的,因为学生5没有这个选项,所以算法会立即返回false。

dz6r00yl

dz6r00yl2#

我找到了一个多项式方法来解决这个问题,主要是根据偏好的限制程度进行排序。

注意以下几点:

如果有人喜欢 [x, x] =>这是最严格的限制,因为我们应该给他找一组大小正好的 x 另一方面,宽松的偏好尺寸 for ex. [1, 1000] =>它是限制性最小的,在考虑更多限制性偏好之前不必考虑
在形成组时,一旦达到最大大小=>则假定组已形成;例如 [1,1] => group of size 1 is ready ####代码准备::class=组
在实现时,我想如果我创建一个 Group class 维护:
组的所有成员(成员按其首选项)
集团合并最小规模
集团合并最大规模
有效性检查器方法来确定组是否最终有效。例如 [(3, 3), (2, 3)] 不是有效的组

如何从初始首选项列表开始

如上所述,我们需要根据限制性最强到限制性最弱的偏好对偏好列表进行排序,即。 y[i]-x[i] ####时间复杂度:o(n^2)

下面是python的工作代码:

from typing import List

class Group:
    def __init__(self, s: int, e: int):
        self.members = [(s, e)]
        self.min, self.max = s, e

    def add_member(self, s: int, e: int):
        self.members.append((s, e))
        self.min, self.max = max(self.min, s), min(self.max, e)

    def can_fit(self, s: int, e: int) -> bool:
        return not (self.reached_maxsize() or (e < self.min or s > self.max))

    def reached_maxsize(self) -> bool:
        return len(self.members) == self.max

    def check_group_validity(self) -> bool:
        num_members = len(self.members)
        return self.min <= num_members <= self.max

def create_groups(preference_list):
    groups: List[Group] = []
    preference_list = sorted(preference_list, key=lambda x: (x[1] - x[0], x[0], x[1]))

    for pref in preference_list:
        found_group = False
        for grp in groups:
            if grp.can_fit(pref[0], pref[1]):
                grp.add_member(pref[0], pref[1])
                found_group = True
                break
        if not found_group:
            groups.append(Group(pref[0], pref[1]))

    # check groups-validity
    if all(group.check_group_validity() for group in groups):
        return groups

    print("No grouping is possible")
    return []

res = create_groups([(1, 2), (1, 3), (2, 3), (2, 2), (3, 3)])
print([x.members for x in res])

res = create_groups([(1, 2), (1, 2), (2, 3), (2, 2), (3, 3)])
print([x.members for x in res])

res = create_groups([(1, 1), (2, 2), (2, 2), (2, 5), (2, 4)])
print([x.members for x in res])

测试输出:

[[(2, 2), (1, 2)], [(3, 3), (2, 3), (1, 3)]]

No grouping is possible
[]

[[(1, 1)], [(2, 2), (2, 2)], [(2, 4), (2, 5)]]

相关问题