I have each patch holding two lists: directions and magnitudes. Both lists contain values that are computed based on nearby turtles:
directions contains the headings from the patch to the various turtles (so basically it is just the turtle's heading rotated by 180°);
magnitudes contains a value that is directly proportional to the turtles' mass and inversely proportional to the distance between the patch and the turtles;
The items of the two lists are coupled in their order, i.e. the first item of directions and the first item of magnitudes are computed based on the same turtle, the two second items are computed based on another turtle and so on.
What I want to achieve is to come up with two single patch-own values, my-direction and my-magnitude, representing in some way the weighted average of directions, where the weights are magnitudes.
To put it another way, I am thinking of this in terms of vectors: turtles are exerting on the patch a force that can be represented as a vector, always pointing in the direction of the turtle and with a certain intensity (the magnitude). The resulting vector (represented by my-direction and my-magnitude) should be the resulting average of these forces.
I have seen this question. It does not address the issue of a weighted average; however it mentions the concept of circular mean. I've delved into it a bit, but I'm not sure how to apply it to my case and even if to apply it: does it still apply even with the formulation of the problem in terms of vectors?
I've seen this question/answer on SE Mathematics where it is said that the average vector can be found by averaging x- and y-coordinates of the initial vectors. In my case, ideally all the pairs of values in the two lists form a different vector with origin in the patch at issue, with heading found in directions and length found in magnitude. I suspect I can find the coordinates of each vector by multiplying its sine and cosine by its magnitude, however at this point I'd use some guidance as I might be overcomplicating things (either from the maths perspective or the NetLogo perspective).
This one below is a reduced version of the code that brings to the point where target-patches (not focusing on all patches, in order to make it quicker) have the two lists populated.
globals [
target-patches
]
turtles-own [
mass
reach
]
patches-own [
my-direction
my-magnitude
directions-list
magnitudes-list
]
to setup
clear-all
set target-patches n-of 10 patches
ask target-patches [
set directions-list (list)
set magnitudes-list (list)
set pcolor yellow + 3
]
create-turtles 10 [
move-to one-of patches with [(not any? turtles-here) AND (not member? self target-patches)]
set mass (random 11) + 5
set reach (mass * 0.8)
set size (mass / 8)
set shape "circle"
]
populate-lists
end
to populate-lists
ask turtles [
let relevant-targets (target-patches in-radius reach)
ask relevant-targets [
set directions-list lput (towards myself) (directions-list)
set magnitudes-list lput (magnitude-based-on-distance) (magnitudes-list)
]
]
end
to-report magnitude-based-on-distance
report [mass] of myself / (distance myself * 1.2)
end
Your initial instinct is right. You can do something like
LET my-dx mean (map direction magnitude [ theta scalar -> scalar * sin theta ])
(I may have that map and anonymous syntax wrong please edit)
And do the same for my-dy using cos (edit: or maybe negative cos?)
patch-at my-dx my-dy is one way of getting the patch.
You can also do (atan my-dx my-dy) to gets the new direction
And distancexy my-dx my-dy to get the magnitude
Don’t remember if patch can use distancexy or patch-at, but hopefully so. Otherwise you have to use a helper turtle, and do the math yourself.
I think I did a orbital mechanics toy model once that did something like this. It’s hiding on turtlezero.com.
Related
I have the set of points implemented in netlogo and agents are moving from one point to another. Each point has a weight (number approximately between 0 and 9, its not a probability). What I want to made is a simple rule.
I want to give all points probability of visit by the value of weight.
So the next point which will be visited by agent should be calculated by the probability based on point weight and the closeness point (more close point - bigger probability), but that closeness isn't so much big factor as the point weight. For example, I would like to set in formula that closeness is twice lower factor then point weight.
I investigated rnd extension, but I am not sure how to append probabilities to points which I am having a lot (approximately around 250 points).
You're on the right track with the rnd extension. From that extension you need the weighted-one-of primitive and you just put the formula into the reporter block.
I think this is something like what you want. It's a complete model so you can run it and see what it does. The reporter block uses the weight and the distance in the probability. Since you want the probability to be larger for closer, then I have used the inverse of the distance, but you could simply subtract the distance from something like the maximum distance in the model. You will also need an appropriate scaling factor (replacing the 10 in my example) so that the weight is worth twice an average value of closeness.
extensions [rnd]
turtles-own [weight]
to testme
clear-all
create-turtles 10
[ setxy random-xcor random-ycor
set weight 1 + random 3
set size weight
set color blue
]
ask one-of turtles
[ set color red
let target rnd:weighted-one-of other turtles [ 2 * weight + 10 / distance myself ]
ask target [ set color yellow ]
]
end
I am building a model that tries to simulate a network-based market. In this model the turtles/nodes get a reward called points, which is a turtles-own variable.
I am now trying to plot a graph of the degree of the nodes against the average number of points that nodes with a given degree have. I have attempted to do this by creating a plot from the interface tab but I cannot manage to make this work.
Here are images of the windows of the plot settings.
Anybody know how can I make this work?
Also, I keep getting these "Runtime error: Can't find the maximum of an empty list" in all the plots/histograms I create. It is not a big deal at the moment as they seem to work fine, however if you know why these appear please let me know!
Thanks beforehand,
Carlos
For simplicity and to avoid overloading your plot setup, I like to use to-report procedures for things like this. As a quick example try this setup:
turtles-own [ points degree ]
to setup
ca
crt 50 [
set degree 5 + random 5
set points random 10
setxy random-xcor random-ycor
]
reset-ticks
end
Make a to-report each for a list of existing degrees, the average points of turtles that have each degree, and the maximum of those average point values:
to-report degrees-list
report sort remove-duplicates [degree] of turtles
end
to-report avg-points-list
let avg-list map [ i ->
mean [points] of turtles with [ degree = i ]
] degrees-list
report avg-list
end
to-report max-avg
report precision ( max avg-points-list + 1 ) 2
end
In this example, degrees-list reports [ 1 2 3 4 5 ], avg-points-list reports something like [6.5 3.9285714285714284 6 3.75 4.2], and max-avg reports something like 7.5- note that of course the exact values will vary since the setup is random.
Now, you can set up your plot window:
The actual plotting is handled by the foreach primitive in the plot pen, which uses plotxy to plot the point value in avg-points-list against the corresponding value in degrees-list. Should give a plot that looks something like:
Hope that's sort of what you're after!
I wish to draw an arrow at the top turtle representing a vector denoted by
[x1,y1] . The vector is of unit magnitude and the size of the arrow should not exceed that of the turtle.
The vector is stored in a list with two elements.
I don't wish to use the shape editor in netlogo to shape as arrow and then point the turtle in the heading denoted by the vector. The reason being I could draw one than 1 arrows for each turtle.
Edit:
Desired:
Bryan's answer gives the following:
Edit 2:
Video link : https://www.youtube.com/watch?v=9SVcLg4Oyoc&t=23 for better explanation.
Here's how I'd do it:
Make sure your turtles are all of one breed, say, particles, or whatever they represent. Create another turtles breed called vectors or something. These turtles are going to be the tip of your vectors but you'll use links to actually visualize the vectors. Now, you can create the vectors like so:
ask particles [
hatch-vectors 1 [
create-link-from myself
hide-turtle
]
]
To update the position of the vectors (given that the vector itself is stored in a turtle variable vec), you can do:
ask particles [
let abs-x xcor + first vec
let abs-y ycor + last vec
;; Since the particle is linked to the vector by a directed link, it's an out-link-neighbor
ask out-link-neighbors [ setxy abs-x abs-y ]
]
Edit in response to update:
That's tougher, since link shape editing is more limited than turtle shape editing. One possibility would be to set the shape of the vector turtles to an arrow head (you could either create a new such shape, or the default turtle shape could suffice). Rather than hiding the vectors, you'd then point them in the right direction. This can easily be done by having them face their link-partner and then turn around.
You may also want to switch from directed to undirected links to get rid of the arrow in the link itself. This should only involve minor code changes.
Given:
The wall(grey agents) are in a constant place along the top of the
world.
The blue agents always directly below but at various
distances. But they be off to the side of the gap but nevertheless
can be rotated so that they face the gap.
That the cone of vision angle is same for all blue turtles.
In the above figures, the blue agent's cone of vision is depicted. I wish to calculate the grey wall which meet the ends of the cone of vision ,that is, one on right and one on left.Also could I somehow calculate the x-coordinate at that point. Not the grey agent's coordinate as that would be a approximation.
To Compute:
The x coordinates where the extremes of cone of vision intersect grey turtles. Or those grey turtles they intersect.
Rough Figure:
So I wish to compute x_1 and x_2 in the below figure.
One way could as suggested by #JenB to divide it into three cases and and calculate A in each case.(Primarily on left or right). Then use trigonometry. I am correct. Are there any other ways as well?
If this is a 2D problem, it is simply a case of intersecting lines.
I would avoid using multiple cases; that is very prone to errors.
You will have a line that describes your wall of turtles, and two lines that describe your FOV boundaries. You can formulate each of these three lines in parametric form as [o.x,o.y] + [v.x, v.y] * s, which is a fixed point [o.x,o.y] plus a normal vector [v.x,v.y] scaled by s.
The wall of turtles is only defined for a certain domain of 's'; let's say domain of wall.s = [0 to 0.4, and 0.6 to 1]
I would describe how to find the intersection points, but intersections of parametric 2D lines is pretty standard fare, and is better shown in a PDF, so I'll refer you to this...
http://www.ahinson.com/algorithms_general/Sections/Geometry/ParametricLineIntersection.pdf
(remember never to divide by zero)
Once you know the values of the scale parameters 'left.wall.s' and 'right.wall.s', you can tell whether the domain of the turtle wall is within the view of the player. Also you can determine the intersection points simply by plugging back into the parametric line formulas.
dwn's answer covers computing the precise point of intersection.
You said you were also interested in just finding out what patch the answer lies on. Here's code for that:
to setup
clear-all
create-turtles 1 [
set heading -30 + random 60
]
ask turtles [
;; show center of vision cone
ask boundary-patch [ set pcolor red ]
;; show edges of 20 degree vision cone
lt 10
ask boundary-patch [ set pcolor blue ]
rt 20
ask boundary-patch [ set pcolor blue ]
;; restore turtle's original heading
lt 10
]
end
;; answers the question, what patch on the top row of the
;; world is the turtle currently facing?
to-report boundary-patch ;; turtle procedure
let n 0
while [true] [
let target patch-ahead n
if target = nobody or [pycor = max-pycor] of target [
report target
]
set n n + 1
]
end
Sample result:
Of course, it would actually be computationally more efficient to compute the answer directly, via a formula. (With an optional rounding step at the end, depending on whether you want a point or a patch.) But this code shows how to do it without having to do any tricky math.
The following trigonometry approach(suggested by #JenB) works perfect:
to-report calx2 [x0 y0 x1 y1 A]
report x0 + (y1 - y0) * tan ( A + atan (x1 - x0) (y1 - y0))
end
to start
ask turtles[
set corner-1 list calx2 xcor ycor ([pxcor] of patch-goal)([pycor] of patch-goal - 0.4) (-45) ([pycor] of patch-goal - 0.4)
set corner-2 list calx2 xcor ycor ([pxcor] of patch-goal)([pycor] of patch-goal - 0.4) ( 45) ([pycor] of patch-goal - 0.4)
]
The problem just arises when the left edge goes beyond 180 and right edge go beyond 0. I didn't consider that cases. Anyways, the above code solves the problem.
I would like to build least-cost paths between the polygon (e.g. polygon A) where there is a wolf and all polygons that are situated in a radius of 3 km around the wolf and to found the polygon that has the lowest cost (see also How can I increase speed up simulation of my least-cost path model. Then, the wolf moves toward this polygon (e.g. polygon B). The process is repeated from the polygon B and so forth.
to-report path-cost
ask wolves [
set my-list-of-polygons-in-buffer ( [plabel] of patches in-radius 3 )
set my-list-of-polygons-in-buffer remove-duplicates my-list-of-polygons-in-buffer
set my-list-of-polygons-in-buffer remove [plabel] of patch-here my-list-of-polygons-in-buffer
set my-list-of-polygons-in-buffer remove "" my-list-of-polygons-in-buffer
foreach my-list-of-polygons-in-buffer [
let ID-polygon-in-buffer ?
ask patches with [plabel = ID-polygon-in-buffer] [
set path-cost calculate-LCP [my-ID-polygon] of myself ID-polygon-in-buffer] ] ]
report [plabel] of (min-one-of patches [path-cost])
end
1) From the polygon A, the code works because only the polygons in the buffer have a path cost. But from the polygon B, there is a problem. The code finds the polygon that has the lowest cost among polygons that are situated in the buffer of polygon A and in the buffer of polygon B. The code has to find only the polygon that has the lowest cost among polygons in the buffer of polygon B. How can I resolve this problem? Have I to reset the state variable “path-cost” for each polygon patch before to calculate path cost from polygon B?
ask patches [
set path-cost 0 ]
2) If a same polygon is included in the buffer of both three wolves, how the path cost will be assign to state variable "path-cost" for each patch polygon i.e. is it possible to have 3 x cost value for a same polygon ?
3) In the figure below, why does the least-cost path not follow a straight line? The least-cost path takes the patch diagonal instead of the patch side that is shorter.
Thank you very much for your help.
I'm going to answer your questions in reverse.
3) As Seth mentioned, this is a separate question. That said, here's the answer. By default, all links cost the same amount. That is, diagonal links cost the same amount as horizontal links. Thus, there's no reason to prefer the horizontal links over the diagonal ones. The cost is actually the same. You can use link weights to resolve this. Just make a new link variable (cost or something), set it to the length of the link, and then ask for the shortest weighted path using that variable.
2) Not really. You could set path-cost to a list that contains the values for the different wolves, but I wouldn't recommend. I don't think using a patch variable is the right way to go here.
1) You would have to set path cost to 0, but there's a better way. Also, your procedure only returns the least cost path for the last wolf run (since the wolves keep overwriting the patch variables).
First, I think that you actually want path-cost to be a wolf procedure (I would also name it something like least-cost-polygon as it's actually reporting a polygon). That is just, it just gives the nearest polygon for a wolf. So here is a simplified version that does that and doesn't store anything in any patch variables (thus avoiding collision because nothing is overwritten):
to-report least-cost-polygon
[ plabel ] of min-one-of patches in-radius 3 with [ plabel != [plabel] of myself ] [
calculate-LCP [ my-ID-polygon ] of myself
]
end
Yes
If only one wolf is computing costs at a time, then there's no problem. After one wolf has finished, that wolf's values for path-cost aren't needed anymore, so it's OK for the next wolf to overwrite them. Right? If it's not OK — if you have a need to keep the information around for later — then I'd suggest using links to store it; that's the usual way of storing many-to-many information in NetLogo.
Your questions 1 and 2 are about the same issue, but this is something entirely different. Please ask one question at a time. In any case, it doesn't seem to me like we can possibly debug this for you with the information we have. Apply standard debugging techniques.