将课程分配给要求的算法

时间:2016-07-06 21:19:39

标签: algorithm typescript

我正在尝试确定用于解决分配课程的最佳算法。要求具有一定数量的学分才能被视为已完成。并且课程获得了许多学分。所以数据结构看起来像:

export class Course {
  constructor(public id:number,
              public credits:number) {
  }
}


export class Requirement {
  constructor(public id:number,
              public name:string,
              public credits:number,
              public courses:RequirementCourse[] = []) {
  }
}

并给出以下数据集:

let requirments =  [
       new Requirement(1, 'math',    3, [1,2,3,4]),
       new Requirement(2, 'science', 2, [5]),
       new Requirement(3, 'english', 2, [2,7]),
       new Requirement(4, 'history',     2, [2,8])
     ];

let courses =  [
      new Course(1,1),
      new Course(2,0.5),
      new Course(3,1),
      new Course(4,1),
      new Course(5,1),
      new Course(6,1),
      new Course(7,1),
      new Course(8,1),
      new Course(9,1)
    ]

确定如何根据需求分配课程的最有效算法是什么。

注意:数据集简化了我的实际用例。特别是,Requirement courses数组中的课程将具有相关的优先级。此外,用户还可以手动分配需要分配给指定要求的课程。

编辑:根据以下评论,算法必须符合以下规则

  • 课程学分不能超过一个学分

  • 如果某个课程有多个学分,则可以将它们分成多个要求

  • 如果没有足够的学分来满足所有要求,算法需要分配学分来填充尽可能多的要求

  • 如果两个课程可以分配到同一个要求,并且不能满足要求(即需要冲突课程的学分),课程必须标记为冲突

    < / LI>

1 个答案:

答案 0 :(得分:2)

鉴于评论,这绝对是最大流量。根据您的输入,构建以下图表:

  • 超级来源 SOURCE
  • 超级水槽 SINK
  • 每个课程
    • 代表该课程的节点 c
    • SOURCE c 的优势,其容量等于 c 的信用点数
  • 满足每项要求:
    • 表示该要求的节点 r
    • r SINK 的优势,其容量等于 r 的信用要求
  • 每个课程 c / required r 对:
    • 如果给定的课程满足给定的要求,从 c r 的边缘,其容量等于 c 的学分数

然后只需将 SOURCE 的最大流量运行到 SINK 。如果最大流量等于所有要求的总信用要求,则您已找到有效流量。只需读取最后一步添加的边缘上的流量,找出哪些课程用于哪些要求。如果最大流量是较低的数字,则无法用给定的课程填写每个要求。

总运行时间:

  • 图表构建(其中C是课程数,R是要求数):
    • 添加节点:1 + 1 + C + R = O(C+R)
    • 添加边缘:C + C*R + R = O(C*R)
  • 运行最大流量
    • 假设preflow push是选择的算法:O(V^3) = O((C+R)^3)
  • 转换为问题解决方案:
    • 检查最大流量有效性:R = O(R)
    • 回读课程:C*R = O(C*R)

因此,我认为该算法受O((C+R)^3),最大流量部分

的约束