Assign each number to 3 turtles

2019-08-15 09:02发布

I am creating a program that creates 1,500 "scientists" (turtles), in a world where there are 1500 "disciplines".

I need to assign each turtle a "discipline" as a number between 1-500, and ensure that there are 3 turtles for each discipline.

This means that set(random) isn't appropriate. Is there a primitive I can use?

Nevermind, I think I have figured it out. Does this make sense?

  to set-discipline
    ask turtles [ set discipline -1 ]
    let unassigned turtles
    let current 1
    while [any? unassigned]
    [
      ask n-of (min (list group-size (count unassigned))) unassigned
        [ set discipline current ]
      set current current + 1
      set unassigned unassigned with [discipline = -1]
    ]
  end

标签: netlogo
2条回答
可以哭但决不认输i
2楼-- · 2019-08-15 09:42

What Nicolas said. But consider also this alternate approach:

to test
  let disciplines reduce sentence map [(list ? ? ?)] n-values 500 [? + 1]
  ask turtles [
    set discipline first disciplines
    set disciplines butfirst disciplines
  ]
end

ask is in random order, so we don't need to shuffle the disciplines list.

Or, if the turtles don't exist yet and you're free to create them as you go:

to test
  let disciplines reduce sentence map [(list ? ? ?)] n-values 500 [? + 1]
  foreach shuffle disciplines [
    create-turtles 1 [ set discipline ? ]
  ]
end

In this one, we have to shuffle the list of disciplines, since the turtles are being created in who number order.

查看更多
SAY GOODBYE
3楼-- · 2019-08-15 09:49

Your code works, but is very... unnetlogoish. while loops and indexes, in NetLogo, are often a sign that you're not taking full advantage of the capabilities of the language. At the very minimum, I would replace your while with a foreach:

ask turtles [ set discipline -1 ]
foreach n-values 500 [ 1 + ? ] [
  let unassigned turtles with [ discipline = -1 ]
  ask n-of (min (list group-size (count unassigned))) unassigned [
    set discipline ?
  ]    
]

You can check the result in the command center with:

observer> print remove-duplicates map [ count turtles with [ discipline = ? ] ] n-values 500 [ 1 + ? ]
[3]

But I would suggest taking it a step further.

Having disciplines just be numbers is a bit limiting. That is, of course, the sort of thing that you would do in a traditional mathematical model. But this is an ABM. And you have all of NetLogo at your disposal. You could make your disciplines... turtles! This would make your model much more flexible. Your disciplines could eventually be heterogeneous: having their own variables, by which they could differ from one another. And I think you'll find that replacing numbers with agents makes code more readable in general.

Here is a full example of what I have in mind:

breed [ scientists scientist ]
scientists-own [ my-discipline ]
breed [ disciplines discipline ]

to setup
  clear-all
  let nb-scientists 1500
  let nb-disciplines 500
  let group-size 3  
  create-scientists nb-scientists [
    set my-discipline nobody
  ]
  create-disciplines nb-disciplines [
    let unassigned scientists with [ my-discipline = nobody ]
    ask n-of (min (list group-size (count unassigned))) unassigned [ 
      set my-discipline myself
    ] 
  ]
end

You can check that it worked:

observer> setup
observer> print remove-duplicates [ count scientists with [ my-discipline = myself ] ] of disciplines
[3]

But you know what? If it was me, I would take it another step further, and make the relation between a scientist and its discipline an actual NetLogo link. This way, you could eventually envision a scientist belonging to (gasp!) more than one discipline. Here is what it would look like:

breed [ scientists scientist ]
breed [ disciplines discipline ]

to setup
  clear-all
  let nb-scientists 1500
  let nb-disciplines 500
  let group-size 3
  create-scientists nb-scientists
  create-disciplines nb-disciplines [
    let unassigned scientists with [ not any? my-links ]
    ask n-of (min (list group-size (count unassigned))) unassigned [ 
      create-link-with myself
    ] 
  ]
end

Don't you think the code is even nicer this way? And it works:

observer> print remove-duplicates [ count my-links ] of disciplines
[3]
查看更多
登录 后发表回答