【问题标题】:What is the best way to find the biggest subset of numbers separated at least by N?找到至少被 N 分隔的最大数字子集的最佳方法是什么?
【发布时间】:2022-09-27 23:16:07
【问题描述】:

我有兴趣获得元素全部间隔的最大大小的组至少它们之间有 N 个单位(N 可能是十进制),我想要一些具有以下输入/输出的东西

1 2 3 4 5, spaced by 2
1 3 5 | 2 4

35 40 45 50 55 60 65 70 75, spaced by 10
35 45 55 65 75 | 40 50 60 70

37.5 39.5 40.5 57.7 62 76.3, spaced by 3.5
37.5 57.7 62 76.3 | 39.5 57.7 62 76.3

我尝试过的是使用以下内容:

split(vector,vector%%spacing)

而且它似乎有效,但我认为 double 的模数是一种非常奇怪的行为,其中引入函数的相同值如果它们来自 data.frame 的第 34 行,则会给出不同的结果,或者如果它们直接传递给函数......我准备了这个 sn-p 以便任何人都可以尝试复制行为:

calculate_solution <- function(parA, parB, parC, parD) {
  varA <- parA/2
  varB <- seq(from=varA+parB,to=parA-parB,by=parB)

  varC <- 1 / parC

  varD <- split(varB,varB%%varC)
  
  print(varD)
}

df_1 <- list(
  a=seq(from=75,to=85,by=5),
  b=seq(from=1,to=2.5,by=0.5),
  c=seq(from=0.05,to=0.4,by=0.05),
  d=seq(from=2,to=2,by=1)) %>%
  expand.grid()

print(c(df_1[34,]$a,df_1[34,]$b,df_1[34,]$c,df_1[34,]$d))

#[1] 75.00  2.50  0.15  2.00

calculate_solution(df_1[34,]$a,df_1[34,]$b,df_1[34,]$c,df_1[34,]$d)

#$`3.5527136788005e-15`
#[1] 40
#
#$`5.32907051820075e-15`
#[1] 60
#
#$`0.833333333333337`
#[1] 47.5
#
#$`0.833333333333339`
#[1] 67.5
#
#$`1.66666666666667`
#[1] 55
#
#$`2.5`
#[1] 42.5
#
#$`2.50000000000001`
#[1] 62.5
#
#$`3.33333333333334`
#[1] 50 70
#
#$`4.16666666666667`
#[1] 57.5
#
#$`5`
#[1] 45
#
#$`5.00000000000001`
#[1] 65
#
#$`5.83333333333334`
#[1] 52.5 72.5
#

df_2 <- data.frame(a=75.0,b=2.5,c=0.15,d=2.0)

calculate_solution(df_2[1,]$a,df_2[1,]$b,df_2[1,]$c,df_2[1,]$d)

#$`0.83333333333333`
#[1] 67.5
#
#$`0.833333333333331`
#[1] 47.5
#
#$`1.66666666666666`
#[1] 55
#
#$`2.5`
#[1] 42.5 62.5
#
#$`3.33333333333333`
#[1] 50 70
#
#$`4.16666666666666`
#[1] 57.5
#
#$`5`
#[1] 45 65
#
#$`5.83333333333333`
#[1] 52.5 72.5
#
#$`6.66666666666666`
#[1] 60
#
#$`6.66666666666667`
#[1] 40

我没有试图找出这种行为背后的原因,而是想也许我可以找到另一种方法来实现我想要的,或者至少可以找到正确的术语来指代我正在尝试做的事情。

  • 假设向量将始终包含区间的所有中间倍数?也就是说,对于c(35, 40, 45, 50, 60, 65),缺少的55 存在差距。
  • 不,它不需要所有中间倍数。我认为它应该独立于序列的类型。
  • 在您的 37.5/3.5 示例中,57.5 如何成为第一个向量的一部分?与 37.5 最接近的 3.5 倍数是 55.0 和 5.85。您期望的容忍度是多少?
  • 我看到您希望返回候选向量列表。为什么总是2?您的第二个和第三个示例都包含更多向量(长度> 1),其中跨度至少为 5 和 10。您为什么要这样做?什么问题表明这是必须做的事情?
  • 我只打算忽略作为另一个结果子集的结果,因为我想要它们中最大的集合。我真的很喜欢你的第二个问题。也许我接近它的方式是错误的。我在这里处理频率。我想知道,给定一组预定义的频率,哪个是最大的集合,而不是你能形成的最大频率跨度?例如,如果最大的集合需要 20 Hz 的跨度,我只需要计算 1/20*Fs 样本的 FFT,就有足够的分辨率来区分它,或者这就是我的想法

标签: r max subset sequence


【解决方案1】:

sapply 中使用 %% 并将其等于 equispace/2 并将零等于子集。

f <- \(x, s) {stopifnot(s > 1); lapply(c((s/2), 0), \(z) x[x %% s == z])}


f(x1, 2)
# [[1]]
# [1] 1 3 5
# 
# [[2]]
# [1] 2 4

f(x2, 10)
# [[1]]
# [1] 35 45 55 65 75
# 
# [[2]]
# [1] 40 50 60 70

【讨论】:

  • 您的解决方案不适用于小数分隔符。我编辑了这个问题,因为最初我并没有要求这样做。现在它甚至不需要等距,但至少间隔 N ......抱歉混淆了
【解决方案2】:

这个函数首先找到第一个向量,其中每个元素至少与前一个元素相距diff。然后它重复这个过程,从第二和后续元素,当将形成子集(在先前的解决方案之一中找到 nth 元素)或没有候选子向量时停止。

func <- function(y, diff = 1, only_longest = TRUE) {
  fun0 <- function(x, diff) {
    if (length(x) < 2) return(x)
    lenx <- length(x)
    x <- sort(x) # just in case
    i <- 1
    leni <- 1L
    while ( (x[lenx] - i[leni]) >= diff ) {
      i1 <- which( x[-seq_len(i[leni])] - x[i[leni]] >= diff )
      if (length(i1)) i <- c(i, i[leni] + i1[1]) else break
      leni <- length(i)
    }
    x[i]
  }
  leny <- length(y)
  len <- 0
  i <- 1L
  out <- list()
  while (!y[i] %in% unlist(out) && length(cand <- fun0(y[seq(i, leny)], diff))) {
    len <- length(cand)
    out[[i]] <- cand
    i <- i + 1L
  }
  lens <- lengths(out)
  if (only_longest) out <- out[lens == max(lens)]
  out
}

示范:

func(1:5, 2)
# [[1]]
# [1] 1 3 5
func(seq(35,75,5), 10)
# [[1]]
# [1] 35 45 55 65 75
func(c(37.5, 39.5, 40.5, 57.7, 62, 76.3), 3.5)
# [[1]]
# [1] 37.5 57.7 62.0 76.3
# [[2]]
# [1] 39.5 57.7 62.0 76.3
# [[3]]
# [1] 40.5 57.7 62.0 76.3

only_longest= 论点曾经是一个想法。假设是,如果任何向量比最长的向量短,那么您可能有兴趣知道它,也可能不感兴趣。只是一个念头,很容易被删除。例如,第二个样本输入:

func(seq(35,75,5), 10, only_longest = FALSE)
# [[1]]
# [1] 35 45 55 65 75
# [[2]]
# [1] 40 50 60 70

【讨论】:

    猜你喜欢
    • 2016-05-31
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    相关资源
    最近更新 更多