Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 在每个位置比较2个阵列_Ruby - Fatal编程技术网

Ruby 在每个位置比较2个阵列

Ruby 在每个位置比较2个阵列,ruby,Ruby,因此,我试图完成的是编写一个(较短的)条件,以确保每个元素与其他数组不同。这是令人困惑的,但我希望这个例子能澄清这一点 array = [1, 2, 3] new_array = array.shuffle until array[0] != new_array[0] && array[1] != new_array[1] && array[2] != new_array[2] new_array = array.shuffle end

因此,我试图完成的是编写一个(较短的)条件,以确保每个元素与其他数组不同。这是令人困惑的,但我希望这个例子能澄清这一点

array = [1, 2, 3]
new_array = array.shuffle

until array[0] != new_array[0] &&
    array[1] != new_array[1] &&
    array[2] != new_array[2]

    new_array = array.shuffle
end
所以我要做的是确保每个元素/索引对在另一个数组中不匹配

# [1, 2, 3] => [3, 1, 2]   yayyyy
# [1, 2, 3] => [3, 2, 1] not what I want because the 2 didnt move

有没有更好的方法来做我想做的事?我查过了,有吗?没有?但我似乎不知道如何实施它们。谢谢

这里有一种可能性:

until array.zip(new_array).reject{ |x, y| x == y }.size == array.size
  new_array = array.shuffle
end

但是请注意,对于
[1]
[1,1,1,2,3]
之类的数组,当
1
的实例数超过数组大小的一半时,它将中断。建议使用
Array#uniq
或类似方法,同时检查大小为
0
1
的数组,具体取决于您的输入的可信度

这里有一种可能性:

until array.zip(new_array).reject{ |x, y| x == y }.size == array.size
  new_array = array.shuffle
end
但是请注意,对于
[1]
[1,1,1,2,3]
之类的数组,当
1
的实例数超过数组大小的一半时,它将中断。建议使用
Array#uniq
或类似方法,同时检查大小为
0
1
的数组,具体取决于您的输入的可信度

我会这样做:

array.zip(new_array).all? { |left, right| left != right }
我会这样做:

array.zip(new_array).all? { |left, right| left != right }

以下两种方法在获得有效样本之前不涉及重复采样:

来自有效排列总体的样本

构建要从中采样的总体:

array = [1, 2, 3, 4]

population = array.permutation(array.size).reject do |a|
  a.zip(array).any? { |e,f| e==f }
end
  #=> [[2, 1, 4, 3], [2, 3, 4, 1], [2, 4, 1, 3], [3, 1, 4, 2], [3, 4, 1, 2],
  #    [3, 4, 2, 1], [4, 1, 2, 3], [4, 3, 1, 2], [4, 3, 2, 1]] 
然后随便选一个:

10.times { p population.sample }
  # [4, 3, 1, 2]
  # [3, 4, 1, 2]
  # [3, 4, 1, 2]
  # [4, 3, 1, 2]
  # [2, 1, 4, 3]
  # [2, 1, 4, 3]
  # [4, 1, 2, 3]
  # [2, 1, 4, 3]
  # [4, 3, 1, 2]
  # [3, 4, 1, 2]
阵列中每个位置的顺序采样

def sample_no_match(array)
  a = array.each_index.to_a.shuffle
  last_ndx = a[-1]

  a.dup.map do |i|
    if a.size == 2 && a[-1] == last_ndx
      select = a[-1]
    else
      select = (a-[i]).sample
    end
    a.delete(select)
    array[select]
  end
end          

10.times.each { p sample_no_match(array) }
  # [2, 4, 3, 1]
  # [4, 3, 1, 2]
  # [2, 1, 3, 4]
  # [1, 3, 4, 2]
  # [1, 3, 2, 4]
  # [1, 3, 2, 4]
  # [1, 4, 3, 2]
  # [3, 4, 2, 1]
  # [1, 3, 4, 2]
  # [1, 3, 4, 2]
我无法证明或反驳第二种方法会产生随机样本。然而,我们可以确定结果的相对频率:

n = 500_000
h = n.times.with_object(Hash.new(0)) { |_,h| h[sample_no_match(array)] += 1 }
h.keys.each { |k| h[k] = (h[k]/(n.to_f)).round(4) }
h #=> {[1, 2, 3, 4]=>0.0418, [2, 1, 3, 4]=>0.0414, [1, 4, 2, 3]=>0.0418,
  #    [3, 4, 2, 1]=>0.0417, [4, 3, 2, 1]=>0.0415, [3, 1, 4, 2]=>0.0419,
  #    [2, 3, 1, 4]=>0.0420, [4, 2, 3, 1]=>0.0417, [3, 2, 1, 4]=>0.0413,
  #    [4, 2, 1, 3]=>0.0417, [2, 1, 4, 3]=>0.0419, [1, 3, 2, 4]=>0.0415,
  #    [1, 2, 4, 3]=>0.0418, [1, 3, 4, 2]=>0.0417, [2, 4, 1, 3]=>0.0414,
  #    [3, 4, 1, 2]=>0.0412, [1, 4, 3, 2]=>0.0423, [4, 1, 3, 2]=>0.0411,
  #    [3, 2, 4, 1]=>0.0411, [2, 4, 3, 1]=>0.0418, [3, 1, 2, 4]=>0.0419,
  #    [4, 3, 1, 2]=>0.0412, [4, 1, 2, 3]=>0.0421, [2, 3, 4, 1]=>0.0421}
avg =  (h.values.reduce(:+)/h.size.to_f).round(4)
  #=> 0.0417 
mn, mx = h.values.minmax
  #=> [0.0411, 0.0423] 
([avg-mn,mx-avg].max/avg).round(6)
  #=> 0.014388
这意味着与平均值的最大偏差仅为平均值的1.4%

这表明第二种方法是产生伪随机样本的合理方法

最初,该方法的第一行是:

  a = array.each_index.to_a

然而,通过观察结果的频率分布,很明显该方法不会产生伪随机样本;因此,需要洗牌
a

这里有两种方法,在获得有效样本之前不涉及重复采样:

来自有效排列总体的样本

构建要从中采样的总体:

array = [1, 2, 3, 4]

population = array.permutation(array.size).reject do |a|
  a.zip(array).any? { |e,f| e==f }
end
  #=> [[2, 1, 4, 3], [2, 3, 4, 1], [2, 4, 1, 3], [3, 1, 4, 2], [3, 4, 1, 2],
  #    [3, 4, 2, 1], [4, 1, 2, 3], [4, 3, 1, 2], [4, 3, 2, 1]] 
然后随便选一个:

10.times { p population.sample }
  # [4, 3, 1, 2]
  # [3, 4, 1, 2]
  # [3, 4, 1, 2]
  # [4, 3, 1, 2]
  # [2, 1, 4, 3]
  # [2, 1, 4, 3]
  # [4, 1, 2, 3]
  # [2, 1, 4, 3]
  # [4, 3, 1, 2]
  # [3, 4, 1, 2]
阵列中每个位置的顺序采样

def sample_no_match(array)
  a = array.each_index.to_a.shuffle
  last_ndx = a[-1]

  a.dup.map do |i|
    if a.size == 2 && a[-1] == last_ndx
      select = a[-1]
    else
      select = (a-[i]).sample
    end
    a.delete(select)
    array[select]
  end
end          

10.times.each { p sample_no_match(array) }
  # [2, 4, 3, 1]
  # [4, 3, 1, 2]
  # [2, 1, 3, 4]
  # [1, 3, 4, 2]
  # [1, 3, 2, 4]
  # [1, 3, 2, 4]
  # [1, 4, 3, 2]
  # [3, 4, 2, 1]
  # [1, 3, 4, 2]
  # [1, 3, 4, 2]
我无法证明或反驳第二种方法会产生随机样本。然而,我们可以确定结果的相对频率:

n = 500_000
h = n.times.with_object(Hash.new(0)) { |_,h| h[sample_no_match(array)] += 1 }
h.keys.each { |k| h[k] = (h[k]/(n.to_f)).round(4) }
h #=> {[1, 2, 3, 4]=>0.0418, [2, 1, 3, 4]=>0.0414, [1, 4, 2, 3]=>0.0418,
  #    [3, 4, 2, 1]=>0.0417, [4, 3, 2, 1]=>0.0415, [3, 1, 4, 2]=>0.0419,
  #    [2, 3, 1, 4]=>0.0420, [4, 2, 3, 1]=>0.0417, [3, 2, 1, 4]=>0.0413,
  #    [4, 2, 1, 3]=>0.0417, [2, 1, 4, 3]=>0.0419, [1, 3, 2, 4]=>0.0415,
  #    [1, 2, 4, 3]=>0.0418, [1, 3, 4, 2]=>0.0417, [2, 4, 1, 3]=>0.0414,
  #    [3, 4, 1, 2]=>0.0412, [1, 4, 3, 2]=>0.0423, [4, 1, 3, 2]=>0.0411,
  #    [3, 2, 4, 1]=>0.0411, [2, 4, 3, 1]=>0.0418, [3, 1, 2, 4]=>0.0419,
  #    [4, 3, 1, 2]=>0.0412, [4, 1, 2, 3]=>0.0421, [2, 3, 4, 1]=>0.0421}
avg =  (h.values.reduce(:+)/h.size.to_f).round(4)
  #=> 0.0417 
mn, mx = h.values.minmax
  #=> [0.0411, 0.0423] 
([avg-mn,mx-avg].max/avg).round(6)
  #=> 0.014388
这意味着与平均值的最大偏差仅为平均值的1.4%

这表明第二种方法是产生伪随机样本的合理方法

最初,该方法的第一行是:

  a = array.each_index.to_a

然而,通过观察结果的频率分布,很明显该方法不会产生伪随机样本;因此,洗牌
a

的需要可以
array
包含重复的数组?总共可以有多少个数组?假设两个数组没有重复。同样,这只适合我,这样我可以改进重构。我只是不满足于这看起来有多“平庸”。数组是否可以包含重复项?总共可以包含多少个数组?假设两个数组没有重复项。同样,这只适合我,这样我可以改进重构。我只是不满足于这看起来多么“平庸”。很好,我只是在看
Array#permutation
并思考应用程序!很好,我只是在看
Array#permutation
并思考应用程序!为了理解这里的过程,
zip
方法允许我同时访问两个数组。然后,
all?
将数组中的每个元素与其在另一个数组中的各自索引进行比较。本质上是:
array.zip(新的数组)?{| el,new|el | el!=new|el}
为了让我理解这里的过程,
zip
方法允许我同时访问两个数组。然后,
all?
将数组中的每个元素与其在另一个数组中的各自索引进行比较。本质上是:
array.zip(新的数组)?{| el,new | el!=new | el}