PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/MIT_OCW_6dot00/dynamicprogramming_8.py

https://github.com/robtsai/mathrocks
Python | 171 lines | 153 code | 3 blank | 15 comment | 1 complexity | cc15c2835514ac8b08807bcf6a92e7ca MD5 | raw file
  1. # 6.00 Problem Set 8
  2. #
  3. # Intelligent Course Advisor
  4. #
  5. # Name: Rob Tsai
  6. # Collaborators:
  7. # Time:
  8. #
  9. import time
  10. SUBJECT_FILENAME = "subjects.txt"
  11. VALUE, WORK = 0, 1
  12. #
  13. # Problem 1: Building A Subject Dictionary
  14. #
  15. def loadSubjects(filename):
  16. """
  17. Returns a dictionary mapping subject name to (value, work), where the name
  18. is a string and the value and work are integers. The subject information is
  19. read from the file named by the string filename. Each line of the file
  20. contains a string of the form "name,value,work".
  21. returns: dictionary mapping subject name to (value, work)
  22. """
  23. inputFile = open(filename)
  24. subjectMap = {}
  25. for line in inputFile:
  26. tempTuple = line.split(',')
  27. subjectMap[tempTuple[0]] = [int(tempTuple[1]), int(tempTuple[2])]
  28. return subjectMap
  29. subjects = loadSubjects("subjects.txt")
  30. def printSubjects(subjects):
  31. """
  32. Prints a string containing name, value, and work of each subject in
  33. the dictionary of subjects and total value and work of all subjects
  34. """
  35. totalVal, totalWork = 0,0
  36. if len(subjects) == 0:
  37. return 'Empty SubjectList'
  38. res = 'Course\tValue\tWork\n======\t====\t=====\n'
  39. subNames = subjects.keys()
  40. subNames.sort()
  41. for s in subNames:
  42. val = subjects[s][VALUE]
  43. work = subjects[s][WORK]
  44. res = res + s + '\t' + str(val) + '\t' + str(work) + '\n'
  45. totalVal += val
  46. totalWork += work
  47. res = res + '\nTotal Value:\t' + str(totalVal) +'\n'
  48. res = res + 'Total Work:\t' + str(totalWork) + '\n'
  49. print res
  50. # Problem 4: Subject Selection By Dynamic Programming
  51. def createLists():
  52. counter = 0
  53. counterList = []
  54. subList = []
  55. valueList = []
  56. workList = []
  57. outputDict = {}
  58. for i in subjects.keys():
  59. counterList.append(counter)
  60. subList.append(i)
  61. valueList.append(subjects[i][VALUE])
  62. workList.append(subjects[i][WORK])
  63. counter += 1
  64. return counterList, subList, valueList, workList
  65. def zeroMatrix(rows, cols):
  66. data = []
  67. rowVector = []
  68. for i in range(cols):
  69. rowVector.append(0)
  70. for j in range(rows):
  71. data.append(rowVector[:])
  72. return data
  73. def knapsack(v, w, mW):
  74. # v is list of values, m is list of weights, mW is maximum weight in knapsack
  75. c = [] #cost matrix
  76. k = [] #keep matrix
  77. n = len(v)
  78. c = zeroMatrix(n, mW+1)
  79. k = zeroMatrix(n, mW+1)
  80. for i in range(0,n): #for every item in list
  81. for j in range(mW+1): #for every weight in maxweight
  82. if (w[i] > j): #if weight of item is bigger than maxweight
  83. if i == 0:
  84. c[i][j] = 0
  85. else:
  86. c[i][j] = c[i-1][j] #don't take, and entry in cost matrix is same as one above
  87. else:
  88. if i == 0:
  89. c[i][j] = v[i] #for first item, you will always take if you can
  90. k[i][j] = 1 #mark keep matrix
  91. else:
  92. 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
  93. if c[i][j] > c[i-1][j]:
  94. k[i][j] = 1
  95. return [c, k, n, mW+1] #return cost matrix, keep matrix, numrows, numcols
  96. def findSolution(c, k, numrows, numcols, v, w): #takes cost matrix and keep matrix
  97. maxVal = c[numrows-1][numcols-1] #lower right hand entry in cost matrix
  98. keepVector = []
  99. for i in range(numrows):
  100. keepVector.append(0)
  101. #start at lower right of keep matrix
  102. rowSearch = numrows-1
  103. colSearch = numcols-1
  104. keepGoing = True
  105. while keepGoing:
  106. if k[rowSearch][colSearch] == 0: # this means you don't take it
  107. rowSearch -= 1
  108. elif k[rowSearch][colSearch] == 1: # this means you take it
  109. keepVector[rowSearch] = 1
  110. print "Putting item in row ", rowSearch, " of value (v,w)", v[rowSearch], w[rowSearch], " in knapsack size ", colSearch
  111. colSearch -= w[rowSearch]
  112. rowSearch -= 1
  113. print "New subproblem to evaluate is item in row ", rowSearch, " and knapsack size ", colSearch
  114. if rowSearch < 0:
  115. keepGoing = False
  116. print "Maximum value is ", maxVal
  117. print "The solution vector is ", keepVector
  118. return maxVal, keepVector
  119. def dpAdvisor(subjects, maxWork):
  120. """
  121. Returns a dictionary mapping subject name to (value, work) that contains a
  122. set of subjects that provides the maximum value without exceeding maxWork.
  123. subjects: dictionary mapping subject name to (value, work)
  124. maxWork: int >= 0
  125. returns: dictionary mapping subject name to (value, work)
  126. """
  127. # TODO...
  128. counterList, subList, valueList, workList = createLists()
  129. print "Value list ", valueList
  130. print "Work list ", workList
  131. print "Max work ", maxWork
  132. c, k, numrows, numcols = knapsack(valueList, workList, maxWork)
  133. print "cost matrix"
  134. print "item(v,w)---------max weight--------"
  135. print " ", range(maxWork+1)
  136. for i in range(len(c)):
  137. print valueList[i], workList[i], c[i]
  138. print "keep matrix"
  139. print "item(v,w)---------max weight--------"
  140. print " ", range(maxWork+1)
  141. for i in range(len(k)):
  142. print valueList[i], workList[i], k[i]
  143. maxVal, keepVector = findSolution(c, k, numrows, numcols, valueList, workList)
  144. subjectsSubset = {}
  145. counter = len(keepVector)
  146. for i in range(counter):
  147. if keepVector[i] == 1: #this means take this class
  148. subjectsSubset[subList[i]] = (valueList[i], workList[i])
  149. counter += 1
  150. printSubjects(subjectsSubset)
  151. return subjectsSubset
  152. #test
  153. dpAdvisor(subjects, 30)