- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
作为一个更大的模拟程序的一部分(我很乐意分享其背景,但与问题无关),我遇到了以下问题,正在寻找一个好的算法。
问题:给定一个长度为 n 的 float 组 f(包含元素 f_1, ..., f_n),指定 n 维空间中的一个点。可以公平地假设 f 的总和为 0.0(取决于浮点精度)。
寻求:求长度为n的整数数组i(有元素i_1, ..., i_n),在n维空间指定一个格点,使得i和d(f,i)之和正好为0,合适的测度f 和 i 之间的距离最小化。
至于合适的度量,我认为最好的方法是最小化相对误差(即对 (i_j/f_j-1)^2 的 j 求和),但最小化普通欧几里德距离(即求和(i_j-f_j)^2) 中的 j 以上也可能有效。
我很容易想到的最好的算法是在第 i 个网格(和为 0)上猜测一个合适的点,然后重复切换到具有最小距离的相邻网格点(和为 0),直到所有邻居都有一个更大的距离。给定距离函数的凹性,这应该收敛于解。
但该算法似乎很笨拙。谁能做得更好?
How to round floats to integers while preserving their sum? 有相关讨论但它没有达到我正在寻找的最优点。
上下文附录:如果您对此感兴趣(也因为我觉得它很酷),让我具体说明问题出现的背景。
该问题作为交易模拟的一部分出现(这是更大模拟的一部分)。在每个地点,代理商提供交易多种商品的服务。由于每个地点和商品都是单独处理的,我们可以专注于一个地点和商品并对其进行顺序处理。
每个代理人 j 都有一定数量的货币 c_j 和一定数量的商品 q_j,它们是并且必须保持完整。每个代理人还指定一个实值的、连续的、非负的、非单调递减的需求函数 d_j(p),它实质上表示代理人在任何给定价格下想要拥有多少单位的商品。
交易按以下步骤执行。
最佳答案
这很简单。定义要使用以下算法计算的 ik。 ik 的总和将始终为 0,欧氏距离将始终最小。
if (f[k] < 0)
i[k] = int(f[k]-0.5);
else
i[k] = int(f[k]+0.5);
int() 是一个返回 float 的整数部分的函数。它会截断 float 。
让我们定义 ek 使得 fk = ik + ek。
对于 n = 2,f0 = -f1。两个fk大小相同但符号相反。通过向 0 舍入,这两个误差也具有相同的大小但符号相反。因为 sum(f) = sum(i) + sum(e) 并且 sum(e) 和 sum(f) 等于 0,所以 sum(i) = 0。
除了平衡两个误差的大小外,通过四舍五入到最接近的整数,我们将误差最小化。 sum(e2) 将是最小的。
我们像上面那样计算 ik。然后 sum(i) 可能取值 -1、0 或 1。
当 sum(i) = -1 时,我们必须增加 ik 之一。选择具有最大 ek 的 ik(所有 ek 都是正值)。
当 sum(i) = 1 时,我们必须减少 ik 之一。选择ek最小的ik(所有ek都是负数)。
当 n=3 时,我们有 3 个错误值 |ek| < 0.5。结果 |sum(e)|永远不能是 2 或更多。由于sum(i)只能取整数值,sum(e)只能取值-1、0或1,sum(i)也是如此。
|总和(e)| = 1 当所有 ek 具有相同的符号时。这是因为 |ek| < 0.5。您总是需要三个相同符号的错误才能达到 1 或 -1。请注意,与符号不同且 sum(i) = 0 的情况相比,这种情况在统计上较少出现。
我们如何决定选择哪个 ik?
当 sum(i) = 1 时,sum(e) = -1 并且所有 ek 都为负。我们必须减一 ik。减少一个 ik 将通过增加其 ek 来平衡,因为 sum(i) + sum(e) = 0。因此我们应该选择 ek 以便增加它,产生最小幅度的错误。这是最接近 -0.5 的 ek,因此也是最小的 ek。这确保了 sum(e2) 最小。
当 sum(i) = -1 时,同样的逻辑适用。在这种情况下,sum(e) = 1 并且所有 ek 都是正数。增加一个 ik 通过减少它的 ek 来平衡。通过选择最接近 0.5 的 ek,我们得到最小的总和 (e2)。
在这种情况下,sum(i) 仍然限于值 -1、0 和 1。
当sum(i) = -1时,取最大的ek。
当sum(i) = 1时,取最小的ek。
|总和(e)|无法达到 2。这就是为什么 sum(i) 被限制为值 -1、0 和 1 的原因。
与 n = 3 的不同之处在于,现在我们可能有 3 或 4 个具有相同符号的 ek。但是通过应用上述规则,sum(e2) 保持最小值。
当 n > 4 |sum(e)|可以大于 1。在这种情况下,我们必须修改多个 ik。
一般算法如下
sum(i) -> m
when m = 0,
we are done.
when m < 0,
increment the m i<sub>k</sub> with biggest e<sub>k</sub>.
when m > 0,
decrement the m i<sub>k</sub> with smallest e<sub>k</sub>.
这是 python 2.7 代码
def solve(pf):
n = len(pf)
# construct array pi from pf
pi = [round(val) for val in pf]
print "pi~:", pi
# compute the sum of the integers
m = sum(val for val in pi)
print "m :", m
# if the sum is zero, we are done
if m == 0:
return pi
# compute the errors
pe = [pf[k]-pi[k] for k in xrange(n)]
print "pe :", pe
# correct pi when m is negative
while m < 0:
# locate the pi with biggest error
biggest = 0
for k in xrange(1,n):
if pe[k] > pe[biggest]:
biggest = k
# adjust this integer i
pi[biggest] += 1
pe[biggest] -= 1
m += 1
# correct pi when m is positive
while m > 0:
# locate the pi with smallest error
smallest = 0
for k in xrange(1,n):
if pe[k] < pe[smallest]:
smallest = k
# adjust this integer i
pi[smallest] -= 1
pe[smallest] += 1
m -= 1
return pi
if __name__ == '__main__':
print "Example case when m is 0"
pf = [1.1, 2.2, -3.3]
print "pf :", pf
pi = solve( pf )
print "pi :", pi
print "Example case when m is 1"
pf = [0.6, 0.7, -1.3]
print "pf :", pf
pi = solve( pf )
print "pi :", pi
print "Example case when m is -1"
pf = [0.4, 1.4, -1.8]
print "pf :", pf
pi = solve( pf )
print "pi :", pi
关于algorithm - 将浮点向量舍入到整数向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28782463/
我想用一个向量执行以下操作。 a = np.array(np.arange(0, 4, 1)) 我想得到一个乘法,结果是一个矩阵 | 0 1 2 3 4 -| - - - - - - - 0
正如标题所述,我正在尝试使用 gsub,其中我使用向量作为“模式”和“替换”。目前,我的代码如下所示: names(x1) names(x1) [1] "2110023264A.Ms.Amp
所以当我需要做一些线性代数时,我更容易将向量视为列向量。因此,我更喜欢 (n,1) 这样的形状。 形状 (n,) 和 (n,1) 之间是否存在显着的内存使用差异? 什么是首选方式? 以及如何将 (n,
我不明白为什么 seq() 可以根据元素中是否存在小数点输出不同的类,而 c() 总是创建一个 num向量,无论是否存在小数。 例如: seqDec <- seq(1, 2, 0.5) # num v
机器学习与传统编程的一个重要区别在于机器学习比传统编程涉及了更多的数学知识。不过,随着机器学习的飞速发展,各种框架应运而生,在数据分析等应用中使用机器学习时,使用现成的库和框架成为常态,似乎越来越不需
寻找有关如何将 RegEnable 用作向量的示例/建议。此外,我想控制输入和使能信号成为 Vector 中寄存器索引的函数。 首先,我如何声明 RegEnable() 的 Vector,其次如何迭代
假设我有一个包含变量名称的向量 v1,我想为每个变量分配一个值(存储在单独的向量中)。我如何在没有迭代的情况下做到这一点? v1 <- c("a","b","c") v2 <- c(1,2,3) 我想
R 提供了三种类型来存储同质对象列表:向量、矩阵 和数组。 据我所知: 向量是一维数组的特殊情况 矩阵是二维数组的特例 数组还可以具有任意维度级别(包括 1 和 2)。 在向量上使用一维数组和在矩阵上
我正在绕着numpy/scipy中的所有选项转圈。点积、乘法、matmul、tensordot、einsum 等 我想将一维向量与二维矩阵(这将是稀疏csr)相乘并对结果求和,这样我就有了一个一维向量
我是一个 IDL 用户,正在慢慢切换到 numpy/scipy,并且有一个操作我在 IDL 中非常经常做,但无法用 numpy 重现: IDL> a = [2., 4] IDL> b = [3., 5
在python计算机图形工具包中,有一个vec3类型用于表示三分量向量,但是我如何进行以下乘法: 三分量向量乘以其转置结果得到 3*3 矩阵,如下例所示: a = vec3(1,1,1) matrix
我正在构建一款小型太空射击游戏。当涉及到空间物理学时,我曾经遇到过数学问题。 用文字描述如下:有一个最大速度。因此,如果您全速行驶,您的飞船将在屏幕上一遍又一遍地移动,就像在旧的小行星游戏中一样。如果
我正在尝试在 python 中实现 Vector3 类。如果我用 c++ 或 c# 编写 Vector3 类,我会将 X、Y 和 Z 成员存储为 float ,但在 python 中,我读到鸭式是要走
我是 Spark 和 Scala 的新手,我正在尝试阅读有关 MLlib 的文档。 http://spark.apache.org/docs/1.4.0/mllib-data-types.html上的
我有一个包含四个逻辑向量的数据框, v1 , v2 , v3 , v4 是对还是错。我需要根据 boolean 向量的组合对数据帧的每一行进行分类(例如, "None" , "v1 only" , "
我正在创建一个可视化来说明主成分分析的工作原理,方法是绘制一些实际数据的特征值(为了说明的目的,我将子集化为二维)。 我想要来自 this fantastic PCA tutorial 的这两个图的组
我有以下排序向量: > v [1] -1 0 1 2 4 5 2 3 4 5 7 8 5 6 7 8 10 11 如何在不遍历整个向量的情况下删除 -1、0 和 11
有什么方法可以让 R 对向量和其他序列数据结构使用基于零的索引,例如在 C 和 python 中。 我们有一些代码在 C 中进行一些数值处理,我们正在考虑将其移植到 R 中以利用其先进的统计功能,但是
我有一个函数可以查询我的数据库中最近的 X 个条目,它返回一个 map 向量,如下所示: [{:itemID "item1" :category "stuff" :price 5} {:itemI
我有 ([[AA ww me bl qw 100] [AA ee rr aa aa 100] [AA qq rr aa aa 90]] [[CC ww me bl qw 100] [CC ee rr
我是一名优秀的程序员,十分优秀!