To build patch clusters at large spatial scales - netlogo

I used the code from How to create cluster patches that do not overlap between them to build patches as shown in the first figure below.
Here is the code :
to make-cluster
loop [
let cluster [patches in-radius (2 + random-float 2)] of one-of patches
if all? (patch-set [neighbors] of cluster) [pcolor = black] [
ask cluster [ set pcolor green ]
stop ] ]
clear-all repeat 20 [ make-cluster ]
When I use this code in a large spatial extent (i.e. 1000 x 1000 patches with patch size = 1 pixel), green patches are like circles (see the second figure below).
How can I have patches as shown in the first figure ?
Thank you very much for your help.

If your goal is to simply have heterogeneous regions (rather than specifically blocky, symmetric things), you might play around with some of the answers here: Creating a random shape (blob) of a given area in NetLogo
Frank's solution and my first solution will probably run pretty slow on that large of a world. I just added a solution that should scale to a world of your size. I've put it here too for convenience:
to make-blob [ area x y ]
let blob-maker nobody
crt 1 [ set blob-maker self setxy x y ]
let border patch-set [ patch-here ] of blob-maker
repeat area [
ask blob-maker [
ask min-one-of border [ distance myself ] [
set pcolor green
set border (patch-set border neighbors4) with [ pcolor = black ]
]
rt random 360
fd .8
]
]
ask blob-maker [ die ]
end
That said, if you like the blockiness, it's often the case that models with a large number of patches in a blocky formation can be reworked into models with a smaller number of patches that behave quite similarly. For example, one strategy is to scale down the size and movements of the turtles so that the world is still relatively large to them.

Related

Network modelling using Netlogo

I am new in using NetLogo, so I hope you can help me with this code.
I would like to build a network with two subnetwork, A and B, where A has N nodes and B beta*N nodes, where beta=0.5. Each network should be initialised with five fully connected nodes. I need to add a new node at a time, assuming that each has fixed out-degree k. Once a new node i comes into the network, it links to a randomly selected target node j. The other remaining k-1 nodes should be selected as following: with probability p, i should be linked to a random node of j's; with probability 1-p, i should be connected to another randomly selected node in A.
On the other hand, the nodes in B should be linked (directed link) to each node in A with probability P. P can vary from 0 to 1.
What I already tried is built the two networks with N and alpha*N nodes respectively. But, as I said, I am new in using NetLogo and I am finding many difficulties to build this network that should be really easy in a different programming language, I would be more familiar with.
; Global variables
breed [agents agent]
breed [bagents bagent]
to setup
clear-all
setup-agent
setup-bagent
end
; Defining agents
to setup-agent
set-default-shape turtles "person" ; agent shape
create-agents n-of-agents ; # of agents
[set size 2 ; agent size
set color white
setxy (random-xcor) (random-ycor)
]
; Random Network
ask agents [create-link-with one-of other agents with [not link-neighbor? myself]
ask links [set color white]
]
end
; Defining bagents
to setup-bagent
set-default-shape turtles "circle" ; bagents shape
set beta=0.5
let n-of-bagents beta*n-of-agents
create-bagents beta*n-of-agents ; # of bagents
[set size 2 ; bagent size
set color red
setxy (random-xcor) (random-ycor)
; Network
ask bagents [create-link-with one-of other bagents with [not link-neighbor? myself]
ask links [set color yellow]
]
end
to go
end
I hope you can help me to understand how to build such a network in NetLogo.
Many thanks
This does what you said. I don't think it's actually what you want as your algorithm is much better but still somewhat confused. But hopefully this gets you on the correct path.
UPDATED to make one node add each tick
globals
[ beta
prob
k
]
breed [A-agents A-agent]
breed [B-agents B-agent]
to setup
clear-all
set beta 0.5
set prob 0.2
set k 3
setup-A-seed
setup-B-seed
reset-ticks
end
to go
add-A-node
if random-float 1 < beta [add-B-node]
tick
end
; Defining A seed network
to setup-A-seed
create-A-agents 5
[ set shape "person"
set size 2
set color white
setxy random-xcor random-ycor
]
ask A-agents
[ create-links-to other A-agents
[ set color white ]
]
end
; Defining B seed network
to setup-B-seed
create-B-agents 5
[ set shape "circle"
set size 2
set color red
setxy random-xcor random-ycor
]
ask B-agents
[ create-links-to other B-agents
[ set color yellow ]
]
end
to add-A-node
create-A-agents 1
[ set shape "person"
set size 2
set color white
setxy random-xcor random-ycor
let target one-of other A-agents ; target is j in description
create-link-to target
repeat k - 1
[ let candidates (other [link-neighbors] of target) with [not link-neighbor? myself]
ifelse random-float 1 < prob or not any? candidates
[ create-link-to one-of other A-agents with [not link-neighbor? myself]
[ set color white ]
]
[ create-link-to one-of candidates
[ set color white ]
]
]
]
end
to add-B-node
create-B-agents 1
[ set shape "circle"
set size 2
set color red
setxy random-xcor random-ycor
let thisB self
ask A-agents
[ if random-float 1 < prob
[ create-link-from thisB
[ set color yellow
]
]
]
]
end
Some of the NetLogo issues I noticed in your code:
NetLogo does not use = for set
you must have space around mathematical operators (or NetLogo will think it's part of the name)
Some of the things you need to think about in your algorithm:
why do you have an initial B network if all Bs connect to each A with fixed probability?
what do you do if the selected A doesn't have any edges to follow?
As general advice, don't try writing something this complicated in one piece. Create your seed networks with 5 fully connected nodes. Make that work. Then do network A and make that work. Then bring in B. This iterative building is important for all programming languages. It is particularly important when using a new language so that you only have to debug one or two errors at a time and you know where the bugs are.

How to find the average distance from turtles that fulfill a certain condition?

I want to move the current turtle one step closer to the others that fulfill a certain condition (e.g. have color = green).
I am doing this the hard way (because I don't know any better), by trying to calculate the the average distance of the current turtle from all others that fulfill the condition, and calculate the average from x+1, x-1, y+1, y-1. Then whichever is the smallest would indicate the direction of the move. Not very elegant, I know, and limits movements to horizontal and vertical, but I couldn't come up with anything better (the only other idea that struck me was to calculate average x and y coordinates of all turtles that fulfill the condition and move the current turtle towards that, but that seemed even more ridiculous to me)
Problem is that even with my clumsy solution, I am not getting anywhere, since I am struggling with how to calculate the average distance from the "green" turtles.
If you want to calculate the mean distance, you can have the asking turtle call mean and [distance myself].
With this setup:
to setup
ca
crt 10 [
set color green
move-to one-of patches with [ pxcor < 0 ]
]
crt 1 [
set color red
move-to one-of patches with [ pxcor > 10 ]
]
reset-ticks
end
Calling the function below will have the red turtle print out first all distances between itself and all green turtles, then the mean of those distances:
to calc-mean-distance
ask turtles with [ color = red ] [
print [ distance myself ] of turtles with [ color = green ]
print mean [ distance myself ] of turtles with [ color = green ]
]
end
Beyond that, I'm not 100% sure what you're trying to do- are you hoping to move the asking turtle towards the nearest turtle that meets some condition? If so, this might work for you:
to go
ask turtles with [ color = red ] [
let target min-one-of ( turtles with [ color = green ] ) [ distance myself ]
face target
ifelse distance target > 1 [
fd 1
] [
move-to target
]
]
tick
end
If you want the asking turtle to move instead towards the geographic center of those turtles that meet a condition, you could indeed get the mean x and y coordinates of those turtles as you describe, then have the asking turtle move towards that point:
to go
let central-x mean [ xcor ] of turtles with [ color = green ]
let central-y mean [ ycor ] of turtles with [ color = green ]
ask turtles with [ color = red ] [
facexy central-x central-y
ifelse distancexy central-x central-y > 1 [
fd 1
] [
setxy central-x central-y
]
]
tick
end
If those aren't quite what you're trying to achieve, feel free to leave a comment for clarification!

Create clusters of patches without changing occurrence

I am writing a Netlogo model which only involves patches. I have managed to create a landscape consisting of patches of 6 different colours (each representing a different vegetation in my project) according to probability. So red patches have a probability of 10% to occur on each patch, yellow 5%, brown 20% and so on.
An example of my code where this probability is set up:
let i random-float 1
ifelse i + random-float 0.1 <= 0.8 ;random 0.1 threshold for environmental noise
[ set pcolor green ]
[ ifelse i + random-float 0.1 <= 0.9
[ set pcolor yellow ]
[ set pcolor blue ] ]
However, this creates a random pattern for each colour. But I would like to create a clustered spatial pattern for one of them.Specifically, in my landscape, I want the proportion of brown patches to be 50%. But if I were to set this 50% probability for every patch, the brown patches will be randomly distributed. How do I get it to occupy 50% of my landscape, but appear in a clustered pattern?
I tried creating the clustered pattern using the Moore neighbourhood, but that obviously changes the proportion of brown patches.
I hope this is somewhat clear. Thanks for any help in advance.
You could seed based on your weights and then grow around the seeds. Here is a different approach: color all patches based on your weights, and then cluster the colors.
extensions [rnd] ;use the rnd extension
globals [threshold]
to setup
ca
set threshold 2
let _cw [[red 10] [yellow 20] [blue 70]] ;colors with weights
ask patches [set pcolor first rnd:weighted-one-of-list _cw [last ?]]
repeat 20 [cluster] ;adjust to taste
end
to cluster
ask patches [
if unhappy? [
swap-pcolor
]
]
end
to swap-pcolor
let _c pcolor
let _p one-of neighbors with [pcolor != [pcolor] of myself]
set pcolor [pcolor] of _p
ask _p [set pcolor _c]
end
to-report unhappy?
let _ct count neighbors with [pcolor = [pcolor] of myself]
report (_ct < threshold)
end

how to see the color identification signal lights?

layout intersections with traffic lights. I want the car to stop when the red lights and the lights go xanh.thi what I should use for car algorithm can recognize the color of the lights
I have used light layout algorithm as follows
to draw-stop-light
ifelse stop-light = "north"
[
ask patch -7 12 [set pcolor green ]
ask patch 10 10 [ set pcolor red ]
ask patch -10 -10 [ set pcolor red ]
]
[
ask patch -7 12 [ set pcolor red ]
ask patch 10 10 [ set pcolor green ]
ask patch -10 -10 [ set pcolor green ]
]
end
This is really a question better suited to the NetLogo users group here than Stack Overflow since you are asking how to program a poorly defined specification. For example, the users group may be able to point you to a similar model. Stack Overflow is really about fixing specific problems with your code. However, here's something to get you started until the question gets deleted.
Break down what you want to happen into very small steps and then code each step. The steps will be something like:
When the car gets near the intersection, check to see what colour the traffic light is
If the light is red, remember to stop at the intersection
Stop at the intersection if required
If at the intersection, wait until the light turns green then go
Do NOT try to write the whole thing. Instead, write one bit at a time and test is to see if it works. Here is some approximate code for the first bit:
ask cars
[ ifelse heading = 180 and ycor > 20 and ycor < 25 and not stop-flag
[ if [ pcolor of patch -7 12 ] = red [ set stop-flag true ] ]
[ ... (cars from other directions)
]
ask cars
[ forward speed
if stop-flag and ... (on intersection patches)
[ ... (move backwards to be outside the intersection)
set stop-flag false
]
]
patch-right-and-ahead (http://ccl.northwestern.edu/netlogo/docs/dictionary.html#patch-lr-and-ahead) could be useful here. Perhaps something like:
if [pcolor] of patch-right-and-ahead 90 1 = red
[ set speed 0 ]

How to randomly remove block side in a grid?

Following on from How to control square size in a grid from square area?, I would like to randomly remove block side in a grid. Here my idea:
%% In a first time, I randomly select a white patch in the grid (figure below):
let random-patch one-of patches with [pcolor = white]
%% Then, I draw red patches to identify intersections between white roads (figure below):
ask patches with [ (pxcor mod (side + 1) = 0 ) and (pycor mod (side + 1) = 0 ) ] [set pcolor red]
%% Finally, I color in brown all white patches that are situated between two red patches and on the same side than the random patch. To identify these white patches, have I to calculate distance between the random patch and the nearest red patches and to color all white patches situated along these distances ?
Thanks in advance for your help.
An alternative way to think about your problem is in terms of finding clusters of white patches: you're picking a white patch at random, and you want to turn all the contiguous white patches to brown.
You can look at the "Patch Clusters Example" in the Code Examples section of NetLogo's model library to see one way to do this.
Here is how I would do it. Let's start by defining a grow-cluster reporter:
to-report grow-cluster [ current-cluster new-patch ]
let patches-to-add [
neighbors4 with [
pcolor = [ pcolor ] of myself and
not member? self current-cluster
]
] of new-patch
let new-cluster (patch-set current-cluster new-patch)
report ifelse-value any? patches-to-add
[ reduce grow-cluster fput new-cluster sort patches-to-add ]
[ new-cluster ]
end
The code may be hard to understand if you're not used to functional programming because it uses recursion within a call to reduce. Still, in a nutshell, it:
takes an existing patch cluster and a new patch to add to this cluster
looks for neighbors of that new patch that should also be added to the cluster, i.e., those that are the same color but not already part of the cluster
calls itself for these new patches to add so that their neighbors can be added to the cluster (and those neighbors' neighbors, etc.) until no new patches are found.
Once you have grow-cluster, you can use it to accomplish exactly what you want by seeding it with an empty cluster and the random patch that you selected:
to remove-random-side
let random-patch one-of patches with [pcolor = white]
let side grow-cluster no-patches random-patch
ask side [ set pcolor brown ]
end
Caveat: for this to work, world wrapping has to be disabled in your model settings.
Since you're making a uniform grid, you might consider just doing math on pxcor and pycor instead of taking the Patch Clusters Example approach. That approach is best suited to dealing with irregular shapes.
To set up your grid, you can just do:
ask patches [
set pcolor brown
let horizontal-street? pycor mod (side + 1) = 0
let vertical-street? pxcor mod (side + 1) = 0
if horizontal-street? or vertical-street?
[ set pcolor white ]
if horizontal-street? and vertical-street?
[ set pcolor red ]
]