zoukankan      html  css  js  c++  java
  • 使用 JavaScript 编写优化算法 (1)

    之前一直用Python来写优化算法,为了增强 JS 的熟练程度,开始将原有的代码改写成 JS。采用的工具包括 node.js + Grunt + nodeunit + github + npm + travis-ci。

    最初的版本采用过程式的方式实现,没有采用面向对象或事件驱动的模式。

    #!/usr/bin/env node --harmony
    
    // Random Search
    
    "use strict";
    
    var util = require("util");
    
    function objective_function(v) {
        return v.map(function(x) {
            return x*x;
        }).reduce(function(a, b) {
            return a+b;
        });
    }
    
    function random_vector(min_max) {
        return min_max.map(function(x) {
            return x[0] + (x[1] - x[0]) * Math.random();
        });
    }
    
    function search(search_space, max_iteration) {
        var best = {};
        for (var iteration = 0; iteration < max_iteration; iteration++) {
            var candidate = {
                'vector': random_vector(search_space)
            };
            candidate['cost'] = objective_function(candidate['vector']);
            //console.log(candidate);
            if (iteration === 0 || candidate['cost'] < best['cost']) {
                best = candidate;
            }
            console.log(' > iteration=' + (iteration+1) + ', best=' + best['cost']);
        }
        return best;
    }
    
    function generate_array(element, repeat) {
        return new Array(repeat+1).join(1).split('').map(function(){return element;});
    }
    
    function run () {
        var problem_size = 2;
        var search_space = generate_array([-5, 5], problem_size);
        var max_iteration = 100;
        var best = search(search_space, max_iteration);
        console.log("Done. Best Solution: " + util.inspect(best));
    }
    
    exports.objective_function = objective_function;
    exports.random_vector = random_vector;
    exports.generate_array = generate_array;
    exports.search = search;
    exports.run = run;
    

      

    调用方式很简单。

    var rs = require('clever_algorithms_js').random_search;
    
    rs.run();
    

    单元测试:

    var random_search = require('../../lib/stochastic/random_search');
    
    exports['objective'] = function (test) {
        test.equal(random_search.objective_function([1, 2]), 5);
        test.done();
    };
    
    exports['random_vector'] = function (test) {
        var rv = random_search.random_vector([[1, 2], [2, 3]]);
        test.equal(rv.length, 2);
        test.ok(1 <= rv[0] && rv[0] <= 2);
        test.ok(2 <= rv[1] && rv[1] <= 3);
        test.done();
    };
    
    exports['generate_array'] = function (test) {
        var a = random_search.generate_array([-5, 5], 2);
        test.equal(a.length, 2);
        test.deepEqual(a, [[-5,5], [-5,5]]);
        test.done();
    };
    
    exports['search'] = function (test) {
        var problem_size = 2,
            search_space = random_search.generate_array([-5, 5], problem_size),
            max_iter = 100;
        var best = random_search.search(search_space, max_iter);
        test.notEqual(best, {});
        test.ok(-5 <= best['cost'] && best['cost'] <= 5);
        test.done();
    };
    

     如果采用CoffeeScript进行改写的话,代码会更简洁一些:

    # Random Search
    
    util = require("util");
    
    objective_function = (v) ->
      v.reduce (x,y) -> x*x + y*y
    
    random_vector = (min_max) ->
      min_max.map (rx) -> rx[0] + (rx[1] - rx[0]) * Math.random()
    
    generate_array = (element, repeat) ->
      (element for [1..repeat])
    
    search = (search_space, max_iteration) ->
      best = {}
      for iteration in [0..max_iteration-1]
        candidate = {
          'vector': random_vector(search_space)
        }
        candidate['cost'] = objective_function(candidate['vector'])
        best = candidate if iteration == 0 || candidate['cost'] < best['cost']
        console.log ' > iteration=' + (iteration+1) + ' best=' + best['cost'];
      best
    
    run = () ->
      problem_size = 2
      search_space = generate_array([-5, 5], problem_size)
      max_iteration = 100
      best = search(search_space, max_iteration)
      console.log "Done. Best Solution: " + util.inspect(best);
      return
    
    exports.objective_function = objective_function;
    exports.random_vector = random_vector;
    exports.generate_array = generate_array;
    exports.search = search;
    exports.run = run;
    

      

    编译出的JavaScript代码,看起来是这个样子:

    (function() {
      var generate_array, objective_function, random_vector, run, search, util;
    
      util = require("util");
    
      objective_function = function(v) {
        return v.reduce(function(x, y) {
          return x * x + y * y;
        });
      };
    
      random_vector = function(min_max) {
        return min_max.map(function(rx) {
          return rx[0] + (rx[1] - rx[0]) * Math.random();
        });
      };
    
      generate_array = function(element, repeat) {
        var _i, _results;
        _results = [];
        for (_i = 1; 1 <= repeat ? _i <= repeat : _i >= repeat; 1 <= repeat ? _i++ : _i--) {
          _results.push(element);
        }
        return _results;
      };
    
      search = function(search_space, max_iteration) {
        var best, candidate, iteration, _i, _ref;
        best = {};
        for (iteration = _i = 0, _ref = max_iteration - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; iteration = 0 <= _ref ? ++_i : --_i) {
          candidate = {
            'vector': random_vector(search_space)
          };
          candidate['cost'] = objective_function(candidate['vector']);
          if (iteration === 0 || candidate['cost'] < best['cost']) {
            best = candidate;
          }
          console.log(' > iteration=' + (iteration + 1) + ' best=' + best['cost']);
        }
        return best;
      };
    
      run = function() {
        var best, max_iteration, problem_size, search_space;
        problem_size = 2;
        search_space = generate_array([-5, 5], problem_size);
        max_iteration = 100;
        best = search(search_space, max_iteration);
        console.log("Done. Best Solution: " + util.inspect(best));
      };
    
      exports.objective_function = objective_function;
    
      exports.random_vector = random_vector;
    
      exports.generate_array = generate_array;
    
      exports.search = search;
    
      exports.run = run;
    
    }).call(this);
    

      

      

    [1] https://www.npmjs.org/package/clever_algorithms_js

    [2] https://github.com/fox000002/clever_algorithms_js

  • 相关阅读:
    客户(项目)经理应具备那些基本心理素质
    js 添加数组 删除数组
    c# ifram 刷新父页面
    [转].Net ajax检测用户名是否重复
    js 自动执行方法
    js 层 分页显示选择用户名
    c# Cookie的操作
    c# 取IE地址值
    js 弹出层无刷新分页
    iframe 无边框
  • 原文地址:https://www.cnblogs.com/huys03/p/3872256.html
Copyright © 2011-2022 走看看