翻译 CleverAlgorithms 代码之 stochastic
最近开始看 Clever Algorithms: Nature-Inspired Programming Recipes,学习各种算法及其代码。作者使用Ruby来编写算法代码。这里为了加深理解和增强 Python 编码技能,建立了将代码翻译成 Python 的小项目,包含算法和测试代码。github 地址:https://github.com/fox000002/PyCleverAlgorithms。
翻译的第一部分是随机搜索算法,以直接随机搜索为例。
原始Ruby代码:
# Random Search in the Ruby Programming Language # The Clever Algorithms Project: http://www.CleverAlgorithms.com # (c) Copyright 2010 Jason Brownlee. Some Rights Reserved. # This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 Australia License. def objective_function(vector) return vector.inject(0) {|sum, x| sum + (x ** 2.0)} end def random_vector(minmax) return Array.new(minmax.size) do |i| minmax[i][0] + ((minmax[i][1] - minmax[i][0]) * rand()) end end def search(search_space, max_iter) best = nil max_iter.times do |iter| candidate = {} candidate[:vector] = random_vector(search_space) candidate[:cost] = objective_function(candidate[:vector]) best = candidate if best.nil? or candidate[:cost] < best[:cost] puts " > iteration=#{(iter+1)}, best=#{best[:cost]}" end return best end if __FILE__ == $0 # problem configuration problem_size = 2 search_space = Array.new(problem_size) {|i| [-5, +5]} # algorithm configuration max_iter = 100 # execute the algorithm best = search(search_space, max_iter) puts "Done. Best Solution: c=#{best[:cost]}, v=#{best[:vector].inspect}" end
翻译后Python代码:
#!/usr/bin/env python def objective_function(v): return sum(map(lambda x : x**2, v)) def random_vector(minmax): import random return map(lambda x : x[0] + (x[1]-x[0]) * random.random(), minmax) def search(search_space, max_iter): best = None for iter in range(0, max_iter): candidate = {} candidate['vector'] = random_vector(search_space) candidate['cost'] = objective_function(candidate['vector']) if best is None or candidate['cost'] < best['cost']: best = candidate print ' > iteration=%d, best=%f' % (iter+1, best['cost']) return best def main(): # problem_size = 2 search_space = [[-5,5]] * problem_size # max_iter = 100 # best = search(search_space, max_iter) print 'Done. Best Solution: c=%f, v=%s' % (best['cost'], str(best['vector'])) if __name__ == "__main__": main()
Python 代码采用lambda语法,利用map来操作list很方便,翻译起来还比较顺畅。
单元测试代码:
#!/usr/bin/env python import unittest import os os.sys.path.append("..") from random_search import objective_function, random_vector, search class TestRandomSearch(unittest.TestCase): def setUp(self): self.data = [1,2] def test_objective_function(self): self.assertEqual(objective_function(self.data), 5) def test_random_vector(self): minmax = [ [1,2], [2,3] ] self.assertEqual(minmax[0][0], 1) rv = random_vector(minmax) self.assertEqual(len(rv), 2) self.assertTrue(rv[0] >= minmax[0][0] and rv[0] <= minmax[0][1]) self.assertTrue(rv[1] >= minmax[1][0] and rv[1] <= minmax[1][1]) def test_search(self): problem_size = 2 search_space = [[-5,5]] * problem_size # max_iter = 100 # best = search(search_space, max_iter) # self.assertIsNotNone(best) self.assertTrue(best['cost'] >= -5 and best['cost'] <= 5) if __name__ == '__main__': unittest.main()