我想计算长度为totalLineLength
的行的子段的长度,其中子段与给定事件的对数成比例。
直观表示:| --- | ----- | --------- |由子分段组成的一行。
我希望计算出的子分段的总和等于totalLineLength
,并且必须打印Success
。也必须使用Log(x+1)
(因为它总是为正面参数提供积极结果,并且也会给出1。)
使用线性缩放,我这样做,并且它可以工作。
var totalLineLength = 20;
var eventTotal;
var calcSubSegment = function(x) {
return totalLineLength * x / eventTotal;
}
var events = [0.1, 1, 22];
eventTotal = events.reduce((a, b) => a + b, 0);
var subSegments = events.map(calcSubSegment);
var segmentLength = subSegments.reduce((a, b) => a + b);
if (segmentLength != totalLineLength) {
console.log("Error:", segmentLength);
} else {
console.log("Success");
}
使用log(x + 1)(更新calcSubSegment),它不起作用。
var totalLineLength = 20;
var eventTotal;
var calcSubSegment = function(x) {
return totalLineLength * Math.log(x+1) / Math.log(eventTotal+1);
}
var events = [0.1, 1, 22];
eventTotal = events.reduce((a, b) => a + b, 0);
var subSegments = events.map(calcSubSegment);
var segmentLength = subSegments.reduce((a, b) => a + b, 0);
if (segmentLength != totalLineLength) {
console.log("Error:", segmentLength);
} else {
console.log("Success");
}
我的代码出了什么问题?我想eventTotal计算,但我不知道如何继续。
我应该如何使用对数缩放?我也想要一个数学解释。
答案 0 :(得分:2)
如果我正确理解您的任务,最简单的解决方案是map
所有events
使用您的log(x+1)
函数,然后使用您已实施的线性拆分。像这样:
function linearSplit(events, totalLineLength) {
var eventTotal;
var calcSubSegment = function(x) {
return totalLineLength * x / eventTotal;
}
eventTotal = events.reduce((a, b) => a + b, 0);
var subSegments = events.map(calcSubSegment);
return subSegments;
}
function logSplit(events, totalLineLength) {
var logEvents = events.map(function(x) { return Math.log(x+1); } );
return linearSplit(logEvents, totalLineLength);
}
function testSplit(events, totalLineLength, fnSplit, splitName) {
var subSegments = fnSplit(events, totalLineLength);
var segmentLength = subSegments.reduce((a, b) => a + b, 0);
console.log(splitName + ":\n" + events + " =>\n" + subSegments);
if (Math.abs(segmentLength - totalLineLength) > 0.001) {
console.log(splitName + " Error:", segmentLength);
} else {
console.log(splitName + " Success");
}
}
var totalLineLength = 20;
var events = [0.1, 1, 22];
testSplit(events, totalLineLength, linearSplit, "linearSplit");
testSplit(events, totalLineLength, logSplit, "logSplit");
这个想法是唯一的分裂
同时是线性分裂。因此,如果要以任何方式缩放系数,则应在传递给线性分割逻辑之前对其进行缩放。否则,部件的总和将不会与代码中的整体(在任何非线性缩放的情况下)相等。
P.S。将浮点值与==
进行比较并不是一个好主意。您应该对计算/舍入误差使用一些容差。