奇怪的代码执行:应该分配一个元素,分配所有

时间:2014-04-06 11:40:17

标签: 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 * @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]]

你知道这种行为的原因吗?

1 个答案:

答案 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]进行分配会影响array1array2,因为所有元素中的对象都是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