0

我编写了以下程序来生成未来三年我可能拥有的所有可能的时间表(我在季度系统上)但它的效率低得离谱,而且正如所写的那样,在接下来的一百万年里不会给我答案.

为了澄清,我确实已经编写了文本文件,指定了我感兴趣的课程以及每个季度的数字、期限和年份(例如,2013-2014 年第 1 季度秋季)。我想将其限制为每季度生成 4-5 节课的时间表,希望在程序中有所体现。

我知道,考虑到所需结果的大小,我写这个的任何方式都会非常慢,但是如果有人可以帮助我加快速度,或者至少给我一个估计需要多长时间才能完成( 24 小时或 24 个月)我将非常感激。

我已经确定但我不知道如何解决的两个问题是:

  1. 我的比较功能(将列表转换回列表,然后在列表的每个成员中搜索另一个列表的每个成员)
  2. 一般来说,列表的广泛使用,根据我的研究,它非常占用内存(例如,我使用的组合函数会生成一个迭代器对象,根据我的研究,它应该比列表更有效,但我没有知道如何有效地使用迭代器,从而减少内存使用;还有我在程序结束时使用的“GrandMasterLists”方法,结合所有的双 for 循环和线性增加的比较函数调用次数每个 for 循环,也必须使这比它需要的效率低得多)。

以下内容很长(177 行)(尽管也是重复的),但如果您正在寻找挑战或者您是编程专家,我将非常感谢您的帮助。

(我也意识到我在每一点上尝试做的很多事情可能不是很透明——在很多时候我都很难想出与我想要做的代码相匹配的代码——所以如果您需要澄清,请向我提问。)

import itertools

class Course:
    def __init__(self, NAME, TERM, YEAR):
        self.term=TERM
        self.year=YEAR
        self.name=NAME


class Quarter:
    def __init__(self, NUMBER, TERM, YEAR):
        self.term=TERM
        self.year=YEAR
        self.number=NUMBER

courselist=[]

def coursegen(NAME, TERM, YEAR):

    return Course(NAME, TERM, YEAR)

f=open('classlist.txt', 'r')
for line in f:
    courselist.append(coursegen(line.rstrip().split(';')[0],line.rstrip().split(';')    [1].split(','),line.rstrip().split(';')[2].split(','))) 
f.close()       

def quartergen(NUMBER,TERM,YEAR):
    return Quarter(NUMBER,TERM,YEAR)

m=open('quarterlist.txt', 'r')

line1=m.readline()
line2=m.readline()
line3=m.readline()
line4=m.readline()
line5=m.readline()
line6=m.readline()
line7=m.readline()
line8=m.readline()
line9=m.readline()

Quarter1=quartergen(line1.rstrip().split(';')[0],line1.rstrip().split(';')[1].split(','),line1.rstrip().split(';')[2].split(','))
Quarter2=quartergen(line2.rstrip().split(';')[0],line2.rstrip().split(';')[1].split(','),line2.rstrip().split(';')[2].split(','))
Quarter3=quartergen(line3.rstrip().split(';')[0],line3.rstrip().split(';')[1].split(','),line3.rstrip().split(';')[2].split(','))
Quarter4=quartergen(line4.rstrip().split(';')[0],line4.rstrip().split(';')[1].split(','),line4.rstrip().split(';')[2].split(','))
Quarter5=quartergen(line5.rstrip().split(';')[0],line5.rstrip().split(';')[1].split(','),line5.rstrip().split(';')[2].split(','))
Quarter6=quartergen(line6.rstrip().split(';')[0],line6.rstrip().split(';')[1].split(','),line6.rstrip().split(';')[2].split(','))
Quarter7=quartergen(line7.rstrip().split(';')[0],line7.rstrip().split(';')[1].split(','),line7.rstrip().split(';')[2].split(','))
Quarter8=quartergen(line8.rstrip().split(';')[0],line8.rstrip().split(';')[1].split(','),line8.rstrip().split(';')[2].split(','))
Quarter9=quartergen(line9.rstrip().split(';')[0],line9.rstrip().split(';')[1].split(','),line9.rstrip().split(';')[2].split(','))

m.close()   

def compare(x, y):

    if set(x).isdisjoint(set(y))==False:
    return True
else:
        return False

def offeredcoursegen(Quarter, courselist):
    offered=[]

    for course in courselist:

        if compare(course.year, Quarter.year)==True and compare(course.term, Quarter.term)==True:

            offered.append(course)

    return offered

def combo(x, courselist):   
    return list(itertools.combinations(offeredcoursegen(x,courselist), 4))+list(itertools.combinations(offeredcoursegen(x,courselist), 5))

Combo1=combo(Quarter1, courselist)

Combo2=combo(Quarter2, courselist)

Combo3=combo(Quarter3, courselist)

Combo4=combo(Quarter4, courselist)

Combo5=combo(Quarter5, courselist)

Combo6=combo(Quarter6, courselist)

Combo7=combo(Quarter7, courselist)

Combo8=combo(Quarter8, courselist)

Combo9=combo(Quarter9, courselist)

GrandMasterList=[]

for i in Combo1:
    for j in Combo2:
        if compare(i, j)==False:
            GrandMasterList.append([i,j])

GrandMasterList2=[]

for i in GrandMasterList:
    for j in Combo3:
        if compare(i[0],j)==False and compare(i[1],j)==False:
            GrandMasterList2.append(i+[j])

GrandMasterList3=[]

for i in GrandMasterList2:
    for j in Combo4:
        if compare(i[0],j)==False and compare(i[1],j)==False and    compare(i[2],j)==False:
            GrandMasterList3.append(i+[j])

GrandMasterList4=[]

for i in GrandMasterList3:
    for j in Combo5:
        if compare(i[0],j)==False and compare(i[1],j)==False and compare(i[2],j)==False and compare(i[3],j)==False:
            GrandMasterList4.append(i+[j])

GrandMasterList5=[]

for i in GrandMasterList4:
    for j in Combo6:
        if compare(i[0],j)==False and compare(i[1],j)==False and compare(i[2],j)==False and compare(i[3],j)==False and compare(i[4],j)==False:
            GrandMasterList5.append(i+[j])

GrandMasterList6=[]

for i in GrandMasterList5:
    for j in Combo7:
        if compare(i[0],j)==False and compare(i[1],j)==False and compare(i[2],j)==False and compare(i[3],j)==False and compare(i[4],j)==False and compare(i[5],j)==False:
            GrandMasterList6.append(i+[j])

GrandMasterList7=[]

for i in GrandMasterList6:
    for j in Combo8:
        if compare(i[0],j)==False and compare(i[1],j)==False and compare(i[2],j)==False and compare(i[3],j)==False and compare(i[4],j)==False and compare(i[5],j)==False and compare(i[6],j)==False:
            GrandMasterList7.append(i+[j])

GrandMasterList8=[]

for i in GrandMasterList7:
    for j in Combo9:
        if compare(i[0],j)==False and compare(i[1],j)==False and compare(i[2],j)==False and compare(i[3],j)==False and compare(i[4],j)==False and compare(i[5],j)==False and compare(i[6],j)==False and compare(i[7], j)==False:
            GrandMasterList8.append(i+[j])

for i in range(len(GrandMasterList8)):
    print 'Schedule %d \n' % (i)
    print 'Quarter 1'
    for j in range(len(GrandMasterList8[i][0])):
    print '%s ' % (GrandMasterList8[i][0][j].name)
print '\n Quarter 2'
for j in range(len(GrandMasterList8[i][1])):
    print '%s ' % (GrandMasterList8[i][1][j].name)
print '\n Quarter 3'
    for j in range(len(GrandMasterList8[i][2])):
        print '%s ' % (GrandMasterList8[i][2][j].name)
print '\n Quarter 4'
    for j in range(len(GrandMasterList8[i][3])):
        print '%s ' % (GrandMasterList8[i][3][j].name)
    print '\n Quarter 5'
    for j in range(len(GrandMasterList8[i][4])):
        print '%s ' % (GrandMasterList8[i][4][j].name)
    print '\n Quarter 6'
    for j in range(len(GrandMasterList8[i][5])):
        print '%s ' % (GrandMasterList8[i][5][j].name)
    print '\n Quarter 7'
    for j in range(len(GrandMasterList8[i][6])):
        print '%s ' % (GrandMasterList8[i][6][j].name)
    print '\n Quarter 8'
    for j in range(len(GrandMasterList8[i][7])):
        print '%s ' % (GrandMasterList8[i][7][j].name)
    print '\n Quarter 9'
    for j in range(len(GrandMasterList8[i][8])):
        print '%s ' % (GrandMasterList8[i][8][j].name)
    print '\n \n \n'
4

2 回答 2

0

@Joshua D. Boyd
这不是答案,但由于某种原因,我无法在评论中清楚地格式化 classlist.txt 的示例。
无论如何,这是一个例子:

德语 209-0;S;13-14,14-15,15-16
德语 309-1;F;14-15,15-16,16-17
德语 309-2;W;14-15,15-16 ,16-17
实盘分析 1;F;13-14,14-15,15-16,16-17
实盘分析 2;W;13-14,14-15,15-16,16-17
实盘分析 3; S;13-14,14-15,15-16,16-17
有机化学 1;F;13-14,14-15,15-16,16-17
有机化学 2;W;13-14,14- 15,15-16,16-17
有机化学 3;S;13-14,14-15,15-16,16-17
微分几何;F;13-14,14-15,15-16,16-17
统计 383-0;W;13-14,14-15,15-16,16-17
经济 381-1;W;13-14,14-15,15-16,16-17
数学 325-0;W ;13-14,15-16

等等

当然,整个列表大约有 90 个课程,程序必须对这些课程进行排序以得出每个季度可用的大约 10 到 20 个课程,然后为每个季度提出这些课程的所有可能组合,然后结合每个季度不重叠课程的组合(即,因此我没有得到包含同一课程不止一次的时间表)。

如果这也有帮助,这里是 Quarterlist.txt:
1;F;13-14
2;W;13-14
3;S;13-14
4;F;14-15
5;W;14-15
6;S; 14-15
7;F;15-16
8;W;15-16
9;S;15-16

我希望这比我以前的方法更有帮助。当我在终端中使用 python 编译器运行上述程序时,甚至需要很长时间才能返回中间步骤(我在整个过程中插入了几行打印行以检查其进度,十分钟后我只得到了“组合”)。考虑到初步步骤需要多长时间才能完成,并且理论上每个“GrandMasterList”的计算时间都比上一个要长,至少在我生成它们的方式上,似乎这个程序需要花费不合理的长时间才能完成。

主要是我想提出一个更有效的方法:
比较函数
方法来生成“GrandMasterList”(即组合每个季度的所有类组合,以便每个组合的类没有重叠)

于 2012-12-21T22:50:39.387 回答
0

您发布的示例数据不够长,因此需要很长时间。

您可以通过执行以下操作来分析您的程序:

python2.6 -m cProfile ./your_program.py

它会告诉你每个函数被调用的次数和一堆其他的统计数据。

在您的组合函数中,您采用两个迭代器并将它们转换为列表以返回组合列表。如果您将组合重写为本身是一个迭代器,那可能会给您带来一些收益。

比较可以更简单地写成:

def compare(x, y):
    return not set(x).isdisjoint(set(y))
于 2012-12-23T21:25:58.800 回答