optim.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #! /usr/bin/env python
  2. import os, subprocess, shutil, random, optparse
  3. comp = {
  4. 'bz2': 'cjf',
  5. 'xz' : 'cJf',
  6. 'gz' : 'czf',
  7. }
  8. def read_wafdir():
  9. try:
  10. os.listdir('waflib')
  11. except:
  12. raise ImportError('please provide a waflib directory in the current folder')
  13. d = 'waflib'
  14. lst = [d + os.sep + x for x in os.listdir(d) if x.endswith('.py')]
  15. e = d + os.sep + 'Tools'
  16. lst.extend([e + os.sep + x for x in os.listdir(e) if x.endswith('.py')])
  17. f = d + os.sep + 'extras'
  18. lst.extend([f + os.sep + x for x in os.listdir(f) if x.endswith('.py')])
  19. random.shuffle(lst)
  20. #lst.sort()
  21. return lst
  22. def gen(lst, options):
  23. if options.maxi:
  24. opti_ref = 0
  25. filename = 'max.tar.%s' % options.kind
  26. def compare(a, b):
  27. return a > b
  28. else:
  29. opti_ref = 1000000000
  30. filename = 'min.tar.%s' % options.kind
  31. def compare(a, b):
  32. return a < b
  33. cmd = 'tar %s %s ' % (comp[options.kind], filename)
  34. opti = [opti_ref]
  35. LEN = len(lst)
  36. POP = 3*LEN + 1
  37. popul = [range(LEN) for x in range(POP)]
  38. fitn = [0 for x in range(POP)]
  39. def rnd():
  40. return random.randint(0, LEN -1)
  41. def mutate():
  42. for x in range(LEN):
  43. # rotate the previous element by one
  44. v = popul[x+LEN] = popul[x+LEN - 1]
  45. a = v.pop(0)
  46. v.append(a)
  47. for x in range(LEN):
  48. # swap elements
  49. a = rnd()
  50. b = rnd()
  51. v = popul[x]
  52. c = v[a]
  53. v[a] = v[b]
  54. v[b] = c
  55. for x in range(LEN):
  56. # get one element out, add at the end
  57. v = popul[x+2*LEN]
  58. a = rnd()
  59. c = v[a]
  60. del v[a]
  61. v.append(c)
  62. def evil():
  63. best = opti_ref
  64. pos = -1
  65. for x in range(len(popul)):
  66. v = popul[x]
  67. arr = [lst[a] for a in v]
  68. tmp = '%s %s' % (cmd, ' '.join(arr))
  69. subprocess.Popen(tmp, shell=True).wait()
  70. siz = os.stat(filename).st_size
  71. fitn[x] = siz
  72. if compare(siz, best):
  73. best = siz
  74. pos = x
  75. if compare(siz, opti[0]):
  76. opti[0] = siz
  77. shutil.copy2(filename, 'best_' + filename)
  78. #print popul[x], sum(popul[x]), sum(range(LEN))
  79. assert (sum(popul[x]) == sum(range(LEN)))
  80. #print pos
  81. for x in range(len(popul)):
  82. if x == pos:
  83. continue
  84. popul[x] = popul[pos][:]
  85. assert(len(popul[x]) == LEN)
  86. return best
  87. for i in range(10000):
  88. mutate()
  89. print(evil())
  90. if __name__ == '__main__':
  91. parser = optparse.OptionParser()
  92. parser.add_option('--max', dest='maxi', default=False, action='store_true', help='maximize the file size (default is minimize)')
  93. parser.add_option('--kind', dest='kind', default='bz2', action='store', help='bz2, xz or gz')
  94. (options, args) = parser.parse_args()
  95. lst = read_wafdir()
  96. gen(lst, options)