- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
假设我有以下代码:
arr = [0.1,0.5,0.2,0.2]; //The percentages (or decimals) we want to distribute them over.
value = 100; //The amount of things we have to distribute
arr2 = [0,0,0,0] //Where we want how many of each value to go
要找出如何在数组中平均分配一百个很简单,这是一个例子:
0.1 * 100 = 10
0.5 * 100 = 50
...
或者使用 for 循环:
for (var i = 0; j < arr.length; i++) {
arr2[i] = arr[i] * value;
}
但是,假设每个计数器都是一个对象,因此必须是完整的。我怎样才能平等地(尽可能多地)以不同的值(value)分配它们。假设值变为 12。
0.1 * 12 = 1.2
0.5 * 12 = 6
...
当我需要整数时如何处理小数?四舍五入意味着我可能没有所需的 12 件。
正确的算法会 -
通过值数组进行输入/迭代(对于此示例,我们将使用上面定义的数组。
将它变成一组整数值,加在一起等于值(为此等于 100)
输出一个值数组,在这个例子中它看起来像 [10,50,20,20](这些值加起来是 100,这是我们需要将它们加起来的值并且也是整数) .
如果任何值不完整,它应该使它完整,这样整个数组仍然加起来等于所需的值 (100)。
TL;DR 在数组上分配值并尝试将它们转换为整数时处理小数
注意 - 如果将其发布在不同的 stackoverflow 网站上,我需要的是编程,但实际问题可能会使用数学来解决。另外,我不知道如何表达这个问题,这使得谷歌搜索变得异常困难。如果我错过了一些非常明显的事情,请告诉我。
最佳答案
您应该在分配所有值时使用已知会均匀分布舍入的舍入对所有值进行舍入。最后,最后一个值将被分配不同的值以将总和四舍五入为 1
。
让我们慢慢开始,否则事情会变得非常困惑。首先,让我们看看如何分配最后一个值以获得所需的总值。
// we will need this later on
sum = 0;
// assign all values but the last
for (i = 0; i < output.length - 1; i++)
{
output[i] = input[i] * total;
sum += output[i];
}
// last value must honor the total constraint
output[i] = total - sum;
最后一行需要一些解释。 i
将比 for(..)
循环中最后允许的 int 多一个,因此它将是:
output.length - 1 // last index
我们分配的值将使所有元素的 sum
等于 total
。我们已经在赋值期间一次性计算了总和,因此不需要再次迭代元素来确定总和。
接下来,我们将解决舍入问题。让我们简化上面的代码,以便它使用一个我们将在稍后详细说明的函数:
sum = 0;
for (i = 0; i < output.length - 1; i++)
{
output[i] = u(input[i], total);
sum += output[i];
}
output[i] = total - sum;
如您所见,除了 u()
函数的引入外,没有任何变化。现在让我们专注于此。
u()
的实现有多种方法。
DEFINITION
u(c, total) ::= c * total
根据这个定义,您得到的结果与上面相同。它既精确又好,但正如您之前所问,您希望这些值是自然数(例如整数)。因此,虽然对于实数这已经是完美的,但对于自然数我们必须对其进行四舍五入。假设我们对整数使用简单的舍入规则:
[ 0.0, 0.5 [ => round down
[ 0.5, 1.0 [ => round up
这是通过以下方式实现的:
function u(c, total)
{
return Math.round(c * total);
}
当您不走运时,您可能会向上舍入(或向下舍入)太多值,以至于最后一次值修正不足以满足总约束条件,而且通常,所有值似乎都偏离太多。这是一个众所周知的问题,存在一个在 2D 和 3D 空间中绘制线条的多维解决方案,称为 Bresenham algorithm .
为了让事情变得简单,我将在这里向您展示如何在一维中实现它(这是您的情况)。
让我们首先讨论一个术语:余数。这是你四舍五入后剩下的。它被计算为你想要的和你真正拥有的之间的差异:
DEFINITION
WISH ::= c * total
HAVE ::= Math.round(WISH)
REMAINDER ::= WISH - HAVE
现在想想。剩下的就像你从一张纸上剪下一个形状时丢弃的那张纸。剩下的那张纸还在那里,但你把它扔掉了。取而代之的是,只需将它添加到下一个切口,这样就不会浪费它:
WISH ::= c * total + REMAINDER_FROM_PREVIOUS_STEP
HAVE ::= Math.round(WISH)
REMAINDER ::= WISH - HAVE
这样您就可以保留错误并将其转移到计算中的下一个分区。这称为摊销错误。
这是 u()
的分摊实现:
// amortized is defined outside u because we need to have a side-effect across calls of u
function u(c, total)
{
var real, natural;
real = c * total + amortized;
natural = Math.round(real);
amortized = real - natural;
return natural;
}
根据您的意愿,您可能希望有另一个舍入规则,如 Math.floor()
或 Math.ceil()
。
我建议您使用 Math.floor()
,因为它已被证明对于总约束是正确的。当您使用 Math.round()
时,您将获得更平滑 的摊销,但您可能会面临最后一个值不为正的风险。你可能会得到这样的结果:
[ 1, 0, 0, 1, 1, 0, -1 ]
只有当ALL VALUES 远离 0
时,您才可以确信最后一个值也将为正。因此,对于一般情况,Bresenham 算法 将使用 flooring,从而导致最后一个实现:
function u(c, total)
{
var real, natural;
real = c * total + amortized;
natural = Math.floor(real); // just to be on the safe side
amortized = real - natural;
return natural;
}
sum = 0;
amortized = 0;
for (i = 0; i < output.length - 1; i++)
{
output[i] = u(input[i], total);
sum += output[i];
}
output[i] = total - sum;
显然,input
和 output
数组必须具有相同的大小并且 input
中的值必须是一个分区(总和为 1) .
这种算法在概率和统计计算中很常见。
关于javascript - 我如何在一系列百分比上最佳地分配值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27330331/
我有一个应用程序,它会抛出 GKSession 并在各种条件下(连接超时、 session 失败等)创建一个新的 GKSession。不过,我遇到了内存泄漏问题,并且有时会在重新连接几次循环后崩溃。
比如我在宿主代码中有一个浮点指针 float *p 是否可以确定他指向的内存类型(设备/主机)? 最佳答案 在 UVA system 中, 运行时 API 函数 cudaPointerGetAttri
我已将项目转换为 .Net 4.0 并且以下代码不起作用: typeof(RuntimeTypeHandle).GetMethod("Allocate", BindingFlags.Instance
当我声明 char ch = 'ab' 时,ch 只包含 'b',为什么它不存储 'a'? #include int main() { char ch = 'ab'; printf("%c"
我对 Disk Sector 和 Block 有疑问。扇区是一个单位,通常为 512 字节或 1k、2k、4k 等取决于硬件。文件系统 block 大小是一组扇区大小。 假设我正在存储一个 5KB 的
假设我有 8 个人和5000 个苹果。 我想将所有苹果分发给所有 8 个人,这样我就没有苹果了。 但每个人都应该得到不同数量 将它们全部分发出去的最佳方式是什么? 我是这样开始的: let peopl
我正在构建的网站顶部有一个搜索栏。与 Trello 或 Gmail 类似,我希望当用户按下“/”键时,他们的焦点就会转到该搜索框。 我的 JavaScript 看起来像这样: document.onk
我有一小段代码: if (PZ_APP.dom.isAnyDomElement($textInputs)){ $textInputs.on("focus", function(){
我观察到以下行为。 接受了两个属性变量。 @property (nonatomic, retain) NSString *stringOne; @property (nonatomic, assign
我正在解决这样的问题 - 实现一个计算由以下内容组成的表达式的函数以下操作数:“(”、“)”、“+”、“-”、“*”、“/”。中的每个数字表达式可能很大(与由字符串表示的一样大)1000 位)。 “/
我有一组主机和一组任务。 每个主机都有 cpu、mem 和任务容量,每个任务都有 cpu、mem 要求。 每个主机都属于一个延迟类别,并且可以与具有特定延迟值的其他主机通信。 每个任务可能需要以等于或
该程序的作用:从文件中读取一个包含 nrRows 行和 nrColomns 列的矩阵(二维数组)。矩阵的所有元素都是 [0,100) 之间的整数。程序必须重新排列矩阵内的所有元素,使每个元素等于其所在
世界!我有个问题。今天我尝试创建一个代码,它可以找到加泰罗尼亚语号码。但是在我的程序中可以是长数字。我找到了分子和分母。但我不能分割长数字!此外,只有标准库必须在此程序中使用。请帮帮我。这是我的代码
我确定我遗漏了一些明显的东西,但我想在 Objective C 中创建一个 NSInteger 指针的实例。 -(NSInteger*) getIntegerPointer{ NSInteger
这个问题在这里已经有了答案: Difference between self.ivar and ivar? (4 个答案) 关闭 9 年前。
我如何将 v[i] 分配给一系列整数(v 的类型是 vector )而无需最初填充 最佳答案 你的意思是将 std::vector 初始化为一系列整数? int i[] = {1, 2, 3, 4,
我想寻求分配方面的帮助....我把这个作业带到了学校......我必须编写程序来加载一个 G 矩阵和第二个 G 矩阵,并搜索第二个 G 矩阵以获取存在数第一个 G 矩阵的......但是,当我尝试运行
我必须管理资源。它基本上是一个唯一的编号,用于标识交换机中的第 2 层连接。可以有 16k 个这样的连接,因此每次用户希望配置连接时,他/她都需要分配一个唯一索引。同样,当用户希望删除连接时,资源(号
是否有任何通用的命名约定来区分已分配和未分配的字符串?我正在寻找的是希望类似于 us/s 来自 Making Wrong Code Look Wrong ,但我宁愿使用常见的东西也不愿自己动手。 最佳
我需要读取一个 .txt 文件并将文件中的每个单词分配到一个结构中,该结构从结构 vector 指向。我将在下面更好地解释。 感谢您的帮助。 我的程序只分配文件的第一个字... 我知道问题出在函数 i
我是一名优秀的程序员,十分优秀!