Making turtles wait x number of ticks - wait

Part of what I am trying to do is make a breed of turtles move around, but when one reaches its destination that turtle waits for a certain number of ticks before continuing ? Also is it possible to make turtles wait for different number of ticks depending upon their destination ( different patch colors). Is it a case of making a turtle breed or global variable to count the number of ticks? The hopefully relevant code is below.

You are right, this can be done by making the turtles count the number of ticks they have been on a patch. Also this has to be a turtle variable and not a global variable since each turtle will have a different value for this
The approach, I have used is this:
Once the turtle arrives at its destination record the ticks (the global variable which records the number of ticks that have passed till now) into a turtle variable say ticks-since-here. This works like a time-stamp.
On each successive tick check the difference between the current-time ticks global variable and the ticks-since-here turtle variable. If this becomes greater than the number of ticks the turtle is allowed to stay on the patch, let it choose and move to the new destination.
breed [visitors visitor]
globals [ number-of-visitors ]
visitors-own [
; visitors own destination
destination
ticks-since-here
]
to go
ask visitors [
move
]
tick
end
to move
; Instructions to move the agents around the environment go here
; comparing patch standing on to dest, if at dest then choose random new dest
; then more forward towards new dest
ifelse ( patch-here = destination )
[
if ticks - ticks-since-here > ticks-to-stay-on-patch patch-here
[
set ticks-since-here 0
set destination one-of patches with
[
pcolor = 65 or pcolor = 95 or pcolor = 125 or pcolor = 25 or pcolor = 15 or pcolor = 5
]
]
]
[
face destination
forward 1
if ( patch-here = destination )
[
set ticks-since-here ticks
]
]
end
to-report ticks-to-stay-on-patch [p]
if [pcolor] of p = 65
[
report 6
]
if [pcolor] of p = 95
[
report 5
]
if [pcolor] of p = 125
[
report 4
]
if [pcolor] of p = 25
[
report 3
]
if [pcolor] of p = 15
[
report 2
]
if [pcolor] of p = 5
[
report 1
]
end
to setup-people
;;;; added the following lines to facilitate world view creation
ask patches
[
set pcolor one-of [65 95 125 25 15 5]
]
set number-of-visitors 100
;;;;
create-visitors number-of-visitors
[
ask visitors
[
; set the shape of the visitor to "visitor"
set shape "person"
; set the color of visitor to white
set color white
; give person a random xy
setxy (random 50) (random 50)
; set visitors destination variable
set destination one-of patches with
[
pcolor = 65 or pcolor = 95 or pcolor = 125 or pcolor = 25 or pcolor = 15 or pcolor = 5
]
]
]
end

Related

how do I input number into a NetLogo plot?

I understand that this formula is super complicated to read, but I guess that the mistake that I'm making is super simple. This is a plot for dissimilarity index for segregation for two districts. The error is "missing value on the left"
plot (
mod (((count turtles with [ditrict-in = "high" color = blue])/ count turtles with [ color = blue ]) -
((count turtles with [ditrict-in "high" color orange])/ count turtles with [ color = orange ]))
+ mod(((count turtles with [ditrict-in = "0" color = blue])/ count turtles with [ color = blue ]) -
((count turtles with [ditrict-in = "0" color = orange])/ count turtles with [ color = orange ]))
)
You have a few errors in your code. The message you're seeing is from the mod operator. You're using mod as if it takes a single argument to the right like mod 10. But if we look at the docs for mod what we find is that mod works like a mathematical operator (+ or -) and takes one argument on the left and one on the right. 15 mod 4 gives 3. So at this point I'm not 100% sure what you want the mod operator to be doing, so I'll leave it to you to adjust how it's used (or maybe you want a different operator).
You also are missing some and operators and = checks in your code, too, though. Sometimes when I'm having trouble tracking down issues, I'll split out complex expressions into their pieces to make it easier to see what's going on. Here is how I split up your code, which still gives the error as you'll need to change the mod portion.
let blueCount (count turtles with [ color = blue ])
let orangeCount (count turtles with [ color = orange ])
let highBlueCount (count turtles with [ditrict-in = "high" and color = blue])
let highOrangeCount (count turtles with [ditrict-in = "high" and color = orange])
let zeroBlueCount (count turtles with [ditrict-in = "0" and color = blue])
let zeroOrangeCOunt (count turtles with [ditrict-in = "0" and color = orange])
plot (
mod ((highBlueCount / blueCount) - (highOrangeCount / orangeCount))
+ mod ((zeroBlueCount / blueCount) - (zeroOrangeCOunt / orangeCount))
)

Breaking out of a recursive function

I'm walking through a set of nested blocks and want to stop the walk when I've found the value I'm looking for.
For reasons that are beyond the scope of this question, I can't use PARSE for this particular problem, nor use FOREACH as the looper:
walk: func [series [block!] criteria [block!]][
use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
I'd like to break out if I find this specific value.
walk [a [b c [d e] f] g] [if value = 'e [return value]]
; returns 'e
However, I'd also like to do operations that don't break out:
walk [a [b c [d e] f] g] [
collect [if find [c e] value [keep value]]
]
; returns [c e]
Would like to try and solve this for any of the Rebol flavours including Red. Any thoughts as to efficiency (reason I use a block instead of a function), etc. would be welcome too.
The function combo I was looking for is CATCH/THROW. Once again, using the given function:
walk: func [series [block!] criteria [block!]][
use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
I can simply wrap it as follows:
catch [walk [a [b c [d e] f] g] [if value = 'e [throw value]]]
; returns 'e
Some Notes
I want the function to return NONE if there are no matches
I'll just have WALK return NONE (am using ALSO just so as not to leave an awkward trailing none):
walk: func [series [block!] criteria [block!]][
also none use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
red does not have a USE function
This introduces a complication as I only want to bind the block to the word VALUE. If I were to rewrite the function as follows:
walk: func [series [block!] criteria [block!] /local value][
do bind compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
] 'value
]
Then it also binds that same block to the words SERIES and CRITERIA which would override the binding of any such words from the calling context, e.g.:
walk [some values][series: none probe value] ; results in error
This version avoids binding anything except VALUE and works in Red 0.6.3 and Rebol2:
walk: func [series [block!] criteria [block!]][
also none do bind compose/deep [
while [not tail? series] [
value: pick series 1
either block? value [
walk value criteria
] [
(to paren! criteria)
]
series: next series
]
]
context [value: none]
]
(Comments on how this implementation differs from what USE does would be welcome.)
And yes, this does not work on Rebol3 Alpha. But neither does the one with the USE. I think it's a THROW issue.

Graph branch decomposition

Hello,
I would like to know about an algorithm to produce a graph decomposition into branches with rank in the following way:
Rank | path (or tree branch)
0 1-2
1 2-3-4-5-6
1 2-7
2 7-8
2 7-9
The node 1 would be the Root node and the nodes 6, 8 and 9 would be the end nodes.
the rank of a branch should be given by the number of bifurcation nodes up to the root node. Let's assume that the graph has no loops (But I'd like to have no such constraint)
I am electrical engineer, and perhaps this is a very standard problem, but so far I have only found the BFS algorithm to get the paths, and all the cut sets stuff. I also don't know if this applies.
I hope that my question is clear enough.
PS: should this question be in stack overflow?
From your example, I'm making some assumptions:
You want to bifurcate whenever a node's degree is > 2
Your input graph is acyclic
With an augmented BFS this is possible from the root r. The following will generate comp_groups, which will be a list of components (each of which is a list of its member vertices). The rank of each component will be under the same index in the list rank.
comp[1..n] = -1 // init all vertices to belong to no components
comp[r] = 0 // r is part of component 0
comp_groups = [[r]] // a list of lists, with the start of component 0
rank[0] = 0 // component 0 (contains root) has rank 0
next_comp_id = 1
queue = {r} // queues for BFS
next_queue = {}
while !queue.empty()
for v in queue
for u in neighbors(v)
if comp[u] == -1 // test if u is unvisited
if degree(v) > 2
comp[u] = next_comp_id // start a new component
next_comp_id += 1
rank[comp[u]] = rank[comp[v]] + 1 // new comp's rank is +1
comp_groups[comp[u]] += [v] // add v to the new component
else
comp[u] = comp[v] // use same component
comp_group[comp[u]] += [u] // add u to the component
next_queue += {u} // add u to next frontier
queue = next_queue // move on to next frontier
next_queue = {}

Increasing distance between subgraphs

I have the following code:
digraph g {
graph [rankdir="LR" ,compound="true" ];
subgraph cluster0 {
graph [label="Ready\n\nAllowed Purchaser Operations:\noperation1,operation2\n\nAllowed Supplier Operations:\noperation1,operation3" ];
1 [ shape="none" ,fontcolor="white" ];
};
subgraph cluster2 {
graph [label="Paused\n\nAllowed Purchaser Operations:\noperation1,operation3\n\nAllowed Supplier Operations:\noperation2,operation3" ];
3 [ shape="none" ,fontcolor="white" ];
};
subgraph cluster4 {
graph [label="Completed\n\nAllowed Purchaser Operations:\noperation4\n\nAllowed Supplier Operations:\noperation4" ];
5 [ shape="none" ,fontcolor="white" ];
};
1 -> 3 [ ltail="cluster0" ,lhead="cluster2" ,comment="6" ];
1 -> 5 [ ltail="cluster0" ,lhead="cluster4" ,comment="7" ];
3 -> 1 [ ltail="cluster2" ,lhead="cluster0" ,comment="8" ];
3 -> 5 [ ltail="cluster2" ,lhead="cluster4" ,comment="9" ];
}
I want to increase the distance between the subgraphs. I've tried using len, margin, pad, but the syntax I've tried doesn't work. Can somebody help me?
I think what you are looking for (as Emden points out) are indeed the nodesep and ranksep attributes.
graph [nodesep=6, ranksep=4];
The result would be:
Clusters are derived objects; their layout depends solely on the nodes contained in them. Thus, to alter the cluster spacing, you need to alter the node spacing. Try setting the ranksep and nodesep attributes to larger values.

How to control the space between boxes in rebol draw?

Question update: I'm almost there, just missing dotted line style for the grid.
grid: [1100 600]
step-grid: 5
max-n-points: grid/1 / step-grid
x-axis-border: 20
Y-margin: 10
max-random: 1000
n-points: 300
get-random-data: func[n p][
block: copy []
repeat i n [
append block RANDOM p
]
block
]
get-extremes: func[block][
extreme: none
foreach element block [
if none? extreme [
extreme: copy []
repeat i 2 [append extreme element]
]
if element > extreme/1 [
extreme/1: element
]
if element < extreme/2 [
extreme/2: element
]
]
extreme
]
data0: get-random-data n-points max-random
extremes: get-extremes data0
height: extremes/1 - extremes/2
ratio: (grid/2 - x-axis-border - (Y-margin * 2)) / height
data: copy []
foreach element skip data0 (n-points - max-n-points) [
append data to-integer (ratio * element)
]
plot: copy []
color: 0.0.0
append plot [
pen green line
]
x: 0
foreach y data [
append plot as-pair x (grid/2 - x-axis-border - Y-margin) - y
x: x + 5
]
main: layout [
origin 20x0
space 1x1
panel1: box 1100x580 black effect reduce [
'line-pattern 4 4
'grid 30x30 0x0 200.200.200
'draw plot
]
panel2: box 1100x0 black
panel3: box 1100x20 black
]
view main
=== former question
The space between each box is too big and I cannot draw dotted grid, how to do this ?
plot: copy []
color: 0.0.0
append plot [line-pattern 4 4]
repeat x 400 [
repeat y 200 [
append plot compose [
box (xy: 25 * as-pair x - 1 y - 1) (xy + 25)
]
]
]
main: layout [
origin 0x0
panel1: box 800x400 black effect reduce ['draw plot]
panel2: box 800x180 black
panel3: box 800x20 black
]
view main
use the space keyword to control spacing
See http://www.rebol.com/docs/view-guide.html#section-29
Also, you can use the 'grid for drawing a grid
"grid Generate a two dimensional grid of lines. This is a useful backdrop for graphical layout programs. The optional arguments are: a PAIR that specifies the horizontal and vertical spacing of the grid lines, a PAIR that specifies the offset of the first lines, a PAIR that indicates the THICKNESS of the horizontal and vertical lines, and a TUPLE that provides the color of the lines."

Resources