/MIT_OCW_6dot00/dynamicprogramming_8.py
Python | 171 lines | 153 code | 3 blank | 15 comment | 1 complexity | cc15c2835514ac8b08807bcf6a92e7ca MD5 | raw file
- # 6.00 Problem Set 8
- #
- # Intelligent Course Advisor
- #
- # Name: Rob Tsai
- # Collaborators:
- # Time:
- #
- import time
- SUBJECT_FILENAME = "subjects.txt"
- VALUE, WORK = 0, 1
- #
- # Problem 1: Building A Subject Dictionary
- #
- def loadSubjects(filename):
- """
- Returns a dictionary mapping subject name to (value, work), where the name
- is a string and the value and work are integers. The subject information is
- read from the file named by the string filename. Each line of the file
- contains a string of the form "name,value,work".
- returns: dictionary mapping subject name to (value, work)
- """
- inputFile = open(filename)
- subjectMap = {}
- for line in inputFile:
- tempTuple = line.split(',')
- subjectMap[tempTuple[0]] = [int(tempTuple[1]), int(tempTuple[2])]
- return subjectMap
- subjects = loadSubjects("subjects.txt")
- def printSubjects(subjects):
- """
- Prints a string containing name, value, and work of each subject in
- the dictionary of subjects and total value and work of all subjects
- """
- totalVal, totalWork = 0,0
- if len(subjects) == 0:
- return 'Empty SubjectList'
- res = 'Course\tValue\tWork\n======\t====\t=====\n'
- subNames = subjects.keys()
- subNames.sort()
- for s in subNames:
- val = subjects[s][VALUE]
- work = subjects[s][WORK]
- res = res + s + '\t' + str(val) + '\t' + str(work) + '\n'
- totalVal += val
- totalWork += work
- res = res + '\nTotal Value:\t' + str(totalVal) +'\n'
- res = res + 'Total Work:\t' + str(totalWork) + '\n'
- print res
- # Problem 4: Subject Selection By Dynamic Programming
- def createLists():
- counter = 0
- counterList = []
- subList = []
- valueList = []
- workList = []
- outputDict = {}
- for i in subjects.keys():
- counterList.append(counter)
- subList.append(i)
- valueList.append(subjects[i][VALUE])
- workList.append(subjects[i][WORK])
- counter += 1
- return counterList, subList, valueList, workList
- def zeroMatrix(rows, cols):
- data = []
- rowVector = []
- for i in range(cols):
- rowVector.append(0)
- for j in range(rows):
- data.append(rowVector[:])
- return data
- def knapsack(v, w, mW):
- # v is list of values, m is list of weights, mW is maximum weight in knapsack
- c = [] #cost matrix
- k = [] #keep matrix
- n = len(v)
- c = zeroMatrix(n, mW+1)
- k = zeroMatrix(n, mW+1)
- for i in range(0,n): #for every item in list
- for j in range(mW+1): #for every weight in maxweight
- if (w[i] > j): #if weight of item is bigger than maxweight
- if i == 0:
- c[i][j] = 0
- else:
- c[i][j] = c[i-1][j] #don't take, and entry in cost matrix is same as one above
- else:
- if i == 0:
- c[i][j] = v[i] #for first item, you will always take if you can
- k[i][j] = 1 #mark keep matrix
- else:
- c[i][j] = max(c[i-1][j], v[i] + c[i-1][j-w[i]]) #else you compare entry above, with taking it and value of subprob
- if c[i][j] > c[i-1][j]:
- k[i][j] = 1
- return [c, k, n, mW+1] #return cost matrix, keep matrix, numrows, numcols
- def findSolution(c, k, numrows, numcols, v, w): #takes cost matrix and keep matrix
- maxVal = c[numrows-1][numcols-1] #lower right hand entry in cost matrix
- keepVector = []
- for i in range(numrows):
- keepVector.append(0)
- #start at lower right of keep matrix
- rowSearch = numrows-1
- colSearch = numcols-1
- keepGoing = True
- while keepGoing:
- if k[rowSearch][colSearch] == 0: # this means you don't take it
- rowSearch -= 1
- elif k[rowSearch][colSearch] == 1: # this means you take it
- keepVector[rowSearch] = 1
- print "Putting item in row ", rowSearch, " of value (v,w)", v[rowSearch], w[rowSearch], " in knapsack size ", colSearch
- colSearch -= w[rowSearch]
- rowSearch -= 1
- print "New subproblem to evaluate is item in row ", rowSearch, " and knapsack size ", colSearch
- if rowSearch < 0:
- keepGoing = False
- print "Maximum value is ", maxVal
- print "The solution vector is ", keepVector
- return maxVal, keepVector
- def dpAdvisor(subjects, maxWork):
- """
- Returns a dictionary mapping subject name to (value, work) that contains a
- set of subjects that provides the maximum value without exceeding maxWork.
- subjects: dictionary mapping subject name to (value, work)
- maxWork: int >= 0
- returns: dictionary mapping subject name to (value, work)
- """
- # TODO...
- counterList, subList, valueList, workList = createLists()
- print "Value list ", valueList
- print "Work list ", workList
- print "Max work ", maxWork
- c, k, numrows, numcols = knapsack(valueList, workList, maxWork)
- print "cost matrix"
- print "item(v,w)---------max weight--------"
- print " ", range(maxWork+1)
- for i in range(len(c)):
- print valueList[i], workList[i], c[i]
- print "keep matrix"
- print "item(v,w)---------max weight--------"
- print " ", range(maxWork+1)
- for i in range(len(k)):
- print valueList[i], workList[i], k[i]
- maxVal, keepVector = findSolution(c, k, numrows, numcols, valueList, workList)
- subjectsSubset = {}
- counter = len(keepVector)
- for i in range(counter):
- if keepVector[i] == 1: #this means take this class
- subjectsSubset[subList[i]] = (valueList[i], workList[i])
- counter += 1
- printSubjects(subjectsSubset)
- return subjectsSubset
- #test
- dpAdvisor(subjects, 30)