0

I'm trying to set a resource variable. It will be time and will function like sugar in sugarscape. Its setup is: ask agentes [set time random-in-range 1 6]. The thing is... I want the agentesto participate in activities linking like we said here. But, with each participation, it should subtract a unity of agentes's time. I imagine it must be with foreachbut I seem to be unable to grasp how this works.

  ask n-of n-to-link agentes with [n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
    while [time >= 2] [
      create-participation-with myself [ set color [color] of myself ] ]
      foreach (command I don't know)[
        set time time - count participations]]

Essentially, I want the agentes to look if they have time to participate. If they do, they create the link and subtract 1 to their time. Only ONE per participation. If they have 3 time, they'll have 2 participations and 1 time. If they have 1 time, they won't have links at all.

EDIT You're right. I don't need while. About foreach, every place I looked said the same thing but I can't think of other way. About colors, they're only for show purpose. The relationship between time and participation counts is as follows: the agentes have time they can spend in activities. They participate if time>=2. But every participation (link with activity) consumes 1 time when the link is active (I didn't write the decay code yet; they'll regain their time when it is off).

EDIT V2

Nothing, it keeps subtracting even with the []. Maybe the best choice is if I give you the code so you can try it. You'll have to set 5 sliders: prob-female (53%), initial-people (around 200), num-activity (around 20), n-capacity (around 25) and sight-radius (around 7). And two buttons, setup and go. I also set a patch size of 10 with 30 max-pxcor and max-pycor. Here is the code. Sorry if I'm not clear enough!

undirected-link-breed [participations participation]

turtles-own [
  n-t-activity
]

breed [activities activity]
activities-own [
  t-culture-tags
  shared-culture
]

breed [agentes agente]
agentes-own [
  gender
  time
  culture-tags
  shared-culture
]

to setup
  clear-all
  setup-world
  setup-people-quotes
  setup-activities
  reset-ticks
END

to setup-world
  ask patches [set pcolor white]
END

to setup-people-quotes                                                      
  let quote (prob-female / 100 * initial-people)                            
  create-agentes initial-people
      [ while [any? other turtles-here ]
      [ setxy random-xcor random-ycor ]
      set gender "male" set color black
  ]
  ask n-of quote agentes
    [ set gender "female" set color blue
  ]
  ask agentes [
    set culture-tags n-values 11 [random 2]
        set shared-culture (filter [ i -> i = 0 ] culture-tags)
  ]
  ask agentes [
    set time random-in-range 1 6
  ]
  ask agentes [
    assign-n-t-activity
  ]
END

to setup-activities
  create-activities num-activity [
    set shape "box"
    set size 2
    set xcor random-xcor
    set ycor random-ycor
    ask activities [
      set t-culture-tags n-values 11 [random 2]
      set shared-culture (filter [i -> i = 0] t-culture-tags)
    ]
    ask activities [
      assign-n-t-activity]
  ]
END

to assign-n-t-activity                                                      
  if length shared-culture <= 4 [
    set n-t-activity ["red"]
    set color red
  ]
  if length shared-culture = 5 [
    set n-t-activity ["green"]
    set color green
  ]
  if length shared-culture = 6 [
    set n-t-activity ["green"]
    set color green
  ]
  if length shared-culture >= 7 [
    set n-t-activity ["black"]
    set color black
  ]
END

to go
  move-agentes
  participate
  tick
end

to move-agentes
  ask agentes [
    if time >= 2 [
    rt random 40
    lt random 40
    fd 0.3
  ]
  ]
end

to participate
  ask activities [
   if count my-links < n-capacity [
      let n-to-link ( n-capacity - count my-links)
      let n-agentes-in-radius count (
        agentes with [
          n-t-activity = [n-t-activity] of myself ] in-radius sight-radius)
      if n-agentes-in-radius < n-to-link [
        set n-to-link n-agentes-in-radius
      ]
      ask n-of n-to-link agentes with [
        n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
        if time >= 2 [
          create-participation-with myself [
            set color [color] of myself ]
          ask agentes [set time time - count my-participations] ]
        ]
      ask activities [
        if not any? agentes in-radius sight-radius [
          ask participations [die]
          ]
        ]
      ]
    ]
end

to-report random-in-range [low high]
  report low + random (high - low + 1)
END

EDIT V3

I asked Bill Rand to help me and he solved the problem. The issue was in this line: let candidates agentes with [ n-t-activity = [n-t-activity] of myself ] in-radius sight-radius. He solved the problem this way: let candidates agentes with [ n-t-activity = [n-t-activity] of myself and not participation-neighbor? myself ] in-radius sight-radius. Being this and not participation-neighbor? myself the condition to make sure that the agente is not already a part of that activity.

1 Answers1

2

You almost never need foreach in NetLogo. If you find yourself thinking you need foreach, your immediate reaction should be that you need ask. In particular, if you are iterating through a group of agents, this is what ask does and you should only be using foreach when you need to iterate through a list (and that list should be something other than agents). Looking at your code, you probably don't want the while loop either.

UPDATED FOR COMMENTS and code - you definitely do not need while or foreach. Your problem is the following code. You ask agentes that satisfy your conditions to create the links, but then you ask ALL AGENTES to change their time (line I have marked), not just the agentes that are creating participation links.

  ask n-of n-to-link agentes with [
    n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
    if time >= 2 [
      create-participation-with myself [
        set color [color] of myself ]
      ask agentes [set time time - count my-participations] ]    ; THIS LINE
    ]

The following code fixes this problem. I have also done something else to simplify reading and also make the code more efficient - I created an agentset (called candidates) of the agentes that satisfy the conditions. In this code, the candidates set is only created once (for each activity) instead of twice (for each activity) because you are creating it to count it and then creating it again to use for participation link generation.

to participate
  ask activities
   [ if count my-links < n-capacity
     [ let candidates agentes with [ 
           n-t-activity = [n-t-activity] of myself ] in-radius sight-radius
        let n-to-link min (list (n-capacity - count my-links) (count candidates ) )
        ask n-of n-to-link candidates
        [ if time >= 2
          [ create-participation-with myself [ set color [color] of myself ]
            set time time - count my-participations ]    ; REPLACED WITH THIS LINE
        ]
      ask activities [
        if not any? agentes in-radius sight-radius [
          ask participations [die]
          ]
        ]
      ]
    ]
end
JenB
  • 17,620
  • 2
  • 17
  • 45
  • I think I wrote similar code to yours but the substraction keeps going even with `agentes`with only one `participation` until they have time<2. I only want to substract time once per `participation` until they stop, with time=1. Imagine an `agente` with time=4 who finds 2 `activities` (with his same color). He will loose 2 time units and participate in 2 `activities` keeping an amount of 2 time units. *PROBLEM EDITED FOR MORE INFO* – Jorge Martínez Jul 03 '17 at 17:00
  • From your other question, you appear to have already solved the problem of creating the correct number of links (I gather links are between agentes and activies). If so, why don't you simply do `ask agentes [set time time - count my-links]` after creating the links? – JenB Jul 03 '17 at 21:34
  • Yes, links are between `agentes` and `activities` and yes, the creation of the links is not the problem. The problem is the subtraction of `time`. Your suggestion is exactly what I did at the beginning! But It keeps consuming the `agentes`'s `time` until it stops (because of the `while [time >= 2]` loop). I want that operation (subtract as many units of `time` as links the `agentes` have) to run only once per link created. But it keeps going. I imagine that happens due to the nature of `go` but I should be capable to limit that operation to happen only when I want... right? – Jorge Martínez Jul 03 '17 at 22:08
  • Yes, if you have this in the `go` step, then it will subtract the resource every tick. That is how you get the resource to be consumed. If you want it to take 10 ticks to be consumed, then do `ask agentes [set time time - 0.1 * count my-links]`. Or maybe you want it to be consumed with some probability. Either way, a `while` loop is incorrect, the `tick` command steps through time (simulated time, not the resource time). – JenB Jul 03 '17 at 22:34
  • That's exactly the problem! I just want Netlogo to subtract the resource `time`when the `agentes`create a new participation. I guess I'd have to do something like `if agentes create-new-participation [set time time - 1] stop subtraction`. But I obviosly don't know how to do it in a way it works. Should I make it happen outside the `go`step? I'm completely lost, as you can see. – Jorge Martínez Jul 04 '17 at 10:54
  • EDIT V2 with more info. – Jorge Martínez Jul 05 '17 at 10:23
  • see revised answer – JenB Jul 05 '17 at 12:18
  • Thanks with the more elegant code. I knew I would have to work on it to get a snappier simulation. But since I'm no expert I would have faced a big problem, I think. About the time issue, I'm sorry if I don't explain myself too well. English isn't my main language so I don't translate my problem quite well. I'll link some images so you can see better what I'm referring to. https://drive.google.com/drive/folders/0B9WYKAF47FqwQmtYdTJYRGJSZUk?usp=sharing. Maybe they explain better than myself the problem I'm facing. You have to focus on the `time`variable. – Jorge Martínez Jul 05 '17 at 14:04
  • I thought I had fixed it, when I tested this the subtraction seemed fine. I marked the changed line in the code. – JenB Jul 05 '17 at 15:18
  • Yeah, I saw the replaced line. Uhm. Maybe I'm doing something wrong, but now we should have the same code. The reason why I think it doesn't stop after creating the link is because time is always stuck (if they have links) under 2 (`[ if time >= 2`). Can it be that we have different versions of NetLogo and maybe the procedure runs differently? I know it shouldn't but I don't know what to think. – Jorge Martínez Jul 05 '17 at 15:43
  • I have the last version, by the way. – Jorge Martínez Jul 05 '17 at 15:53
  • One curious thing more... now that I'm looking deeper, it works but only in a handfull of `agentes`. While the majority lose all their time, some of them doesn't. Here is a weird example: https://drive.google.com/file/d/0B9WYKAF47FqwZTVjOFZHTzlOU1U/view?usp=sharing. Could it be some code interrupting the order? – Jorge Martínez Jul 05 '17 at 17:10
  • It's definitely not a version problem. I can't see anything weird about that example, which means I clearly don't understand what you're trying to do. That turtle has 3 time left and I thought your original problem was that time reduced to 0. So what's wrong with it being 3? – JenB Jul 05 '17 at 23:16
  • The weird thing is that this works okay with the ones far from the activity. If they get closer and the `activity` has `capacity` for them (even if it is other activity) it finally subtracts all their time. I think this happens because the `activity` creates the link but the `agente` moves away before all their time is subtracted, since the subtraction only happens near the `activity`. Normally this would kill the `link`but in some cases it doesn't. The biggest problem is, still, the `time` being subtracted until it is under 2. For the record you understood what I'm trying. I think. – Jorge Martínez Jul 06 '17 at 09:43
  • Edit V3. With solution. – Jorge Martínez Jul 07 '17 at 23:22
  • 2
    Great, glad it's fixed. So it sounds like there were actually about 3 different errors in the same piece of code. NetLogo is easy to debug if it's a syntax error and difficult to debug if it's a logical error (because there's not a good way to trace what's going on). It is therefore VERY important to program gradually, making sure each logical step works before writing the next piece. For this sort of build, it would have been good to make the selected turtles change size. Only once you were sure that was correct would you then introduce the resource subtraction. – JenB Jul 08 '17 at 10:14