学校排课算法

时间:2018-06-20 11:34:07

标签: c# algorithm combinatorics

任务是这样。课程11a每周应教授35个小时(6天,无周日)。在一天中,他们必须教6个小时(最多)。

“ Matematika”每周-4小时,“ Fizika” -4小时,“ Rusi”-2小时,“ Anglisi” -2小时,“ Naqsha” -2小时, “ Biologiya” -2小时,“ Himiya” -2小时,“ Botanika” -2小时,“ Adabiyot” -3小时, “ Zabon-3小时”,“ Huquq” -3小时,“ TXT” -2小时,“ TDQ” -4。

我创建了这样的课程:

 class Class
{
    public string Name { get; set; }
    public Dictionary<string,int> Subjects { get; set; }
    public int MaxHoursInDay { get; set; }
    public int MaxHoursInWeek { get; set; }

}

然后我填写了数据:

 Class _class = new Class();
        _class.Name = "11 a";
        _class.MaxHoursInDay = 5;
        _class.MaxHoursInWeek = 35;
        _class.Subjects = new Dictionary<string, int>();
        _class.Subjects.Add("Matematika", 4);
        _class.Subjects.Add("Fizika", 4);
        _class.Subjects.Add("Rusi", 2);
        ...

现在,我想生成所有可能的计划选项。有解决问题的公式或算法吗?

1 个答案:

答案 0 :(得分:0)

这不是最快也是最干净的方法,但这是该过程的基本逻辑。

  • 首先将List的所有课程及其小时数投入。
  • 然后生成列表的所有排列。这将为序列创建所有可能的排序。这会产生成千上万的可能性。请以MoreLinq Permutation为例。
  • 一旦有了所有排列,就需要创建上课的天数,以查看此组合工作的天数。因此,迭代每个排列。
  • 对于每个排列,请创建一个类别列表,并将其命名为“ ClassDay”,然后仅在总小时数低于您的阈值(5小时)时,将排列所指定的顺序添加到该类别中。
  • 如果您要添加的课程总数超过5小时,则将ClassDay存储在另一个List中(非常重要),开始一个新的ClassDay并保持一次又一次地使用相同的逻辑进行添加(最多5个小时),直到您将所有课程都置于最长5个小时的ClassDay中。
  • 最后检查每个排列创建了多少ClassDay。对于单个排列,您没有6 ClassDay以外的任何东西,这种组合不好。只有正好为6 ClassDay的用户才是有效组合。

如果可以将班级划分为不同的小时段,例如2小时可以得到2乘以1小时,则需要将所有班级拆分为尽可能小的段。然后,您将需要最后一道通行证,以按顺序合并一天中的所有课程,因此,如果3 x 1小时Matematika彼此跟随,则会将它们重新分组为3小时中的1小时。