Search code examples
dictionarynetlogohamming-distance

NetLogo: remove turtle given hamming distance


Very new to NetLogo... I have two breeds "vaccine" and "antibody". Each owns a string of symbols (e.g. ["A" "B" "C"]). I want the antibodies to remove the vaccine when they occupy the same space AND if at least 2/3 symbols match (latter is issue). I have been trying to use the 'map' function but cannot get it to work. Please Help! Here is what I have tried:

breed [vaccine vaccines]
breed [antibody antibodies]

vaccine-own [
  string2
  hamming-distance
]
antibody-own [
  string1
]

to setup
  clear-all
  create-antibody 10 [ setxy random-xcor random-ycor
    set string1 n-values 3 [one-of["A" "B" "C"]]]
  create-vaccine 2 [ setxy random-xcor random-ycor set color red 
    set string2 n-values 3 [one-of["A" "B" "C"]] ]
  reset-ticks
end

to go
  move-antibody
  remove-antigen
  tick
end

to move-antibody
  ask antibody [
    right random 360
    forward 1
  ]
end

to remove-antigen
  ask vaccine [
    if any? other antibody-here [
      set hamming-distance (length remove true (map [?1 = ?2] string2 [string1] of myself))
      ]
    if any? other antibody-here with [hamming-distance > 1] [die]
  ] 
end

Solution

  • Your use of map in this case is great! The way you combine length, remove true and map for calculating the Hamming distance shows a good understanding of these concepts.

    Your problem is with the structure of your code. I think you should first define hamming-distance as a separate reporter, which will make the rest of the code easier to write:

    to-report hamming-distance [ list1 list2 ]
      report length remove true (map [?1 = ?2] list1 list2)
    end
    

    If you test it in the command center, you will see that it works:

    observer> show hamming-distance ["A" "B" "C"] ["A" "B" "B"]
    observer: 1
    observer> show hamming-distance ["A" "B" "C"] ["C" "C" "C"]
    observer: 2
    

    Once you have that, it's easy to write remove-antigen correctly:

    to remove-antigen
      ask vaccines [
        if any? antibodies-here with [
          hamming-distance string1 [ string2 ] of myself <= 1
        ] [ die ]
      ]  
    end
    

    A few notes:

    • you inverted plural and singular in your breed definitions. The plural always comes first. This way, you ask vaccines (i.e., all the vacinnes) instead of ask vacinne (which would be only one vacinne and doesn't make a lot of sense).

    • to be able to define a hamming-distance reporter, you will need to remove the hamming-distance variable from vaccines-own; you don't need it anyway.

    • in your original code, you asked the vacinnes to check for other antibody-here, but the use of other was unnecessary since you were looking for members of a different breed.

    • in your original code, I think you inverted string1 and string2. In general, you should try to avoid calling variables something1 and something2 (unless it's in some very general code like the hamming-distance reporter I suggested above). Does the string represent DNA? Then call it DNA! And there is nothing wrong with two different breeds having a variable of the same name: don't append 1 and 2 if they represent the same thing.

    • if you want the vaccine to die when 2/3 of the symbols are the same, you should check that the Hamming distance is <= 1, not > 1. Or even better, check that it is <= (1 / 3) * length string1.