假设一个课程包括5个教程,从A到E标记,并且在课程中学生学习了7个不同的信息,我将其编号为1至7。在给定教程中学到的信息是固定的,但是我可以以任何顺序教授教程。例如,如果我想的话,我可以首先教授C教程。
Tut A: (1,2,3,4)
Tut B: (5,6,7)
Tut C: (2,3)
Tut D: (5,6)
Tut E: (1,2,3)
假设我按照以下顺序教授这些教程:
Ordering 1:
Tut A: (1,2,3,4)
Tut B: (5,6,7)
Tut C: (2,3)
Tut D: (5,6)
Tut E: (1,2,3)
Tut F: (1,3)
在第一个教程中,学生将学习4个信息点,在第二个教程中,学生将学习3个新的信息点。这样的顺序安排不好,因为学生在课程开始时需要学习过多的新信息(陡峭的学习曲线),并且在后续的教程中没有什么可学的了。以下是更好的顺序:
Ordering 2:
Tut C: (2,3)
Tut F: (1,3)
Tut E: (1,2,3)
Tut A: (1,2,3,4)
Tut D: (5,6)
Tut B: (5,6,7)
在第一节教程中,学生学到了两件新事物,在第二节学到了一件新事物,在第三节学到了一件新事物,在第四节没有学到新的东西,在第五节学到了两件新事物,在最后一节教程中学到了一件新事物。
这种排序几乎得到了相同的结果:
Ordering 3:
Tut C: (2,3)
Tut E: (1,2,3)
Tut F: (1,3)
Tut A: (1,2,3,4)
Tut D: (5,6)
Tut B: (5,6,7)
我已经写了以下函数:
def curve(tutorials):
covered = set()
for t in tutorials:
new = set(t).difference(covered)
covered.update(new)
yield len(new)
# Ordering 1:
print(tuple(curve(((1,2,3,4), (5,6,7), (2,3), (5,6), (1,2,3), (1,3)))))
# Ordering 2:
print(tuple(curve(((2,3), (1,3), (1,2,3,4), (1,2,3), (5,6), (5,6,7)))))
# Ordering 3:
print(tuple(curve(((2,3), (1,2,3), (1,3), (1,2,3,4), (5,6), (5,6,7)))))
我使用上述三种排序方法的数据进行调用,得到以下输出:
(4, 3, 0, 0, 0, 0)
(2, 1, 1, 0, 2, 1)
(2, 1, 0, 1, 2, 1)
我将使用以下函数来测量这些学习曲线的陡峭程度:
def steepness(r):
return sum((r[i]*(len(r)-i) for i in range(len(r))))
以下是三种排序方式的结果:
39
26
25
最佳解决方案是使用函数斜率返回的最小值进行排序。
以下是我解决此问题的完整方案:
import itertools
def curve(tutorials):
covered = set()
for t in tutorials:
new = set(t).difference(covered)
covered.update(new)
yield len(new)
def steepness(r):
r = tuple(r)
return sum((r[i]*(len(r)-i) for i in range(len(r))))
tutorials = ((1,2,3,4), (5,6,7), (2,3), (5,6), (1,2,3), (1,3))
print(min(itertools.permutations(tutorials), key=lambda x: steepness(curve(x))))
输出结果为:
((2, 3), (1, 2, 3), (1, 3), (1, 2, 3, 4), (5, 6), (5, 6, 7))
现在这一切都很好,但我实际上有30个教程需要排序,而不是上面提供的5个,并且我大约有20个独特的信息。我该如何优化我的解决方案,以便不需要花费太长时间来找到解决方案?