- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
考虑一个排序的 vector x
介于 min
之间和 max
.以下是此类 x
的示例在哪里 min
可能是 0
和 max
可能是 12
:
x = c(0.012, 1, exp(1), exp(1)+1e-55, exp(1)+1e-10,
exp(1)+1e-3, 3.3, 3.33333, 3.333333333333333, 3+1/3, 5, 5, 10, 12)
5
和 5
以及 exp(1)
和 exp(1)+10^(-55)
具有完全相同的值(达到 float 的准确度)。其他一些条目差异很大,而另一些条目差异很小。我想考虑一个近似相等测试
ApproxEqual = function(a,b) abs(a-b) < epsilon
,其中 epsilon
可能是 1e-5
例如。
目标
我想修改变量 x
的值“尽可能少”以确保 x
中没有两个值是“近似相等”和x
仍然在 min
之间和 max
.
我很高兴让您决定“尽可能少”的真正含义。例如,可以最小化原始 x
之间的平方偏差总和。以及预期的变量输出。
示例 1
x_input = c(5, 5.1, 5.1, 5.1, 5.2)
min=1
max=100
x_output = c(5, 5.1-epsilon, 5.1, 5.1+epsilon, 5.2)
示例 2
x_input = c(2,2,2,3,3)
min=2
max=3
x_output = c(2, 2+epsilon, 2+2*epsilon, 2+3*epsilon, 3-epsilon,3)
当然,在上述情况下,如果 (3-epsilon) - (2+3*epsilon) < epsilon
是 TRUE
,那么函数应该抛出错误,因为问题没有解决方案。
旁注
如果解决方案非常高效,我会很高兴。答案可以使用Rcpp
例如。
最佳答案
我怀疑在不迭代的情况下这是可能的,因为将一些点从太近的邻居中移开可能会导致移动的点聚集在更靠近其他邻居的地方。这是一种解决方案,它仅更改获得解决方案所需的那些值,并将它们移动尽可能小的距离,以确保 epsilon 的最小间隙。
它使用一个函数来为每个点分配一个力,这取决于我们是否需要将它从太近的邻居移开。力的方向(符号)表明我们是否需要增加或减少该点的值。夹在其他太近的邻居之间的点不会移动,但它们的外部邻居都会远离中心点(这种行为是尽可能少地移动点)。分配给端点的力始终为零,因为我们不希望 x 的整体范围发生变化
force <- function(x, epsilon){
c(0, sapply(2:(length(x)-1), function(i){ (x[i] < (x[i-1]+epsilon)) - (x[i] > (x[i+1]-epsilon)) }), 0)
}
接下来,我们需要一个函数来移动点,这取决于作用在它们上的力。积极的力量使他们移动到比前一点更高的epsilon。负面的力量使它们向下移动。
move <- function(x, epsilon, f){
x[which(f==-1)] <- x[which(f==-1)+1] - epsilon
x[which(f==1)] <- x[which(f==1)-1] + epsilon
# Next line deals with boundary condition, and prevents points from bunching up at the edges of the range
# I doubt this is necessary, but included out of abundance of caution. Could try deleting this line if performance is an issue.
x <- sapply(1:(length(x)), function(i){x[i] <- max(x[i], head(x,1)+(i-1)*epsilon); x[i] <- min(x[i], tail(x,1)-(length(x)-i)*epsilon)})
x
}
最后,函数separate
用于迭代计算力和移动点,直到找到解决方案。它还在迭代之前检查几个边缘情况。
separate <- function(x,epsilon) {
if (epsilon > (range(x)[2] - range(x)[1]) / (length(x) - 1)) stop("no solution possible")
if (!(all(diff(x)>=0))) stop ("vector must be sorted, ascending")
initial.x <- x
solved <- FALSE
##################################
# A couple of edge cases to catch
##################################
# 1. catch cases when vector length < 3 (nothing to do, as there are no points to move)
if (length(x)<3) solved <- TRUE
# 2. catch cases where initial vector has values too close to the boundaries
x <- sapply(1:(length(x)), function(i){
x[i] <- max(x[i], head(x,1)+(i-1)*epsilon)
x[i] <- min(x[i], tail(x,1)-(length(x)-i)*epsilon)
})
# Now iterate to find solution
it <- 0
while (!solved) {
it <- it+1
f <- force(x, epsilon)
if (sum(abs(f)) == 0) solved <- TRUE
else x <- move(x, epsilon, f)
}
list(xhat=x, iterations=it, SSR=sum(abs(x-initial.x)^2))
}
在 OP 提供的示例上对此进行测试:
x = c(0.012, 1, exp(1), exp(1)+1e-55, exp(1)+1e-10, exp(1)+1e-3, 3.3, 3.33333, 3.333333333333333, 3+1/3, 5, 5, 10, 12)
epsilon <- 1e-5
separate(x, epsilon)
# $xhat
# [1] 0.012000 1.000000 2.718272 2.718282 2.718292 2.719282 3.300000 3.333323 3.333333 3.333343
# [11] 4.999990 5.000000 10.000000 12.000000
#
# $iterations
# [1] 2
#
# $SSR
# [1] 4.444424e-10
编辑 1
在 separate
函数中添加了行以响应注释以捕获一些极端情况 -
A) 传递给函数的 vector 长度 < 3
separate(c(0,1), 1e-5)
# $xhat
# [1] 0 1
#
# $iterations
# [1] 0
#
# $SSR
# [1] 0
B) 传递的 vector 在边界处有多个值
separate(c(0,0,0,1), 1e-5)
# [1] "it = 1, SSR = 5e-10"
# $xhat
# [1] 0e+00 1e-05 2e-05 1e+00
#
# $iterations
# [1] 1
#
# $SSR
# [1] 5e-10
关于c++ - 编辑数组以确保严格增加值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37534412/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!