Advertisement
Guest User

Untitled

a guest
Oct 11th, 2013
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.25 KB | None | 0 0
  1. import pprint
  2.  
  3. def solve(words, heuristic, num_sections):
  4.     avg = sum(words)/float(len(words))
  5.    
  6.     #first compute number of words in any subslice
  7.     num_words = [[0 for j in xrange(len(words)+1)] for i in xrange(len(words)+1)]
  8.     for section_length in xrange(1, len(words)+1):
  9.         #try all ranges from 0 to num words - 1
  10.         for i in xrange(len(words) - section_length + 1):
  11.             j = i + section_length
  12.             num_words[i][j] = num_words[i][j-1] + words[j-1]
  13.  
  14.     #results is a 3D array[n][i][j] where n is number of sections,
  15.     #i is the start section index, j is the end section index,
  16.     #containing (the minimal badness, partition) or None if impossible
  17.     #or "notprocced" if it wasn't relevant
  18.     results = [[["notprocced" for j in xrange(len(words)+1)] for i in xrange(len(words)+1)]
  19.                for n in xrange(num_sections+1)]
  20.  
  21.     #completely solve for spliiting into 1 section, then 2, etc... up to num_sections
  22.     for n in xrange(1, num_sections+1):
  23.         #try all section leigths from 1 to the num words
  24.         for section_length in xrange(1, len(words)+1):
  25.             #try all ranges from 0 to num words - 1
  26.             for i in xrange(len(words) - section_length + 1):
  27.                 j = i + section_length
  28.                 if n > section_length:
  29.                     #infinitely bad, we have too many sections
  30.                     results[n][i][j] = (None, 0, None)
  31.                     continue
  32.                
  33.                 #what is the solution? if we have 1 section, that's the base case
  34.                 if n == 1:
  35.                     words_in_sub = num_words[i][j]
  36.                     results[1][i][j] = (heuristic(words_in_sub, avg), 0, None)
  37.                 else:
  38.                     #otherwise try all partitions & pick the best
  39.                     bestbad = None
  40.                     bestsplits = None
  41.                     bestpartition = None
  42.                     for splits_on_left in xrange(1, n):
  43.                         for partition in xrange(i+1, j):
  44.                             bad1 = results[splits_on_left][i][partition]
  45.                             bad2 = results[n - splits_on_left][partition][j]
  46.                             if bad1 == "notprocced" or bad2 == "notprocced":
  47.                                 raise ValueError("not procced subproblem")
  48.                             if bad1[0] is None or bad2[0] is None:
  49.                                 #impossible
  50.                                 continue
  51.                             if bestbad is None or bad1[0] + bad2[0] < bestbad:
  52.                                 bestpartition = partition
  53.                                 bestsplits = splits_on_left
  54.                                 bestbad = bad1[0] + bad2[0]
  55.                     results[n][i][j] = (bestbad, bestsplits, bestpartition)
  56.  
  57.     verbose = False
  58.     if verbose:
  59.         for n in xrange(len(results)):
  60.             print "For splitting into %d sections:" % (n,)
  61.             for i in xrange(len(results[n])):
  62.                 for j in xrange(len(results[n][i])):
  63.                     if results[n][i][j] == "notprocced":
  64.                         continue
  65.                     print "From %d to %d, badness=%s" % (i, j, results[n][i][j])
  66.             print "====="
  67.         print num_sections, 0, len(words), results[num_sections][0][len(words)]
  68.  
  69.     #trace out the results
  70.     splits = []
  71.     def trace_result_of(n, i, j):
  72.         badness, leftsplits, partition = results[n][i][j]
  73.         #print n, i, j, "=", badness, leftsplits, partition
  74.         if n == 1:
  75.             splits.append(words[i:j])
  76.             return
  77.        
  78.         trace_result_of(leftsplits, i, partition)
  79.         trace_result_of(n-leftsplits, partition, j)
  80.     trace_result_of(num_sections, 0, len(words))
  81.  
  82.     return splits
  83.  
  84. section_words = [100, 100, 100, 100, 100, 100, 40000, 100, 100, 100, 100]
  85.  
  86. def heuristic(num_words, avg):
  87.     return abs(num_words - avg)**3
  88.  
  89. def print_solution(solution):
  90.     num_words = sum(map(sum, solution))
  91.     print "Total=%d, %d readings, avg=%.2f" % (num_words, len(solution), num_words/float(len(solution)))
  92.     for i, breaks in enumerate(solution):
  93.         print "Reading #%d (%5d words): %s" % (i+1, sum(breaks), breaks)
  94.  
  95. print_solution(solve(section_words, heuristic, 5))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement