0

My object method "mutateWeights" is overwriting the weights of other objects in the array.

In the object constructor:

var Bot = function(id, w) {
  this.id = id;
  //default weight setup
  this.weights = [];
  for (var i = 0; i < layerSize.length-1; i++){
    if (!w){
      this.weights.push(randM(layerSize[i], layerSize[i+1]));
    }
    else {
      this.weights.push(w[i]);//transfer weights
    }
  }
...
}

The object method in question:

this.mutateWeights = function() {
    for (var a = 0; a < this.weights.length; a++){//layer
    for (var b = 0; b < this.weights[a].length; b++){//node
    for (var c = 0; c < this.weights[a][b].length; c++){//weight
      if (Math.random() < mutRate) {
        this.weights[a][b][c] += -(Math.random()*mutAmount) + mutAmount/2;
        //mutate weight
      }
    }
    }
    }
  }

Context (separate file)

var w = [...];

//fitness
var calcFit = function(r){
  return r[0]+r[1]-r[2]-r[3];//maximize first 2 values, minimize second 2 values
}
var results = [];
//add sims
var sims = [];
for (var i = 0; i < 5; i++) {
  sims.push(new bots.Bot("test"+i,w))
}

for (var i = 0; i < sims.length; i++){
  //sims[i].mutateWeights();
  console.log(sims[i].weights[0][0]);//display
}
console.log("------")
for (var i = 0; i < sims.length; i++){
  sims[i].mutateWeights();
  console.log(sims[i].weights[0][0]);//display
  var fit = calcFit(sims[i].forward([1]));
  results.push([sims[i].weights,fit,sims[i].id]);
}
console.log("------")
for (var i = 0; i < sims.length; i++){
  //sims[i].mutateWeights();
  console.log(sims[i].weights[0][0]);//display
}

Output:

[
  0.192568385610431,
  0.05389724145564245,
  0.041428484330964466,
  0.24917383336955612
]
[
  0.192568385610431,
  0.05389724145564245,
  0.041428484330964466,
  0.24917383336955612
]
[
  0.192568385610431,
  0.05389724145564245,
  0.041428484330964466,
  0.24917383336955612
]
[
  0.192568385610431,
  0.05389724145564245,
  0.041428484330964466,
  0.24917383336955612
]
[
  0.192568385610431,
  0.05389724145564245,
  0.041428484330964466,
  0.24917383336955612
]
------
[
  0.11953976619833329,
  0.24212772009134087,
  0.23558528526270894,
  0.3910083938836849
]
[
  -0.06987351105892547,
  0.3742948009844833,
  0.10437078715186321,
  0.33516549084268943
]
[
  -0.2855455435602774,
  0.2298369165359223,
  0.15845657493982612,
  0.16781895331427665
]
[
  -0.5093025166025955,
  0.08006909879998025,
  0.16292588137910247,
  0.14662554002545924
]
[
  -0.6707607041616855,
  0.08180062777479391,
  0.4043582027949565,
  0.0009207379625008061
]
------
[
  -0.6707607041616855,
  0.08180062777479391,
  0.4043582027949565,
  0.0009207379625008061
]
[
  -0.6707607041616855,
  0.08180062777479391,
  0.4043582027949565,
  0.0009207379625008061
]
[
  -0.6707607041616855,
  0.08180062777479391,
  0.4043582027949565,
  0.0009207379625008061
]
[
  -0.6707607041616855,
  0.08180062777479391,
  0.4043582027949565,
  0.0009207379625008061
]
[
  -0.6707607041616855,
  0.08180062777479391,
  0.4043582027949565,
  0.0009207379625008061
]

Notice in the final segment of the output that all the weights are the same, even though they shouldn't be. Why is this happening and how do I fix it?

IDE: Replit Language: Node Js

  • Does this answer your question? [Is JavaScript a pass-by-reference or pass-by-value language?](https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) – jabaa May 13 '22 at 02:12
  • 1
    TLDR; you're passing the same reference to the same array every time you call `bots.Bot`. All bots have a reference to the same array. Your next question is probably something like [What is the most efficient way to deep clone an object in JavaScript?](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/5344074#5344074) or [Fastest way to duplicate an array in JavaScript - slice vs. 'for' loop](https://stackoverflow.com/questions/3978492/fastest-way-to-duplicate-an-array-in-javascript-slice-vs-for-loop). A shallow copy is enough. – jabaa May 13 '22 at 02:14
  • It feels like you should probably make `Bot` into a proper class. Your 'object constructor' isn't really a constructor but just a function so `this` is shared across all calls. This is mostly a slightly different way to say what @jabaa said above. – mr rogers May 13 '22 at 02:29

0 Answers0