在 R 中:避免从多行中选择重复项

In R: Avoid duplicates in selection from many rows

总结:我有一个 10 行 4 列的数组,里面填满了数字。我 select 每行一个数字,希望避免 selection.

中出现重复

详述: 我有一个 100*100 单元格的网格。在该网格中有 10 个包含 "person" 的单元格。在迭代过程中,我想让人 "walk around" 在网格中,但我不想出现两个人同时在同一个单元格中。

我有一个描述 10 个人位置的向量。它包含一个人的手机号码。这些位置在所有行和列中计数(即范围从 1:10000)。例如:位置 234 将在第 3 行第 34 列)。

Positions<-sample(1:10000,10)   #Initial positions

我所做的是首先为每个人(上、右、下、左)周围的单元格制作一个数组,为每个人提供 4 个位置:

Surroundings<-array(c(Positions+100,Positions+1,Positions-100,Positions-1),dim=c(10,4))

然后我从 Surroundings 中的每一行随机选择一个方向进入向量 PosNew。这是我要避免重复的最后一个向量。

我可以重复 PosNew 的随机 selection 过程,直到没有重复,但这可能需要很长时间。可能有更有效的方法来做到这一点。

为简单起见,我们假设人员没有离开网格并且没有其他错误发生。

我的脚本:

Positions<-sample(1:10000,10)   #Initial positions

for(i in 1:50) {
 Surroundings<-array(c(Positions+100,Positions+1,Positions-100,Positions-1),dim=c(10,4))
 PosNew<-Surroundings[cbind(1:10,sample(1:4,10,replace=TRUE))] 
 Dups<-length(which(duplicated(PosNew)==TRUE))
 Positions<-PosNew
}

我正在寻找一种方法来检查 selected 新位置中的重复项并确保 Dups 永远不会超过零。欢迎提出任何建议,包括使代码 faster/more 高效的建议。

补充:当一个或多个人真的无法移动到一个空牢房时,我该怎么办,因为所有 4 边都被占用了?我要那个人留在原来的牢房里。如何编码?

非常感谢您的宝贵时间!

由于这是一个迭代过程,每个人的移动都取决于其他人的位置,我认为除了移动一个人并根据集合的差异对下一个人的位置进行采样之外,你能做得更好所有方向和所有占用的位置(请注意,这增加了一点不公平,因为第一个人可以说移动最自由)。

所以代码应该是这样的:

Positions <- sample(1:10000, 10)   #Initial positions

for (i in 1:50) {
  Surroundings <-
    array(c(Positions + 100, Positions + 1, Positions - 100, Positions - 1),
          dim = c(10, 4))

  # BEGIN NEW CODE
  PosNew <- numeric(10)
  for (i in 1:10) {
    # PosNew[seq_len(i-1)] is the set of occupied positions
    available <- setdiff(Surroundings[i, ], PosNew[seq_len(i-1)])
    if (length(available) != 0)
      PosNew[i] <- sample(available, 1)
    else
      PosNew[i] <- Positions[i] # stay where you are
  }
  # END NEW CODE

  Dups <- sum(duplicated(PosNew)) # shorter version - sum logical values to get a count

  Positions <- PosNew
}

希望对您有所帮助!