I want to count the neighbors and the neighbors neighbors of a turtle to kind of find out a way to calculate the eigenvector-centrality. Since I can´t get the NW:extensions to work and my prof neither. I thought of building a method myself. Since I don´t have that much time until the first round of presentation, I try my best to just count the neighbors and the neighbors neighbors of a turtle.
I decided to have a turtles-own, which counts all neighbors and then sum all the neighbors and neighbors neighbors. But I am stuck in my head and cant get it to work.
set Neighborscount count(link-neighbors)
Anyone has any ideas?
Also a final way to get the eigenvector-centrality to work would be very much appreciated.
First, my main recommendation is to get NW working. I'd be happy to help with that.
Barring that, the below assumes you're working with undirected networks. If that's not the cast, let me know.
The problem with the method that you describe is that it will count some neighbors-of-neighbors multiple times. Instead, you can get the agent-set of neighbors-of-neighbors, and then just count it:
to-report neighbors-of-neighbors
report turtle-set [ link-neighbors ] of link-neighbors
end
Then, [ count neighbors-of-neighbors ] of turtle 0 will give the number of neighbors of neighbors of turtle 0.
Now, a few points:
This will include the turtle itself, since a turtle is always a link neighbor of its link neighbors. If you don't want to include the turtle itself, you can just throw an other in there: [ count other neighbors-of-neighbors ] of turtle 0.
This won't include turtles that are link neighbors of turtle 0, but are not linked to any other neighbors of turtle 0. To add those in, you might consider a procedure like this:
to-report turtles-in-link-radius [ n ]
let result turtle-set self
repeat n [
set result (turtle-set result [ link-neighbors ] of result)
]
report result
end
This can then be used, for instance, like so: [ count turtle-in-link-radius 2 ] of turtle 0 to count all turtles at most 2 hops from turtle 0. This reporter has the same behavior as nw:turtles-in-radius, though it will be significantly slower.
Now, I first noted that your idea would count some turtles multiple times. Given that you're interested in something like eigenvector-centrality, maybe this is what you want. In that case you can do this: [ sum [ count link-neighbors ] of link-neighbors ] of turtle 0 to get it without having to bother with a turtles-own. That said, if you do use a turtles-own, you can actually calculate the eigenvector centrality itself:
turtles-own [
...
next-ec ;; helper variable for iteratively computing eigenvector-centrality
eigenvector-centrality
...
]
to calculate-eigenvector-centralities
ask turtles [
set eigenvector-centrality 1
]
repeat 100 [ ;; the higher this number, the more accurate the value. NW uses 100
ask turtles [
set next-ec sum [ eigenvector-centrality ] of link-neighbors
]
let max-ec max [ next-ec ] of turtles
ask turtles [
set eigenvector-centrality next-ec / max-ec ;; normalize
]
]
end
Call calculate-eigenvector-centralities to calculate all turtles eigenvector centralities. The turtles' eigenvector centralities will then be stored in eigenvector-centrality. Note that this code won't work for disconnected networks: each component has to be normalized independently, which is what NW does, but there's no easy way to do that in NetLogo without using NW.
Related
I have been practicing graph questions lately.
https://leetcode.com/problems/course-schedule-ii/
https://leetcode.com/problems/alien-dictionary/
The current way I detect cycles is to use two hashsets. One for visiting nodes, and one for fully visited nodes. And I push the result onto a stack with DFS traversal.
If I ever visit a node that is currently in the visiting set, then it is a cycle.
The code is pretty verbose and the length is long.
Can anyone please explain how I can use a more standard top-sort algorithm (Kahn's) to detect cycles and generate the top sort sequence?
I just want my method to exit or set some global variable which flags that a cycle has been detected.
Many thanks.
Khan's algorithm with cycle detection (summary)
Step 1: Compute In-degree: First we create compute a lookup for the in-degrees of every node. In this particular Leetcode problem, each node has a unique integer identifier, so we can simply store all the in-degrees values using a list where indegree[i] tells us the in-degree of node i.
Step 2: Keep track of all nodes with in-degree of zero: If a node has an in-degree of zero it means it is a course that we can take right now. There are no other courses that it depends on. We create a queue q of all these nodes that have in-degree of zero. At any step of Khan's algorithm, if a node is in q then it is guaranteed that it's "safe to take this course" because it does not depend on any courses that "we have not taken yet".
Step 3: Delete node and edges, then repeat: We take one of these special safe courses x from the queue q and conceptually treat everything as if we have deleted the node x and all its outgoing edges from the graph g. In practice, we don't need to update the graph g, for Khan's algorithm it is sufficient to just update the in-degree value of its neighbours to reflect that this node no longer exists.
This step is basically as if a person took and passed the exam for
course x, and now we want to update the other courses dependencies
to show that they don't need to worry about x anymore.
Step 4: Repeat: When we removing these edges from x, we are decreasing the in-degree of x's neighbours; this can introduce more nodes with an in-degree of zero. During this step, if any more nodes have their in-degree become zero then they are added to q. We repeat step 3 to process these nodes. Each time we remove a node from q we add it to the final topological sort list result.
Step 5. Detecting Cycle with Khan's Algorithm: If there is a cycle in the graph then result will not include all the nodes in the graph, result will return only some of the nodes. To check if there is a cycle, you just need to check whether the length of result is equal to the number of nodes in the graph, n.
Why does this work?:
Suppose there is a cycle in the graph: x1 -> x2 -> ... -> xn -> x1, then none of these nodes will appear in the list because their in-degree will not reach 0 during Khan's algorithm. Each node xi in the cycle can't be put into the queue q because there is always some other predecessor node x_(i-1) with an edge going from x_(i-1) to xi preventing this from happening.
Full solution to Leetcode course-schedule-ii in Python 3:
from collections import defaultdict
def build_graph(edges, n):
g = defaultdict(list)
for i in range(n):
g[i] = []
for a, b in edges:
g[b].append(a)
return g
def topsort(g, n):
# -- Step 1 --
indeg = [0] * n
for u in g:
for v in g[u]:
indeg[v] += 1
# -- Step 2 --
q = []
for i in range(n):
if indeg[i] == 0:
q.append(i)
# -- Step 3 and 4 --
result = []
while q:
x = q.pop()
result.append(x)
for y in g[x]:
indeg[y] -= 1
if indeg[y] == 0:
q.append(y)
return result
def courses(n, edges):
g = build_graph(edges, n)
ordering = topsort(g, n)
# -- Step 5 --
has_cycle = len(ordering) < n
return [] if has_cycle else ordering
I am trying to model my agents effects on their patch landscape, ie harvesting grain over a period of time. I have a variable that patches-own penergy, I would like to plot the total penergy across the behaviorspace over time. I have an idea how to do this but I don't think I am doing it the most effective way.
To complicate matters, I have multiple grain types, ie ptype. I would like to plot these types independently.
to patch-health
if ptype = 1[
let new-penergy min(list 10 (penergy))
let diff (new-penergy - penergy)
set Wheat-health ((sum ptype1-health) + diff)
]
if ptype = 0 [
let new-penergy min(list 10 (penergy))
let diff (new-penergy - penergy)
set Barley-health ((sum ptype0-health) + diff)
]
end
to-report ptype1-health
if ptype = 1 [
report [penergy] of patches
]
end
to-report ptype0-health
if ptype = 0 [
report [penergy] of patches
]
end
It produces a list of each patches penergy but I added the sum pytpe0-health function to convert the list to a total penergy. The plot works but the model is bogged down and running very slow.
I want think this is easy but can't seem to figure it out. Is there a more efficient way to achieve similar results?
I would like to take the X axis information where there is a turtle with the biggest ID with some specific conditions. And I want to count the number of turtles on the right side of the X axis information. The following is a sample program. I would like to draw a code to obtain X axis information where there is a turtle with the largest ID at the point "here?" in this sample program. Thank you for your advice.
(this link is the 3D image https://i.stack.imgur.com/DQf93.png)
count turtles with [xcor > "here?" ]
There is a lot of ambiguity in your question, but you should be able to change the following to meet your needs.
turtles-own [ID] ;if unique, you can just use `who`
to setup ;make some turtles with various xcors and IDs
ca
crt 100 [
setxy random-xcor random-ycor
set ID random 1000
]
end
to-report top ;get a turtle with biggest id
report max-one-of turtles [ID]
end
to-report winners ;get turtles to right of top
let topx [xcor] of top
report turtles with [xcor > topx]
end
to test
setup
print count winners
end
I am building a simulation of the epidermal cells in NetLogo.
I have two type of cells, progenitors and post mitotic cells. The progenitors are the cells which can divide into either progenitor or post mitotic.
Each run begins with a number of 239 progenitor cells with each their own identity (from 1 to 239) which is a turtles-own. Each time a progenitor divides, the identity is given to the offspring.
I want to count the number of different identities after a certain amount of ticks. I tried it with a monitor and with a list but it did not work.
Here is a small part of the code I have made:
turtles-own [ identity]
globals [ id-count]
to setup
ask patches [sprout-postmitotic 1]
ask n-of (( 22 / 100) * count postmitotic) patches [
ask postmitotic-here [
hatch-progenitor 1
[
set identity id-count
set id-count id-count + 1 ]
die ]
]
end
to go
ask progenitor[
if random-float 1 < l [
hatch-postmitotic 1
]
end
If you post code for a question like this, try to produce a minimal example to support the question. Here are two approaches. (The first illustrates the use of table:counts, which gives access to more information.)
extensions [table]
turtles-own [identity]
to setup
ca
crt 1000 [set identity random 1000]
end
to-report id-count-01
let _idcts table:counts [identity] of turtles
let _unique table:keys _idcts
report length _unique
end
to-report id-count-02
let _unique remove-duplicates [identity] of turtles
report length _unique
end
I'm new at netlogo, and in my model, I'm trying to make it so there's one turtle per patch, so that all the patches are filled up with one turtle instead of them overlapping each other. The code for that part of the model is
to solid
set color blue
set xcor random sqrt number-of-particles - number-of-particles / 2
set ycor random sqrt number-of-particles - number-of-particles / 2
ifelse any? patches with [pcolor = black and count turtles-here = 0]
[move-to one-of patches with [pcolor = black and count turtles-here = 0]]
[die]
end
I've been trying it out with different variables, but it works for odd "Volume" (amount of patches in each row) but not the even ones.
(even numbered one) Link 1
(odd numbered one) Link 2
how would i make it so that it works for both odd and even numbers? thanks!
This is my full setup code. Sorry that I posted them in my comments, this is my first time on stackoverflow.
to Setup-Container
ca
cro 4
[set color black
rt 45
fd Volume * sqrt 2 / 2
rt 135
pd
set pen-size 6
fd Volume
die
]
ask patches
[ifelse pxcor <= Volume / 2 and pxcor >= Volume / 2 * -1
and pycor <= Volume / 2 and pycor >= Volume / 2 * -1
[set pcolor black] [set pcolor black + 3]
]
end
; Creates a number of particles, which depends on the corresponding slider.
; Executes certain commands depending on the temperature slider.
to Setup-Particles
ask turtles
[die]
cro number-of-particles
ask turtles [
set shape "water"
if Temperature <= 0 ; freezing point is 0 degrees celsius.
[ice-cube]
if Temperature > 0 and Temperature < 100
[water]
if Temperature >= 100 ; boiling point is 100 degrees celsius.
[water-vapor]
]
end
There's actually a primitive that just creates a turtle on a given patch: sprout. So, ask patches [ sprout 1 ] would create one turtle on each patch.
Bryan's answer is most probably the right one, here: if your main requirement is to have one turtle per patch, sprout is the way to go.
A few more comments:
In the screenshots you've shown us, you control your "volume" and your number of particles separately, so there is aways a chance that your container will be either too big or too small for the number of particles you want. If you really want a one-to-one relationship between the size of your container and the number of particles, you should really have a single parameter for both.
sprout allows you to give commands to the newly created turtles. If you don't want them to be "rainbow colored", you can do: ask patches with [pcolor = black] [sprout 1 [set color blue]].
In your original code, you set the xcor and the ycor of your turtles... and then immediately move them. The point will be moot if you use sprout, but I wanted to point out that these two lines were unnecessary.
If you still have trouble with sprout, I'd suggest you ask a separate question and show us what you tried. We may able to help you...