以下似乎是做到邊緣化的工作。它創建一個具有成員和值的行的表。表格中的每一行必須具有相同數量的成員。
它還沒有實現乘法(真正的工作必須在某個時候完成......)。請注意,在ECMAScript中,0.1 + 0.2 = 0.30000000000000004
因此您需要實施某種舍入來修復並保持準確性。
/**
* A table has rows, all rows within a table have the same number of members
* Each row as 1 to n members plus a value
* e.g. a = 0, b = 0, c = 0, value = 0.1
* a = 0, b = 0, c = 1, value = 0.2
* a = 1, b = 0, c = 0, value = 0.1
* a = 1, b = 1, c = 0, value = 0.1
* a = 1, b = 1, c = 1, value = 0.1
*
* Marginalisation addition takes the values of matching values and sums them,
*
* e.g.
* marginalisation of {a, b} where a=0 and b=0:
* matching rows are 0 and 1, so add 0.1 + 0.2 => 0.3
*
* marginalisation of {a, b} where a=1 and b=1:
* matching rows are 3 and 4, so add 0.1 + 0.1 => 0.2
*
* @param {number} numberOfValues - number of values in each row. So for 3 members
* plus value then numberOfValues is 4
*/
function BayTable (numberOfValues) {
// Array containing rows of values
this.rows = [];
// Number of values in a row, so for [a, b, c, value] memberCount is 4
this.memberCount = numberOfValues;
}
/**
* @param {number} memberValue[, memberValue, ...], rowValue
*
* e.g. addRow(0, 0, 0, 0.1)
*/
BayTable.prototype.addRow = function() {
if (arguments.length != this.memberCount) return; // or throw error
var row = [];
for (var i=0, iLen=arguments.length; i<iLen; i++) {
row.push(arguments[i]);
}
this.rows.push(row);
}
/**
* marginalise finds matching rows and adds their values,
* so marginalise(0,0) finds rows where a=0 and b=0 ignoring
* any other member in the row and
* sums the value for the rows
*/
BayTable.prototype.marginalise = function() {
// Guard agains too many arguments
if (arguments.length > this.memberCount - 2) return; // or throw error
var total = 0;
var row, match;
// For each row
for (var i=0, iLen=this.rows.length; i<iLen; i++) {
row = this.rows[i];
match = true
// Check values against arguments until a missmatch
for (var j=0, jLen=arguments.length; j<jLen && match; j++) {
match = row[j] === arguments[j];
}
// If no missmatch, add row value
if (match) total += row[row.length - 1];
}
return total;
}
var x = new BayTable(4);
x.addRow(0, 0, 0, 0.1);
x.addRow(0, 0, 1, 0.2);
x.addRow(1, 0, 0, 0.1);
x.addRow(1, 1, 0, 0.1);
x.addRow(1, 1, 1, 0.1);
console.log(x.marginalise(0, 0)); // 0.30000000000000004
console.log(x.marginalise(1, 0)); // 0.1
console.log(x.marginalise(1, 1)); // 0.2
這裏的對象版本,它使用一對夫婦的ES5方法:
/**
* A table has rows, all rows within a table have the same number of members
* Each row as 1 to n members plus a value
* e.g. a = 0, b = 0, c = 0, value = 0.1
* a = 0, b = 0, c = 1, value = 0.2
* a = 1, b = 0, c = 0, value = 0.1
* a = 1, b = 1, c = 0, value = 0.1
* a = 1, b = 1, c = 1, value = 0.1
*
* Marginalisation addition takes the values of matching values and sums them,
*
* e.g.
* marginalisation of {a, b} where a=0 and b=0:
* matching rows are 0 and 1, so add 0.1 + 0.2 => 0.3
*
* marginalisation of {a, b} where a=1 and b=1:
* matching rows are 3 and 4, so add 0.1 + 0.1 => 0.2
*
* @param {number} numberOfValues - number of values in each row. So for 3 members plus value
* then numberOfValues is 4
*/
function BayTable (numberOfValues) {
// Array containing rows of values
this.rows = [];
// Number of values in a row, so for [a, b, c, value] memberCount is 4
this.memberCount = numberOfValues;
}
/**
* @param {Object} row - {label:value[, label:value, ...], 'value':value}
*
* e.g. addRow({a:0, b:0, c:0, value:0.1})
*/
BayTable.prototype.addRow = function(row) {
this.rows.push(row);
}
/**
* marginalise finds matching rows and adds their values,
* so marginalise({a:0, b:0}) finds rows where a=0 and b=0 ignoring
* any other member in the row and sums the values of matched rows
*/
BayTable.prototype.marginalise = function(obj) {
var keys = Object.keys(obj);
// For each row
return this.rows.reduce(function(total, row) {
// If all key/values match, accumlate value
if (keys.every(function(key){return obj[key] === row[key]}))
total += row.value;
return total;
}, 0);
/*
// Less obscure version, same number of lines of code
var total = 0;
var keys = Object.keys(obj);
// For each row
this.rows.forEach(function(row) {
// If key/values match, add row value to total
if (keys.every(function(key){return obj[key] === row[key]}))
total += row.value;
});
return total;
*/
}
var x = new BayTable(4);
x.addRow({a:0, b:0, c:0, value:0.1});
x.addRow({a:0, b:0, c:1, value:0.2});
x.addRow({a:1, b:0, c:0, value:0.1});
x.addRow({a:1, b:1, c:0, value:0.1});
x.addRow({a:1, b:1, c:1, value:0.1});
console.log(x.marginalise({a:0, b:0})); // 0.30000000000000004
console.log(x.marginalise({a:1, b:0})); // 0.1
console.log(x.marginalise({a:1, b:1})); // 0.2
console.log(x.marginalise({a:1, c:1})); // 0.1
console.log(x.marginalise({b:0, c:0})); // 0.2
這會不會是困難的,如果你能解釋一下計算的工作究竟如何,他們不是在直觀快速看。 – Nit
「*因此,我修改了代碼... *」。什麼代碼?這純粹是一種映射練習,還是有計算邊緣化的算法? – RobG
我剛剛修改了描述@Nit,以增加有關乘法和邊緣化操作的更多細節。謝謝。 – jhonatanoliveira