我正在尝试编写用于函数逼近的遗传算法。负责一个基因突变的部分代码改变了整个染色体阵列。它甚至会更改此部分中未使用的另一个数组。这是代码。
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
...
这是变异迭代的输出:
chrom_array5:[[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],[128383853580908.78],[128383853580908.78], [128383853580908.78],[128383853580908.78],[128383853580908.78]]
new_chrom_array5:[[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],[128383853580908.78],[128383853580908.78], [128383853580908.78],[128383853580908.78],[128383853580908.78]]
z:2
v:0
new_chrom_array [0] [0]:[[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],[128383853580908.78],[128383853580908.78], [128383853580908.78],[128383853580908.78],[128383853580908.78]]
new_chrom_array [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]]
chrom_array6:[[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]]
new_chrom_array6:[[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]]
你知道这种行为的原因吗?
答案 0 :(得分:0)
如果new_chrom_array的所有元素都包含相同的对象,则会出现这种情况。例如,使用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"]]
因此,对array[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
根据我的经验,有几件事导致了这一点:
使用像这样的Array.new
创建一个数组,它将对所有元素使用相同的对象:
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
您可以通过使用块来初始化元素来避免这种情况,因为每次调用块时块都会返回一个新对象 - 请注意不同的object_id
s
irb(main):013:0> b = Array.new(5) {['x']}
=> [["x"], ["x"], ["x"], ["x"], ["x"]]
irb(main):014:0> b[0].object_id
=> 70353535993240
irb(main):015:0> b[4].object_id
=> 70353535992900
第二个常见问题是使用.dup
制作数组的副本,而不记得它是否制作浅副本:
irb(main):016:0> a1 = [['x']]
=> [["x"]]
irb(main):017:0> a2 = a1.dup
=> [["x"]]
irb(main):018:0> a2[0][0] = 'y'
=> "y"
irb(main):019:0> a1
=> [["y"]]
irb(main):020:0> a2
=> [["y"]]
您可以使用object_id
查看数组的内容。获取深副本(将副本与原始副本分离)的一种方法是使用ruby的Marshal
制作数据结构的副本 - 在这里我们看到更改{{ 1}}不会影响a3
a1