Search code examples
netlogoagent-based-modeling

NetLogo: pair lists containing similar elements


I wonder if anyone can help with this question for which I am a bit lost. I have turtles with three-dimensional boolean lists [a b c] where a, b, c in {0, 1}. I would like each turtle to create a link with another one who has 1 on all the same positions of the list. A turtle should thus identify where in its list it has 1 and look for another turtle that has 1 in the every same position. Where the original turtle has 0, the second one can have either 1or 0.

That is:

Turtle 1 [0 1 0]

Turtle 2 [1 1 1]

Turtle 3 [1 0 1]

Turtle 4 [0 1 1]

Turtle 1 should create links with Turtle 2 or Turtle 4 (because both have 1 on item 1, the second position) but not with Turtle 3 since it has a 0in that position. Turtle 4 should create a link with Turtle 2 only (1 in the second and third positions), as should Turtle 3 (1in the first and third position), and Turtle 2 should be unable to create links (no turtles with 1 in all three positions).

What I have is

let candidate one-of turtles with [list1 = [list1] of myself]
create-link-with candidate

Which of course doesn't work since the turtle will look for another one that has exactly the same list (including zeros) and not one that has the same positions for 1 only. I know this should be related to foreach, map, reduceand filterbut I can't quite get the syntax right...

Happy end of year to everyone


Solution

  • I'm sure someone who is better at lists will be able to do this with reduce or other clever tools. However, since position only gives the first position, I can't see any vectorised way to do this. So I have iterated with foreach instead.

    to testme
      let list1 [0 1 0]
      let list2 [1 1 1]
      let list3 [1 0 1]
      let list4 [0 1 1]
      type "check 1, 2: " print match-ones list1 list2
      type "check 1, 3: " print match-ones list1 list3
      type "check 1, 4: " print match-ones list1 list4
      type "check 2, 1: " print match-ones list2 list1
      type "check 2, 3: " print match-ones list2 list3
      type "check 2, 4: " print match-ones list2 list4
      type "check 3, 1: " print match-ones list3 list1
      type "check 3, 2: " print match-ones list3 list2
      type "check 3, 4: " print match-ones list3 list4
      type "check 4, 1: " print match-ones list4 list1
      type "check 4, 2: " print match-ones list4 list2
      type "check 4, 3: " print match-ones list4 list3
    end
    
    to-report match-ones [#source #target]
      foreach range length #source
      [ x -> if item x #source = 1 and item x #target != 1
        [ report false
        ]
      ]
      report true
    end
    

    The reporting procedure takes the first list and simply runs through checking each item. If it's a 1 and the other list doesn't have a 1 then the procedure reports false (and ends without testing the others). If that never happens, the the procedure reports true.

    The testme procedure is simply there to call the procedure and check your test data. The code is a complete model.