maths.ts
Version:
Math utilities library for TypeScript, JavaScript and Node.js
1,676 lines (1,534 loc) • 447 kB
JavaScript
var maths =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const metaheuristics = __webpack_require__(1);
exports.metaheuristics = metaheuristics;
const structures = __webpack_require__(10);
exports.structures = structures;
const arithmetic = __webpack_require__(16);
exports.arithmetic = arithmetic;
const discrete = __webpack_require__(32);
exports.discrete = discrete;
const graph = __webpack_require__(34);
exports.graph = graph;
__export(__webpack_require__(42));
__export(__webpack_require__(46));
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(__webpack_require__(2));
__export(__webpack_require__(8));
__export(__webpack_require__(9));
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const _debug = __webpack_require__(3);
const integers_1 = __webpack_require__(7);
const debug = _debug('mh::sa');
/**
* Simulated annealing metaheuristic seeks for a global optimal solution for
* a given problem. This algorithm is inspired by the steel annealing process.
* @param problem The problem which must have a solution generator, a
* calculator for the solution and a neighbor generator for each solution.
* @param nNeighbors The number of neighbors for the solution generated each
* cycle.
* @param kDiffer The percentage change of each neighbor from the solution.
* @param t0 The initial temperature where to start the algorithm. Default 100.
* @param tf The final temperature where to end the algorithm. Default 0.
* @param tDecrease Sets the temperature decrease. Default nextT = T - 0.1.
* @param sRepetitions The maximum number of repetitions for a given
* solution before temperature drops down.
* @returns The solution found by this algorithm.
*/
function simulatedAnnealing(problem, nNeighbors = 1, kDiffer = 2, t0 = 100, tf = 0, tDecrease = decrease, sRepetitions = 5) {
// Generates an initial solution
let solution = problem.generateSolution();
// Calculates the 'energy' of the initial solution
let sEnergy = problem.solutionValue(solution);
let k = 0;
for (let t = t0; t > tf;) {
// Generates nNeighbor candidates solutions from the neighborhood of
// s, then picks one.
const cSolution = problem
.generateNeighbors(solution, kDiffer, nNeighbors)[integers_1.randInt(0, nNeighbors)];
// Calculates 'energy' of candidate solution
const csEnergy = problem.solutionValue(cSolution);
// Calculates the difference between 'energies'
const AE = sEnergy - csEnergy;
// Informative, only when debugging
debug('Temperature = ' + t, 'e^(AE/t) = ' + Math.exp(AE / t));
debug('curS: ' + solution, 'canS: ' + cSolution);
debug('curS value: ' + sEnergy, 'canS value: ' + csEnergy);
if (AE < 0) {
// If candidate solution is a better solution update
solution = cSolution;
sEnergy = csEnergy;
debug('Update, better solution!');
}
else if (Math.random() >= Math.exp(AE / t)) {
// If candidate solution is not a better solution but the
// temperature is high enough then update
solution = cSolution;
sEnergy = csEnergy;
debug('Update, high enough temperature!');
t = tDecrease(t);
}
else if (k++ === sRepetitions) {
k = 0;
t = tDecrease(t);
}
}
return solution;
}
exports.simulatedAnnealing = simulatedAnnealing;
function decrease(t) {
return t - .1;
}
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(process) {/**
* This is the web browser implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = __webpack_require__(5);
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = 'undefined' != typeof chrome
&& 'undefined' != typeof chrome.storage
? chrome.storage.local
: localstorage();
/**
* Colors.
*/
exports.colors = [
'#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC',
'#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF',
'#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC',
'#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF',
'#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC',
'#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033',
'#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366',
'#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933',
'#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC',
'#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF',
'#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'
];
/**
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
* and the Firebug extension (any Firefox version) are known
* to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
return true;
}
// Internet Explorer and Edge do not support colors.
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
return false;
}
// is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
exports.formatters.j = function(v) {
try {
return JSON.stringify(v);
} catch (err) {
return '[UnexpectedJSONParseError]: ' + err.message;
}
};
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs(args) {
var useColors = this.useColors;
args[0] = (useColors ? '%c' : '')
+ this.namespace
+ (useColors ? ' %c' : ' ')
+ args[0]
+ (useColors ? '%c ' : ' ')
+ '+' + exports.humanize(this.diff);
if (!useColors) return;
var c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit')
// the final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
var index = 0;
var lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, function(match) {
if ('%%' === match) return;
index++;
if ('%c' === match) {
// we only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
}
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log() {
// this hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return 'object' === typeof console
&& console.log
&& Function.prototype.apply.call(console.log, console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (null == namespaces) {
exports.storage.removeItem('debug');
} else {
exports.storage.debug = namespaces;
}
} catch(e) {}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
var r;
try {
r = exports.storage.debug;
} catch(e) {}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
return r;
}
/**
* Enable namespaces listed in `localStorage.debug` initially.
*/
exports.enable(load());
/**
* Localstorage attempts to return the localstorage.
*
* This is necessary because safari throws
* when a user disables cookies/localstorage
* and you attempt to access it.
*
* @return {LocalStorage}
* @api private
*/
function localstorage() {
try {
return window.localStorage;
} catch (e) {}
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4)))
/***/ }),
/* 4 */
/***/ (function(module, exports) {
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = __webpack_require__(6);
/**
* Active `debug` instances.
*/
exports.instances = [];
/**
* The currently active debug mode names, and names to skip.
*/
exports.names = [];
exports.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/
exports.formatters = {};
/**
* Select a color.
* @param {String} namespace
* @return {Number}
* @api private
*/
function selectColor(namespace) {
var hash = 0, i;
for (i in namespace) {
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return exports.colors[Math.abs(hash) % exports.colors.length];
}
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
var prevTime;
function debug() {
// disabled?
if (!debug.enabled) return;
var self = debug;
// set `diff` timestamp
var curr = +new Date();
var ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
// turn the `arguments` into a proper Array
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
args[0] = exports.coerce(args[0]);
if ('string' !== typeof args[0]) {
// anything else let's inspect with %O
args.unshift('%O');
}
// apply any `formatters` transformations
var index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
// if we encounter an escaped % then don't increase the array index
if (match === '%%') return match;
index++;
var formatter = exports.formatters[format];
if ('function' === typeof formatter) {
var val = args[index];
match = formatter.call(self, val);
// now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
});
// apply env-specific formatting (colors, etc.)
exports.formatArgs.call(self, args);
var logFn = debug.log || exports.log || console.log.bind(console);
logFn.apply(self, args);
}
debug.namespace = namespace;
debug.enabled = exports.enabled(namespace);
debug.useColors = exports.useColors();
debug.color = selectColor(namespace);
debug.destroy = destroy;
// env-specific initialization logic for debug instances
if ('function' === typeof exports.init) {
exports.init(debug);
}
exports.instances.push(debug);
return debug;
}
function destroy () {
var index = exports.instances.indexOf(this);
if (index !== -1) {
exports.instances.splice(index, 1);
return true;
} else {
return false;
}
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
exports.save(namespaces);
exports.names = [];
exports.skips = [];
var i;
var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
var len = split.length;
for (i = 0; i < len; i++) {
if (!split[i]) continue; // ignore empty strings
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
exports.names.push(new RegExp('^' + namespaces + '$'));
}
}
for (i = 0; i < exports.instances.length; i++) {
var instance = exports.instances[i];
instance.enabled = exports.enabled(instance.namespace);
}
}
/**
* Disable debug output.
*
* @api public
*/
function disable() {
exports.enable('');
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
if (name[name.length - 1] === '*') {
return true;
}
var i, len;
for (i = 0, len = exports.skips.length; i < len; i++) {
if (exports.skips[i].test(name)) {
return false;
}
}
for (i = 0, len = exports.names.length; i < len; i++) {
if (exports.names[i].test(name)) {
return true;
}
}
return false;
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) return val.stack || val.message;
return val;
}
/***/ }),
/* 6 */
/***/ (function(module, exports) {
/**
* Helpers.
*/
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var y = d * 365.25;
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @param {String|Number} val
* @param {Object} [options]
* @throws {Error} throw an error if val is not a non-empty string or a number
* @return {String|Number}
* @api public
*/
module.exports = function(val, options) {
options = options || {};
var type = typeof val;
if (type === 'string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isNaN(val) === false) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error(
'val is not a non-empty string or a valid number. val=' +
JSON.stringify(val)
);
};
/**
* Parse the given `str` and return milliseconds.
*
* @param {String} str
* @return {Number}
* @api private
*/
function parse(str) {
str = String(str);
if (str.length > 100) {
return;
}
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
str
);
if (!match) {
return;
}
var n = parseFloat(match[1]);
var type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n;
default:
return undefined;
}
}
/**
* Short format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtShort(ms) {
if (ms >= d) {
return Math.round(ms / d) + 'd';
}
if (ms >= h) {
return Math.round(ms / h) + 'h';
}
if (ms >= m) {
return Math.round(ms / m) + 'm';
}
if (ms >= s) {
return Math.round(ms / s) + 's';
}
return ms + 'ms';
}
/**
* Long format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtLong(ms) {
return plural(ms, d, 'day') ||
plural(ms, h, 'hour') ||
plural(ms, m, 'minute') ||
plural(ms, s, 'second') ||
ms + ' ms';
}
/**
* Pluralization helper.
*/
function plural(ms, n, name) {
if (ms < n) {
return;
}
if (ms < n * 1.5) {
return Math.floor(ms / n) + ' ' + name;
}
return Math.ceil(ms / n) + ' ' + name + 's';
}
/***/ }),
/* 7 */
/***/ (function(module, exports) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Generates a random integer in the range [lb, up).
* @param lb The lower bound.
* @param ub The upper bound.
* @returns A random integer between lb and ub.
*/
function randInt(lb, ub) {
return Math.floor(Math.random() * (ub - lb)) + lb;
}
exports.randInt = randInt;
/**
* Calculates the factorial of a given number.
* @param n The number from which to calculate factorial.
* @returns n!
*/
function factorial(n) {
let a = 1;
for (let i = 2; i <= n; i++) {
a *= i;
}
return a;
}
exports.factorial = factorial;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const _debug = __webpack_require__(3);
const integers_1 = __webpack_require__(7);
const debug = _debug('mh::hs');
/**
*
* @param problem The problem which must have a solution generator, a
* calculator for the solution and a neighbor generator for each solution.
* @param hms Harmonic memory size.
* @param hmcr Harmonic memory consideration rate represents the probability
* to use the harmonic memory to generate a solution.
* @param kDiffer Percentage of change of each neighbor from the solution.
* @param maxIt
* @returns The solution found by this algorithm.
*/
function harmonicSearch(problem, hms = 30, hmcr = 0.7, kDiffer = 2, maxIt = 500) {
// Generates an initial harmonic memory
const hMemory = [];
for (let i = 0; i < hms; i++) {
hMemory.push(problem.generateSolution());
}
for (let i = 0; i < maxIt; i++) {
let is;
if (hmcr > Math.random()) {
is = problem.generateNeighbors(hMemory[integers_1.randInt(0, hMemory.length)], kDiffer)[0];
}
else {
is = problem.generateSolution();
}
const w = findWorst();
if (problem.solutionValue(is) >= problem.solutionValue(hMemory[w])) {
hMemory[w] = is;
}
}
return hMemory[findBest()];
/**
* Finds the best note in the harmonic memory.
* @returns The index of the best solution at memory.
*/
function findBest() {
let k = -1;
let kValue = -Infinity;
for (let i = 0; i < hMemory.length; i++) {
const iValue = problem.solutionValue(hMemory[i]);
if (kValue < iValue) {
k = i;
kValue = iValue;
}
}
return k;
}
/**
* Finds the worst note in the harmonic memory.
* @returns The index of the worst solution at memory.
*/
function findWorst() {
let k = -1;
let kValue = Infinity;
for (let i = 0; i < hMemory.length; i++) {
const iValue = problem.solutionValue(hMemory[i]);
if (kValue > iValue) {
k = i;
kValue = iValue;
}
}
return k;
}
}
exports.harmonicSearch = harmonicSearch;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const _debug = __webpack_require__(3);
const debug = _debug('mh::ts');
/**
*
* @param problem The problem which must have a solution generator, a
* calculator for the solution and a neighbor generator for each solution.
* @param nNeighbors The number of neighbors for the solution generated each
* cycle.
* @param kDiffer The percentage change of each neighbor from the solution.
* @param tlSize The taboo list size.
* @param iterations The number of iterations executing the algorithm.
* @returns The solution found by this algorithm.
*/
function tabooSearch(problem, nNeighbors = 5, kDiffer = 2, tlSize = 30, iterations = 100) {
// Generates an initial solution
const sol = problem.generateSolution();
const tabooList = [];
let bestS = sol;
debug('Initial sol: ' + bestS);
let bestVal = problem.solutionValue(bestS);
for (let i = 0; i < iterations; i++) {
const neighbors = problem.generateNeighbors(sol, kDiffer, nNeighbors);
const candidates = [];
neighbors.forEach(n => {
debug('%s=%d', '' + n, problem.solutionValue(n));
if (!isIn(n, tabooList)) {
candidates.push(n);
}
});
let bestC = candidates[0];
let bestCVal = 0;
candidates.forEach(c => {
const cVal = problem.solutionValue(c);
if (cVal > bestCVal) {
bestCVal = cVal;
bestC = c;
}
});
debug('Picked: %s=%d', '' + bestC, bestCVal);
if (bestCVal > bestVal) {
debug('Solution updated to ' + bestC);
bestS = bestC;
bestVal = bestCVal;
tabooList.unshift(bestC);
if (tabooList.length >= tlSize) {
tabooList.pop();
}
}
}
debug(tabooList);
return bestS;
function isIn(e, array) {
for (let i = 0; i < array.length; i++) {
if (problem.compareSolutions(array[i], e)) {
return true;
}
}
return false;
}
}
exports.tabooSearch = tabooSearch;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const Graph_1 = __webpack_require__(11);
exports.Graph = Graph_1.default;
const Vertex_1 = __webpack_require__(13);
exports.Vertex = Vertex_1.default;
const Edge_1 = __webpack_require__(12);
exports.Edge = Edge_1.default;
const Matrix_1 = __webpack_require__(14);
exports.Matrix = Matrix_1.default;
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const Edge_1 = __webpack_require__(12);
const Vertex_1 = __webpack_require__(13);
/**
* Represents a graph as an adjacency list. It provides methods for
* adding/removing vertex and edges.
*/
class Graph {
/**
* Builds a graph with or without vertex.
* TODO: neighbor and graph function generators.
* @param nVertexes The initial number of vertexes for this.
* @param directed Indicates if the graph is going to be a directed
* graph or not.
*/
constructor(nVertexes, directed = false) {
this.directed = directed;
// TODO: There may be a better way to built a graph, I think.
this._vertexes = [];
this.directed = directed;
for (let i = 0; i < nVertexes; i++) {
this.addVertex();
}
}
/**
* Gets the vertex in this graph.
* @return The vertexes of this graph.
*/
get vertexes() {
return this._vertexes;
}
/**
* Gets all edges from Graph.
* @return The edges of this graph.
*/
get edges() {
const es = [];
this.vertexes.forEach((v) => v.edges.forEach((e) => es.push(e)));
return es;
}
/**
* Adds a vertex to this graph.
* @param name The name for the new vertex.
* @param info Additional name about the vertex.
*/
addVertex(name, info) {
this.vertexes.push(new Vertex_1.default(this.vertexes.length, name, info));
}
/**
* Builds an edge, then adds it to the source vertex.
* @param from
* @param to
* @param weight
* @param info
*/
addEdge(from, to, weight, info) {
this.vertexes[from].addEdge(new Edge_1.default(this.vertexes[from], this.vertexes[to], weight, info));
if (!this.directed) {
this.vertexes[to].addEdge(new Edge_1.default(this.vertexes[to], this.vertexes[from], weight, info));
}
}
/**
* Returns the value gotten from evaluating a given heuristic with given
* source and destination.
* @param s The source.
* @param d The destination.
* @return {number} The distance between them according to the heuristic
* defined on this graph.
*/
heuristicValue(s, d) {
if (this._heuristic) {
return this._heuristic(this.vertexes[s], this.vertexes[d]);
}
return 0;
}
/**
* Sets a heuristic for this graph.
* @param h The new heuristic.
*/
setHeuristic(h) {
this._heuristic = h;
}
/**
* Prints this graph vertex and adjacency list.
*/
toString() {
if (this._vertexes.length <= 0) {
return 'Empty graph';
}
return 'Graph:\n\t' + this.vertexes.join('\n\t');
}
}
exports.default = Graph;
/***/ }),
/* 12 */
/***/ (function(module, exports) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Represents an edge of a graph. It must provides a source, a destination
* and optionally a weight and name.
*/
class Edge {
/**
* Builds this with respective source, destination, weight(optional) and
* name(optional).
* @param _source The source of this.
* @param _destination The destination of this.
* @param weight The weight for this. It may be the result of a function
* or just a number.
* @param info Additional name for this.
*/
constructor(_source, _destination, weight, info) {
this._source = _source;
this._destination = _destination;
this.info = info;
if (typeof weight === 'number') {
this.weight = weight;
}
else {
this.setWeightFunction(weight);
}
this.info = info;
}
/**
* Returns the weight of this edge. If weight is given by a function it
* executes such function. If there is no weight defined it returns 1.
* If the weight is given by a number it just returns the number.
* @return The weight associated to this edge.
*/
get weight() {
if (this.weightFunction) {
return this.weightFunction(this.source, this.destination);
}
else if (this._weight === undefined) {
return 1;
}
else {
return this._weight;
}
}
/**
* Sets a weight for this.
* @param w The number to be the weight for this vertex.
*/
set weight(w) {
this._weight = w;
}
/**
* Gets the origin point of this.
* @return The source of this.
*/
get source() {
return this._source;
}
/**
* Sets the origin point for this.
* @param value The vertex wanted to be the source of this edge.
*/
set source(value) {
this._source = value;
}
/**
* Gets the destination for this.
* @return The destination of this.
*/
get destination() {
return this._destination;
}
/**
* Sets the destination for this.
* @param value The new destination for this.
*/
set destination(value) {
this._destination = value;
}
/**
* Sets a weight function for this vertex.
* @param f A function receiving the two vertex adjacent to this to
* calculate weight for this.
*/
setWeightFunction(f) {
this.weightFunction = f;
}
/**
* Removes the weight function.
*/
removeWeightFunction() {
this.weightFunction = undefined;
}
/**
* Returns this as an coordinate: (source, destiny, weight).
* @return The representation of this.
*/
toString() {
return '(' + this.source.name + ', ' + this.destination.name +
(this.weight !== undefined ? ', ' + this.weight : '') + ')';
}
}
exports.default = Edge;
/***/ }),
/* 13 */
/***/ (function(module, exports) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Represents a vertex of a graph. It must provide an id and a neighborhood,
* that is, a list of adjacent vertexes. Vertexes may be built manually or
* with the Graph class for its internal handling.
*/
class Vertex {
/**
* Builds a vertex with an optional name and optional extra information
* for it.
* @param id The id of this vertex on graph. Must be handled internally
* by the Graph which this vertex belongs to.
* @param _name The name this is going to get when printing.
* @param info
*/
constructor(id, _name, info) {
this.id = id;
this._name = _name;
this.info = info;
this.info = info;
this._edges = [];
}
/**
* Returns the list of edges adjacent to this.
* @return The edges of this vertex.
*/
get edges() {
return this._edges;
}
/**
* The name for this vertex, if there is.
* @return The name of this vertex.
*/
get name() {
if (this._name) {
return this._name;
}
return this.id + '';
}
/**
* Sets a name for this graph.
* @param value The new name for this.
*/
set name(value) {
this._name = value;
}
/**
* Adds an edge to this vertex neighborhood.
* @param e The new edge from this.
*/
addEdge(e) {
for (let i = 0; i < this._edges.length; i++) {
if (this.edges[i].source.equals(e.source) &&
this.edges[i].destination === e.destination) {
if (this.edges[i].weight && e.weight &&
this.edges[i].weight > e.weight) {
this.edges[i] = e;
return;
}
}
}
this.edges.push(e);
}
/**
* Returns the neighborhood of this vertex, that is, the vertexes
* connected to this with an edge.
* @return A list of the vertexes connected to this vertex through an edge.
*/
getNeighborHood() {
return this.edges.map((e) => e.destination);
}
/**
* Checks if another vertex is equivalent to this.
* @param v The other vertex.
* @return true if this equals v, false otherwise.
*/
equals(v) {
return v._edges === this._edges && this._name === v._name;
}
/**
* Gets useful information about this vertex.
* @return The name of this and the edges associated to this vertex.
*/
toString() {
return this.name + (this.edges.length ? ': ' : '') +
this.edges.join(', ');
}
}
exports.default = Vertex;
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @author Hector J. Vasquez <ipi.vasquez@gmail.com>
*
* @licence
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const Node_1 = __webpack_require__(15);
const $ = __webpack_require__(31);
/**
* An implementation of a Matrix in mathematics. This matrix may be a matrix
* of any kind of mathematical expression: number, expression...
*/
class Matrix {
/**
* Builds a matrix from the dimensions of the matrix or its representation
* as an Array or as a Matrix object.
* @param m May be a the representation of the matrix as an Array or as
* a Matrix; or, it may be the number of rows for this Matrix.
* @param n The number of columns of the matrix in case of the first
* argument (m) is a number.
*/
constructor(m = 1, n = 1) {
if (typeof m === 'number') {
this.mxnConstructor(m, n);
}
else {
this.matrixConstructor(m);
}
}
/**
* Gets the number of rows in this matrix.
* @return The number of rows in matrix.
*/
get M() {
return this.matrix.length;
}
/**
* Get the number of columns in this matrix.
* @return The number of columns in this matrix.
*/
get N() {
return this.matrix[0].length;
}
/**
* Creates a copy of the matrix this object represents as an array.
* @return A two dimensional array of which this Matrix is representing.
*/
get nodeMatrix() {
return this.matrix.map(row => row.map(Node_1.default.newNode));
}
/**
* Creates a copy of the matrix this object represents as a two
* dimensional array of numbers. If this Matrix contains elements that
* cannot be converted as numbers (such as expression with variables) it
* will return an undefined in the element th