Search code examples
netlogoagent-based-modeling

Create links according to turtle's attributes


I have two turtle breeds (products and consumers) each with a 3-dimension list that defines their needs (consumers) and their attributes (products).

What I'd like is to have each consumer (i) look for a product that satisfies all their needs and create a link with them. If that product does not exist, I'd like them to (ii) drop the one need with the lowest value and look for a product that satisfies the other two. If that product does not exist, then I want them to (iii) look for another one that only satisfies the need with the highest value.

So say that consumer 20 has needs [0.2 0.5 0.3]. If they find a product whith exactly the same list of attributes [0.2 0.5 0.3] I want the link to take place. If there's no such product then I want the consumer to ignore the lowest value (0.2 in the example) and look for a product that has attributes [xx 0.5 0.3], where xx stands for "whatever".

Using examples from elsewhere here in SO, I have cobbled up the following code that (almost!) does the first part of the trick (i), but can't manage to do (ii) and (iii) despite multiple efforts. Would anyone have an indea on how to do this?

breed [consumers consumer]
breed [products product]

consumers-own [
 needs
]

products-own [
 attributes
 number-buyers
]

to setup
 ca
 create-consumers 100 [ setxy random-xcor random-ycor]
 create-products 100 [ setxy random-xcor random-ycor]
 set-default-shape consumers "person"
 set-default-shape products "box"
 ask consumers [
   set needs n-values 3 [ precision (random-float 1) 1 ]
 ]
 ask products [
   set attributes n-values 3 [ precision (random-float 1) 1 ]
 ]
 reset-ticks
end

to go
 buy
 tick
end

to buy
 ask links [ die ]
 ask consumers [
   carefully [ create-link-with one-of products with [reduce and (map = attributes [ needs ] of myself)] ] [ show "how do I find a sub-optimal product by ignoring my need with the lowest value ?" ]
 ]
 ask products [
   set number-buyers count link-neighbors 
 ]
end

Solution

  • You are overthinking the full match - just check if the two lists are the same. However, the almost match is a bit more complicated. Here is a complete example model that finds the position in the list of the lowest and then checks that the other items are the same.

    breed [consumers consumer]
    breed [products product]
    
    consumers-own [
     needs
    ]
    
    products-own [
     attributes
     number-buyers
    ]
    
    to setup
      clear-all
      ask patches [set pcolor white]
      create-consumers 10
      [ setxy random-xcor random-ycor
        set shape "person"
        set color blue
        set needs n-values 3 [ one-of [1 2 3] ] 
      ]
      create-products 10
      [ setxy random-xcor random-ycor
        set shape "box"
        set color red
        set attributes n-values 3 [ one-of [1 2 3] ]
      ]
      reset-ticks
    end
    
    to go
      ask consumers [buy]
      tick
    end
    
    to buy    ; set up as turtle procedure for testing purposes
      ask my-links [ die ]
      let candidates products with [attributes = [needs] of myself]
      ifelse any? candidates
      [ create-link-with one-of candidates ]
      [ type self type " attributes: " type needs print " no matches"
        let lowpoint position (min needs) needs ; note will take first if two equal min
        set candidates products with
        [ ((item 0 attributes = item 0 [needs] of myself) or lowpoint = 0) and
          ((item 1 attributes = item 1 [needs] of myself) or lowpoint = 1) and
          ((item 2 attributes = item 2 [needs] of myself) or lowpoint = 2)
        ]
        ifelse any? candidates
        [ create-link-with one-of candidates ]
        [ print "no almost-match available" ]
      ]
    end
    

    I created the agentset (called candidates) of potential products to link to and then created the link. This makes the code much more readable. It also allows the if any? construction if no matches were found. And it also makes it easier to debug because you can put print statements reporting numbers of matches and similar. I recommend that you always do this if you are applying some sort of condition that restricts the choices.

    Also, you have a three item list with 10 possible values for each item. This means there will be 1000 combinations. You only have 100 consumers and 100 products, so matching will be fairly rare.