I have n turtles which all have links with one another. That means I posses a complete directed weighted graph. I've managed to locate the links with maximum value per each turtle, but now I want to delete all other links without maximum value, again per each turtle.
I'm using the [die] function but in order to distinguish the set of links per each turtle and then clear links from each set
This is the line of code I'm using:
> ask turtles
[
> ask my-in-links with [trust < max [trust] of links with [other-end] = ] [die]
]
However, I thought instead of using other-end function I could also use this line of code
> ask turtles [
ask my-in-links with [trust < max [trust] of links with [out-link-to] = ] [die]
]
My initial thought was by using one of the two functions (other-end/ out-link-to), I could create a common attribute between the set of links.
My main problem is
I'm not sure whether the functions (other-end/ out-link-to) are correct
I don't know what to write after the "=" expression
I don't know which turtle the ask turtle function begins to work with
Here's a complete model that does what you are trying to achieve.
links-own [trust]
to testme
clear-all
; create complete directed network
create-turtles 10
ask turtles
[ create-links-to other turtles
[ set trust random 50
]
]
; display complete network briefly
layout-circle turtles 10
type "average trust value is: " print mean [trust] of links
wait 5
; delete all except highest trust for each turtle
ask turtles
[ let keeper my-in-links with-max [trust]
ask my-in-links with [not member? self keeper][die]
]
type "average trust value is: " print mean [trust] of links
end
I have it showing the initial network and printing average trust values so you can see what's going on.
The important concept here is that my-links is an agentset (in particular, it's a linkset because the agents in the set are links). Since what you're trying to do is just look through the links that are connected to one turtle, then it doesn't matter which turtles are at the other end and you don't need to refer to the other end at all.
You can simply look at the set of links that attach to the particular turtle (my-in-links or my-links or my-out-links) and then look at the values of trust for those links. I have used with-max to find the one with the highest value and then used set membership. But you could also use
ask turtles
[ let upper max [trust] of my-in-links
ask my-in-links with [trust < upper] [die]
]
which is closest to the code you wrote in your question.
Related
In this example I am trying to make two directed-link-breed links based on turtles-own Value. The condition is as follows ask turtles to link to other turtles who have a smaller Value than me.
directed-link-breed [active-links active-link]
turtles-own [ Value ]
to setup
crt 100 [setxy random-xcor random-ycor set value random 500]
ask turtles [ create-active-links-to min-n-of 2 other turtles [Value < myself] ][set links to have xxxxx ]
end
when I do the following:
ask turtles [ create-active-links-to min-n-of 2 other turtles with [value < [ value ] of myself ] [set links to have xxxxx ]
I am getting the following error:
Requested 3 random agents from a set of only 2 agents.
error while turtles 8 running N-OF
called by procedure GO
called by Button 'go'
That message is telling you that (for the particular lettuce), there were only two that satisfied the criteria, but you wanted to link with 3 of them. Looking at your question, you want turtles to send links to turtles with lower values of a specific variable. What do you want the turtle with the lowest value of that variable to do? Clearly it can't link to lower valued turtles because there aren't any.
I'm also not clear why you are using min-n-of. Do you want to link to the lowest valued turtles (in which case every turtle will send links to the same few turtles) or do you want to link to randomly selected turtles with lower values (in which case turtles with higher values will have more choices)?
There are a couple of ways you can handle this once you have the logic sorted out. If you definitely want the lowest value, then use min-n-of first to find the candidates, then link to any with a lower value than the asking turtle. If you want to randomly select from a potentially larger group, use up-to-n-of instead of n-of. Or you could count the number found before trying to link to make sure there's enough.
I have a complete directed graph with each link a weight of it's own. I've managed to select the max-out-link of every turtle. But, sometimes the max-out-link of two turtles are opposite of each other resulting in both links opposite of one another being selected. if this happens i want the link with the lower value to die.
i have created the two lists with this:
set max-end1 [[end1] of max-one-of my-out-links [trust]] of turtles
set max-end2 [[end2] of max-one-of my-out-links [trust]] of turtles
and by setting an x and y parameter like so:
ask turtles
[
set x max-one-of my-out-links [label]
set y my-in-links
]
i was hoping to compare each item of the two lists like so:
if [x] of max-end2 = any? [y] of max-end1
[
ifelse x X y
[ask x [die]]
[ask y [die]]
]
but i have no idea how to combine the foreach command with the if command
can someone help me?
I can't actually figure out how your code is supposed to work. Lists seems like an awkward way to approach this and the way you are using any? is not going to work. So, I have instead started again and written a standalone model (put it in an empty NetLogo session) to do what I think you are trying to do.
links-own [ weight ]
to testme
clear-all
create-turtles 15
ask turtles
[ create-links-to other turtles
[ set weight random 100
]
]
layout-circle turtles 10
kill-lowers
end
to kill-lowers
; first remove any that's not a max weight
ask turtles
[ let big-link max-one-of my-out-links [weight]
let dying my-out-links with [not member? self (link-set big-link)]
ask dying [die]
]
; find pairs and make lower turn red
ask links
[ let opp-links links with [end1 = [end2] of myself and end2 = [end1] of myself ]
if any? opp-links
[ ask opp-links [set color red]
]
]
end
The testme procedure just creates a complete network. It then calls the kill-lowers procedure to do the link removal. The first section has each turtle identify its out-link with the largest weight (or randomly selects one if two equally high) and then creates the link-set of all the other links and gets them to die. I think you already have that happening in your code.
So the interesting bit is the section that starts ask links. It randomly runs through all the links (think of it as a foreach except operating on a set of links rather than a list). In turn, for the particular link, the code checks if there is a link in the opposite direction and sets that to the variable named opp-links. The way it checks is to simply see if there is a link that has end2 to be its own end1 and also the other way. end1 is the source of a directed link and end2 is the target.
If there is such a link, it becomes red. That's so you can check the code is doing what you want. After you have tested it, then you have it die instead.
I am trying to create a network that moves through the environment as a "static" unit, i.e. nothing in the simulation changes except the position and orientation of the whole, the position and orientation of the individual turtles relative to one another are fixed by their links. Turtles are connected via undirected links, which are tied and set to tie-mode "fixed".
The problem is that in certain situations the links fail to remain fixed and link-lengths begin to change. Initially I noticed that, where the average network degree is relatively low or the network is a complete graph, the tie primitive works. However, when links were created to produce a graph that is moderately connected the link-lengths between the turtles begins to change. Upon further experimentation I can create a network with the same number of links and turtles but with different configurations i.e. the network structure is different, that sometimes maintain the positions and link-lengths but in other situations fail to do so.
How do I get the network to move as a unit no matter how connected the network is or what the configuration of the network is? See example code below, I have added code at the end where you can run multiple configurations of a network with 6 turtles and 6 links to see the issue for yourself, try running at least a half dozen iterations. Thanks!
this produces a network that moves as a unit
to setup
create-turtles 10
ask turtles [fd 2]
ask turtles [create-links-with other turtles [tie] ]
ask links [set tie-mode "fixed"]
reset-ticks
create-turtles 10
ask turtles [fd 2]
ask turtles [create-links-with other turtles [tie] ]
ask links [set tie-mode "fixed"]
reset-ticks
end
to go
ask turtles [lt 1 fd 1]
end
This produces a network whose links are still tied and set to tie-mode "fixed", but change their link-lengths. The more links that are asked to die, the more the link-lengths change.
to setup
clear-all
create-turtles 10
ask turtles [fd 2]
ask turtles [create-links-with other turtles [tie] ]
ask links [set tie-mode "fixed"]
ask one-of links [die]
reset-ticks
end
to go
ask turtles [lt 1 fd 1]
end
Here is additional code showing a specific instance of link-length change. Please input the seed 659269695 when prompted by the button "use-seed-from-user". Apologies if the code is clunky, first time using random-seed. "Print-lengths" button is to confirm that lengths change.
;USE seed: 659269695
to use-new-seed
let my-seed new-seed ;; generate a new seed
output-print word "Generated seed: " my-seed ;; print it out
random-seed my-seed ;; use the new seed
reset-ticks
end
;; Use a seed entered by the user
to use-seed-from-user
loop [
let my-seed user-input "Enter a random seed (an integer):"
carefully [ set my-seed read-from-string my-seed ] [ ]
ifelse is-number? my-seed and round my-seed = my-seed [
random-seed my-seed ;; use the new seed
output-print word "User-entered seed: " my-seed ;; print it out
reset-ticks
stop
] [
user-message "Please enter an integer."
]
]
end
to setup
clear-all
create-turtles 6
ask turtles [
fd 5
set shape "circle"
set size 1
set color yellow
if count links < 7 [ask one-of turtles [create-link-with one-of other turtles
[tie]]]]
reset-ticks
end
to go
ask turtles [lt 1 fd 1]
end
to print-lengths
print sort-by < [precision link-length 2] of links
end
I slightly revised your code so that the go procedure includes breaking a link. I also got rid of the explicit setting of tie-mode since that is done by setting the link to tie and added a tick so I could plot. So the code looks like this:
to setup
clear-all
create-turtles 10 [fd 2]
ask turtles [create-links-with other turtles [tie] ]
reset-ticks
end
to go
ask one-of links [die]
ask turtles [lt 1 fd 1]
tick
end
As far as I can see, the turtles move as a unit until it fragments with the loss of links.
I added a monitor for mean [link-length] of links, which is what I think you are asking about and also a plot of the same calculation. Yes, it is true that the average link length changes, but remember that the links are not all the same length. If a longer one dies, then the average length will reduce, and if a shorter one dies then the average will increase. The plot wanders a little, but it is basically flat until fragmentation.
I've been trying to write a model where turtles create links with a certain number of other turtles, and for those turtles to create links with the link-neighbors of the turtle that linked to it. Right now, I can get turtles to create links with other turtles, but they don't share the same link-neighbors. I want to end up with little sub-groups of turtles of a certain group size. However, at the moment I can only tell turtles to create a certain number of links, but they don't end up in sub-groups because their link-neighbors don't necessarily share the same link-neighbors. I thought I could ask each turtle to ask their link-neighbors to create-link-with [link-neighbors] of myself. I think this would work, except I get an error saying a turtle can't link with itself. I've tried to change the code so it says to a turtle ask link-neighbors [create-link-with [link-neighbors] of myself with [who != self]], but this doesn't work either.
Here is some of my code:
;group size is 1 + (count link-neighbors)
;preferred-size is a slider, used to alter what group size I want turtles to be in
ask turtles
[if (preferred-size > group-size) and (any? other turtles in-radius 1 with [preferred-size > group-size])
[create-link-with one-of other turtles in-radius 1 with [preferred-size > group-size]
ask link-neighbors
[create-links-with [link-neighbors] of myself]
]
Also, is there a term like link-neighbors but referring to all the turtles on a string of connections?
Any help would be greatly appreciated!
You were very close! All you need is other:
create-links-with other [ link-neighbors ] of myself
You cannot compare who to self: who is a number and self is a turtle. And in the context of with [ who != self ]], they would always be variables of the same turtle. In any case, it's usually better to avoid dealing with who numbers anyway: there's almost always a better way to do things.
is there a term like link-neighbors but referring to all the turtles on a string of connections?
I'm not entirely sure that's what you mean, but maybe nw:turtles-on-path-to? Or perhaps you will find some other useful thing in the nw extension.
I have a landscape where each patch contains a cost value.
I placed a turtle within each patch according to the following code :
to create-turtles
ask neighbors [ sprout 1 [
set shape "dot"
set size 0.5 ] ]
end
Then, I built a link between each turtle according to the following code :
to create-link-turtles
ask turtles [ create-links-with turtles-on neighbors ]
end
As each patch contains a cost value, I would like to assign a cost value to links between turtles.
For example,
If the link intersects two patches (patches 1 and 2) that have two different costs, the link would be equal to cost in patch 1 + cost in patch 2.
If the link intersects two patches (patches 1 and 2) that have the same cost, the link would be equal to cost in patch 1.
How can I assign a cost value to links between turtles in this way ?
After this, I would like to apply the dijkstra' s algorithm.
Thank you for your help.
Have a good day
Assuming that:
your patches have a cost variable
your links have a link-cost variable
turtles are always connected to turtles on neighboring patches (like in the code you posted)
You can simply :
ask links [ set link-cost sum [ cost ] of both-ends ]
This will just add the costs of the two patches under the turtles at both ends of the link. (If you had links traversing more than two patches, this approach would not work and things would get much more complicated.)
For calculating distances afterwards, I'd suggest you take a look at the NW extension. Its weighted-distance-to primitive uses Dijktra's algorithm internally.