A social network of agents of different ages is set up in NetLogo similarly to the following, which results in a circle of agents connected by links. The overall purpose of these links is to represent contact between those links. The model simulates the spread of infection through the network. Agents begin as susceptible, with the possibility of becoming infected if they come into contact with an infectious link neighbour. I want to model for example the isolation or quarantine of an infected individual. i.e. their links to others would be deactivated completely or at least the majority of their links would be deactivated. Ideally I'd press a button on the observer interface to deactivate the links of infected agents. I'd also like to be able to model the closure of a school for instance whereby the majority of toddlers and children and their connections between each other would be deactivated, stopping the ability of infection between children. Their links to adults should probably remain open if fewer of them, though it may be better to just focus on links between one breed at a time for now.
breed [ toddlers toddler ]
breed [ children child ]
breed [ adults adult ]
breed [ over45s over45 ]
globals
[
num-nodes
num-infected
num-susceptible
prob-infection-toddler
prob-infection-child
prob-infection-adult
prob-infection-over45
force-of-infection
]
turtles-own
[
temp-infected? ;; temporary infected state
infected? ;; true if agent has been infected
susceptible?
num-infected-neighbors
]
links-own
[
closed?
]
to setup
clear-all
create-toddlers 20
create-children 20
create-adults 20
create-over45s 20
create-network
reset-ticks
layout-circle (sort turtles) max-pxcor - 8
ask turtles
[
facexy 0 0
if who mod 2 = 0 [fd 4]
]
ask turtles
[set susceptible? true]
ask one-of turtles
[
set infected? true
set susceptible? false
set color red
]
display
end
to create-network
let connexions (list
(list toddlers toddlers 5)
(list toddlers children 2)
(list toddlers adults 2)
(list toddlers over45s 1)
(list children toddlers 3)
(list children children 8)
(list children adults 5)
(list children over45s 1)
(list adults toddlers 1)
(list adults children 3)
(list adults adults 6)
(list adults over45s 3)
(list over45s toddlers 1)
(list over45s children 1)
(list over45s adults 5)
(list over45s over45s 5)
)
foreach connexions [
let source-breed item 0 ?
let target-breed item 1 ?
let num-connexions item 2 ?
let reverse-num-connexions item 2 first filter [
item 0 ? = target-breed and item 1 ? = source-breed
] connexions
ask source-breed [
repeat num-connexions [
let possible-targets other target-breed with [
(not member? myself link-neighbors) and
(count link-neighbors with [ breed = source-breed ] < reverse-num-connexions)
]
let target one-of possible-targets
if target != nobody [ create-link-with target ]
]
]
]
ask links [set closed? false]
end
to spread
;;; there is one of these for each age group as they have different probabilities for infection
ask toddlers with [ susceptible? = true ]
[
;;tried changing to something like this but this is the line that throws up an error
ask my-links with [closed? = false][
set num-infected-neighbors count (link-neighbors with [infected? = true])
]
;;should only include active links
set force-of-infection (prob-infection-toddler) ^ num-infected-neighbors ;;paraphrased equation but num-infected-neigbours is important
if ( random-float 1 <= force-of-infection) ;; infect with probability p
[
set temp-infected? true
set susceptible? false
]
]
ask turtles with [temp-infected? = true]
[
set infected? true
set temp-infected? false
]
end
to isolate-infected
;;for all infected individuals deactivate their links
end
to close-schools
ask toddlers
[
ask my-links [set closed? true]
]
end
to close-offices
;; e.g cut the number of links between adults and so on
end
As you can see there are two problems here, one being the deactivation (ideally they could be turned on again once school closures are over or once an infected individual recovers for example) of links based on what state the end nodes are in or the breed that they are.
And the second problem of counting the number of infected link-neighbours without including the links which are deactivated. Hiding a link does not stop it from existing it just becomes invisible and thus doesn't stop the contact. I've also considered simply changing the color of the deactivated links to for example black. Is there a way in which I can rewrite the counting of infected neighbors to count only links that aren't black or hidden for example set num-infected-neighbors count (link-neighbors with [infected? = true]
...and link hidden? = false.... or link-color "!=" black? )
I feel the second problem is probably the easier of the two but I may be mistaken. I've hit too many brick walls at this stage and my head is fried on the matter. Any help would really be greatly appreciated. Thanks for your time reading this already, I realise it was a bit of a rant :) Thanks again to Nicolas Payette for his help previously
EDIT: Added links-own boolean for closed?
Tried to alter the section which counts the number of infected neighbours on open links but I get the error
this code can't be run by a link
error while link 14 15 running SET
called by procedure SPREAD
called by Button 'Spread'
Also added in a function in "to close-schools" which gives a very basic closure of all toddlers links by setting closed? to true
Edit: Would this be a possible solution here
set num-infected-neighbors 0
ask my-links with [closed? = false][
ask other-end [if (infected?) [set num-infected-neighbors num-infected-neighbors + 1 ]]
]
set force-of-infection 1 - (1 - prob-infection-adult) ^ num-infected-neighbors
Edit: num-infected-neighbors should be a turtles-own
variable as far as I can tell, but when I put a watch on a turtle and run the simulation, the num-infected-neighbors that a turtle has seems to consistently surpass the actual number of link-neighbors that the turtle has. It is also just wrong. I can't see why though....
Edit:
let infectnum 0
set num-infected-neighbors 0
ask my-links with [closed? = false][
ask other-end [if (infected?) [set infectnum infectnum + 1 ]]
;;set num-infected-neighbors count (link-neighbors with [infected? = true])
]
set num-infected-neighbors infectnum
doesn't seem to be working properly either...
Edit: For future reference problem was solved by -
set num-infected-neighbors length filter [[infected?] of ?]
[other-end] of my-links with [not closed?]
First a list is formed of the link-neighbors on not-closed links, then that is filtered to give just the infected ones. num-infected-neighbors is the length of that list