Ruby 奇怪的代码执行:应该分配一个元素,分配所有元素
我正在尝试写一个函数逼近的遗传算法。负责一个基因突变的部分代码改变了整个染色体阵列。它甚至更改了本部分中未使用的另一个数组。这是密码Ruby 奇怪的代码执行:应该分配一个元素,分配所有元素,ruby,arrays,genetic-algorithm,Ruby,Arrays,Genetic Algorithm,我正在尝试写一个函数逼近的遗传算法。负责一个基因突变的部分代码改变了整个染色体阵列。它甚至更改了本部分中未使用的另一个数组。这是密码 print "\n\nchrom_array5: ", @chrom_array print "\n\nchrom_array5: ", @chrom_array random = rand if @no_of_chrom*@no_of_variables*@mutation_rate > random z=( rand * @n
print "\n\nchrom_array5: ", @chrom_array
print "\n\nchrom_array5: ", @chrom_array
random = rand
if @no_of_chrom*@no_of_variables*@mutation_rate > random
z=( rand * @no_of_chrom ).to_i
print "\n\nz: ", z
v=( rand * @no_of_variables).to_i
print "\n\nv: ", v
ble=new_chrom_array[0][0]
print "\nnew_chrom_array[0][0]: ", new_chrom_array
new_chrom_array[z][v] = ble + ble*rand - ble*random
print "\nnew_chrom_array[z][v]: ", new_chrom_array
end
print "\n\nchrom_array6: ", @chrom_array
print "\nnew_chrom_array6: ", new_chrom_array
@chrom_array = new_chrom_array
...
以下是变异迭代的输出:
色度阵列5:[1283853580908.78],[1283853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[1283853580908.78],[1283853580908.78],[1283853580908.78]]
新的彩色阵列5:[1283853580908.78],[1283853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[1283853580908.78],[1283853580908.78],[1283853580908.78]]
z:2
v:0
新的彩色阵列[0][0]:[1283853580908.78],[1283853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[128383853580908.78], [128383853580908.78], [128383853580908.78],
[1283853580908.78],[1283853580908.78],[1283853580908.78]]
新的"彩色"阵列[z][v]:[143481948278275.22],[143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22],[143481948278275.22],[143481948278275.22]]
色度阵列6:[143481948278275.22],[143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22],[143481948278275.22],[143481948278275.22]]
新的彩色阵列6:[143481948278275.22],[143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22], [143481948278275.22], [143481948278275.22],
[143481948278275.22],[143481948278275.22],[143481948278275.22]]
您知道这种行为的原因吗?发生这种情况的一种方式是,如果新的\u chrom\u数组的所有元素都包含相同的对象。例如,使用irb以交互方式执行ruby代码:
~ ∙ irb
irb(main):001:0> sub_array = [1]
=> [1]
irb(main):002:0> array1 = [sub_array, sub_array, sub_array]
=> [[1], [1], [1]]
irb(main):003:0> array2 = [sub_array, sub_array, sub_array, sub_array]
=> [[1], [1], [1], [1]]
irb(main):004:0> array1[1][0] = 'x'
=> "x"
irb(main):005:0> array1
=> [["x"], ["x"], ["x"]]
irb(main):006:0> array2
=> [["x"], ["x"], ["x"], ["x"]]
因此,这里对数组[1][0]进行赋值会影响array1和array2,因为它们所有元素中的对象都是sub_array
这可以通过查看数组元素的object_id来确认:
irb(main):007:0> array1[0].object_id
=> 70353532235320
irb(main):008:0> array1[1].object_id
=> 70353532235320
irb(main):009:0> array2[1].object_id
=> 70353532235320
irb(main):010:0> a = Array.new(5, ['x'])
=> [["x"], ["x"], ["x"], ["x"], ["x"]]
irb(main):011:0> a[0].object_id
=> 70353539884820
irb(main):012:0> a[4].object_id
=> 70353539884820
根据我的经验,有两件事导致了这种情况:
使用array.new创建数组,如下所示,它将对所有元素使用相同的对象:
irb(main):007:0> array1[0].object_id
=> 70353532235320
irb(main):008:0> array1[1].object_id
=> 70353532235320
irb(main):009:0> array2[1].object_id
=> 70353532235320
irb(main):010:0> a = Array.new(5, ['x'])
=> [["x"], ["x"], ["x"], ["x"], ["x"]]
irb(main):011:0> a[0].object_id
=> 70353539884820
irb(main):012:0> a[4].object_id
=> 70353539884820
您可以通过使用块来初始化元素来避免这种情况,因为块每次调用时都会返回一个新对象-请注意不同的对象ID
第二个常见问题是使用.dup复制数组,但不记得它是浅拷贝:
您可以使用object_id查看数组的内容。获得一个使副本与原始副本分离的深度副本的一种方法是使用ruby的封送处理来制作数据结构的副本——在这里,我们看到改变a3不会影响a1
irb(main):021:0> a3 = Marshal.load(Marshal.dump(a1))
=> [["y"]]
irb(main):022:0> a3[0][0] = 'z'
=> "z"
irb(main):023:0> a1
=> [["y"]]