iterate over two lists in NetLogo: Big picture context :R extension. Assign patch values to specific patches from R - r

I need to pass some data to R from NetLogo using the R-extension, do some computations and then assign the R output to specific patches.
I have tried every combination of map and foreach in NetLogo that I can imagine. I have been trying to change colors based on a patch id because it is visible. Setting all of the patches blue works.
observer> foreach [1 2 3] [ x -> ask patches with [id = x] [ set pcolor blue ] ]
When I add the second list nothing I have tried works. I also tried assigning values to the patches to no avail. This turned patches 4, 5, and 6 red...
observer> foreach [4 5 6] [ x -> ask patches with [id = x] [ set pcolor [blue red green] ]]
The next approach did not work.
observer> set list-a (list blue red green)
observer> set list-b (list 7 8 9)
observer> ask patches with [id = list-b] [ set pcolor list-a]
Attempting a foreach with two lists like this:
observer> foreach list-b list-b ask patches with [id = list-b] [set pcolor list-a]
observer> show map list-b list-b ask patches with [id = list-b] [set pcolor list-a]
redefining list-a and then trying the original approach again sets those patches blue.
observer> set list-a r:get "df1[[1]]"
observer> show list-a
observer: [1 5 8]
observer> foreach list-a [ x -> ask patches with [id = x] [ set pcolor blue ] ]
If I could just understand how to work through two lists I would be set.
for example
list-a [1 2 3]
list-b [blue green red]
; effectively do the following
ask patch with [id = 1] [set pcolor blue]
ask patch with [id = 2] [set pcolor green]
ask patch with [id = 3] [set pcolor red]
The actual problem is I have activity variables (all the patches below are planting corn).
> a
id a_corn a_crp a_soy
1 1 0 1 0
2 2 0 1 0
3 3 0 1 0
4 4 0 1 0
5 5 0 1 0
6 6 0 1 0
7 7 0 1 0
8 8 0 1 0
9 9 0 1 0
10 10 0 1 0
>
I know with the r extension dataframes come into netlogo as unnamed nested lists. So if I avoid the nesting by:
set list-id r:get "a$id"
set list-a r:get "a$a_corn"
; then netlogo iterates through the lists:
ask patch with [id = 1] [set a_corn 0]
ask patch with [id = 2] [set a_corn 0]
; and so on
I am open to suggestions for better ways. But the ids need to match, may not be sequential, and the a dataframe above will vary in size and contents.
UPDATE:
As I continue working the problem I am documenting the steps here so I can find them later.
I have found anonymous-commands.
observer> set procedure [[x y] -> ask patches with [id = x] [set pcolor y]]
observer> show is-anonymous-command? procedure
observer: true
observer> set list-a (list blue red green)
observer> set list-b (list 7 8 9)
observer> (foreach list-b list-a procedure) ; does nothing
I cleared all, set up again and the following worked:
observer> ask patches with [id = 7] [set pcolor red]
observer> set procedure [[x y] -> ask patches with [id = x] [set pcolor y]]
observer> set list-b (list 7 8 9)
observer> set list-a (list blue red green)
observer> (foreach list-b list-a procedure)
Now for the application portion of the problem:
observer> set procedure [[x y] -> ask patches with [id = x] [set a_corn y]]
observer> set list-a (list 1 1 1)
observer> (foreach list-b list-a procedure)
and it works!

Related

Jump simple graph path problem, why is it looping?

I want to have x vehicle which goes on a graph going from vertex 1 and ending in the same all vertices as to be seen one time by one and only one vehicle (for those who know, i'm interesting in a PDPTW problem, but i'm stuck at this point)
using JuMP
using Cbc
nbVertex = 5
nbTransp = 2
model = Model(optimizer_with_attributes(Cbc.Optimizer, "seconds" => limiteExec))
set_optimizer_attribute(model, "PrimalTolerance", 1e-9)
print(model)
#les variables de decisions
#variable(model, route[1:nbVertex,1:nbVertex,1:nbTransp],Bin) #if road between 2 vertex is taken by vehic v
#variable(model, object>=0)
#constraint(model, [v in 1:nbTransp],sum(route[1,i,v] for i in 1:nbVertex)==1)#starting at one
#constraint(model, [v in 1:nbTransp],sum(route[i,1,v] for i in 1:nbVertex)==1)#ending at one
#constraint(model, [j=2: nbVertex],sum(route[i,j,v] for i in 1:nbVertex , v in 1 : nbTransp if i != j )==1)
# all vertices as to be seen by one and only one vehicule
#constraint(model, [j=1:nbVertex, v= 1: nbTransp],sum(route[i,j,v] for i in 1:nbVertex if i != j)-sum(route[j,k,v] for k in 1:nbVertex if k != j)==0)
# here is the constraint
#objective(model, Min,object)
#show model
optimize!(model)
for k in 1:nbTransp
dataTmp=Matrix(undef,2,0)
for i in 1:nbVertex
for j in 1:nbVertex
if value.(route[i,j,k])==1
dataTmp=hcat(dataTmp,[i,j])
println("vehicule ", k, " from ", i, " to ", j, ": $(route[i,j,k]) " )
end
end
end
end
vehicule 1 from 1 to 2: route[1,2,1]
vehicule 1 from 2 to 1: route[2,1,1]
vehicule 2 from 1 to 3: route[1,3,2]
vehicule 2 from 3 to 1: route[3,1,2]
vehicule 2 from 4 to 5: route[4,5,2]
vehicule 2 from 5 to 4: route[5,4,2]
why is vehicle 2 looping in 4->5->4->5->4 ...?
You need to add constraint forbidding cycles in the graph.
If you represent your route as x and the set of vertices as N (that is N = 1:nbVertex it can be denoted as:
This makes sure that for any given sub-set of vertices you will have less travels than the number of vertices.
In practice this constraint will look something like this:
using Combinatorics
N = 1:nbVertex
for E in powerset(N,2,nbVertex)
#constraint(mo, [k in K], ∑(route[i,j,k] for i ∈ E, j ∈ E if i != j) <= length(E)-1)
end
The problem is that the number of possible cycles grows very quickly when the size of N increases. You could try to mitigate it by using a lazy constraints callbacks approach (there is lots of literature on that) - unfortunately it is available only with commercial solvers. GLPK supports lazy constraints but the last time I tested it it was buggy. CBC has no support for lazy constraints.

Netlogo Get a pushing force from all neighbours within a distance

For each turtle, I got an agentset called visible-neighbors which are the turtles within a distance.
I wanna get a pulling force on this turtle from each of visible-neighbors. And then sum the forces. For each single pulling force from one neighbor is following the equation force = 1 / distance ^ 2. My idea is to decompose the force to x and y components and then sum the forces on x and y, finally compose the force again.
Here is the code I have at the moment. It's runnable, but for some reasons it doesn't work.
to get-direction-naive
set visible-neighbors (other turtles) in-radius 75 with [ distance myself > 0 ]
ifelse any? visible-neighbors
[let distance-list [distance myself] of visible-neighbors
let x-cors [xcor] of visible-neighbors
let x-diff map [? -> ? - xcor] x-cors
let x-forces (map [ [a b] -> a / (b ^ 3) ] x-diff distance-list)
let x-sum sum x-forces
let y-cors [ycor] of visible-neighbors
let y-diff map [? -> ? - ycor] y-cors
let y-forces (map [ [a b] -> a / (b ^ 3) ] y-diff distance-list)
let y-sum sum y-forces
ifelse y-sum = 0
[ifelse x-sum > 0
[set heading 0]
[set heading 180] ]
[set heading atan x-sum y-sum]
]
[right random 360]
end
Any advices would be appreciated.
What are you finding that isn't working? You want the turtles to be pulled towards each other, is that correct? This seems to set turtles' headings as needed- I think you can drop the two nested ifelse statements, though. Check out this toy version:
to setup
ca
crt 20 [
setxy random-xcor random-ycor
pd
]
reset-ticks
end
to force-pull
ask turtles [
let visible-neighbors other turtles in-radius 10
ifelse any? visible-neighbors [
let distance-list [distance myself] of visible-neighbors
let x-cors [xcor] of visible-neighbors
let x-diff map [ ? -> ? - xcor] x-cors
let x-forces force-calc x-diff distance-list
let x-sum sum x-forces
let y-cors [ycor] of visible-neighbors
let y-diff map [? -> ? - ycor] y-cors
let y-forces force-calc y-diff distance-list
let y-sum sum y-forces
set heading atan x-sum y-sum
let hyp sqrt ( ( x-sum ^ 2 ) + ( y-sum ^ 2 ) )
fd e ^ ( -0.5 * hyp )
] [
right random 360
]
]
tick
end
to-report force-calc [ dif-list dist-list ]
report ( map [ [ a b ] -> a / ( b ^ 3 ) ] dif-list dist-list )
end
It seems to me that the turtles face the calculated heading properly and get drawn together.

Netlogo : change patch color of one patch if orthogonal neighbors have the same color

I'm new to netlogo and I need some help.
I am trying to grow a continuous patch of one color (green on a black background). However, I will sometimes have a black patch that is completely surrounded by green patches. I would like to change the color of those black patches to green.
I tried :
ask patches [
if neighbors4 with [pcolor = 55]
[set pcolor 55]
]
but it gives me an error, as does
ask patches [
if any? neighbors4 [pcolor = 55]
[set pcolor 55]
]
Here is the code that works that will sometimes leave black patches surrounded by green patches :
to setup
clear-all
set-patch-size 4
resize-world -50 50 -50 50
ask patches[set pcolor black]
grow-cell
reset-ticks
end
to grow-cell
ask patch 0 0 [
set pcolor 55
ask neighbors [
set pcolor 55
]
]
repeat 45
[ ask patches with [pcolor = black]
[ set pcolor [pcolor] of one-of neighbors4 ] ]
end
Here is an ugly/barely clever hack.
Ask patches[
if mean [pcolor] of neighbors4 = green[set pcolor green]
]
Or alternately:
Ask patches with [ count neighbors4 with [pcolor = green] = 4 ]
[set pcolor green]

Simple way to replace nth element in a vector in clojure?

E.g., I have a vector [1, 2, 3], and I want to update the second element so that the vector becomes [1, 5, 3]. In other languages, I would just do something like array[1] = 5, but I'm not aware of anything that would allow me to do this easily in Clojure.
Thoughts on how to accomplish this, or on whether I should be using a different data structure?
assoc works fine for that. It takes the index where to put the new value and return the newly created vector:
Clojure> (assoc [1 2 3] 1 5)
[1 5 3]
Yve's answer doesn't show how to update the original vector.
This does, but as a Clojure noob, I'm not sure it's the best way:
main=> (def ar [1 2 3])
#'main/ar
main=> ar
[1 2 3]
main=> (def ar (assoc ar 1 5))
#'main/ar
main=> ar
[1 5 3]

Get the coordinates of a matrix from its flatten index

How can we get the coordinates of a n dimensions matrix from its shape and its flatten index?
I mean, if for example I have the following (2,3) matrix of 2 dimensions:
[ [ 0, 1 ],
[ 2, 3 ],
[ *4*, 5 ] ]
...and I want to find the value of the index in bold from the coordinates [0,2], how can I do?
Or if I have this (2,2,5) matrix of 3 dimensions:
[ [ [ nil, nil ],
[ nil, nil ] ],
[ [ nil, nil ],
[ nil, nil ] ],
[ [ nil, *9* ],
[ nil, nil ] ],
[ [ nil, nil ],
[ nil, nil ] ],
[ [ nil, nil ],
[ nil, nil ] ] ]
...and I know the coordinates that I want have a flatten index value of 9, how can I find the relative coordinates are: [1,0,2]?
If possible, I would like to know a general and simple method, which work on matrix of any shape.
Many thanks for your help.
You can use this simple algorithm:
Let's say you have the matrix A[a][b][c][d] (where a,b,c,d are the dimensions) and the index X.
To get the first coordinate of the index X you simply divide X by b*c*d.
Let it be this next matrix, having the sizes [2][5] and the index X=7
0 1 2 3 4
5 6 7 8 9
You first divide X by the last dimension to find the first coordinate. X/5=1 . Then, from there you move forward and give X the value X%=5 . So you'll have X = 7%5 =2. Now you have to search the coordinates for the remaining dimensions using the same algorithm. If you reach the last dimension , the coordinate will be the remaining X, in this case 2. So the coordinates for X=7 are [1][2] , which is actually the answear.
Again, for the general case, where you have a,b,c,d dimensions.
I'll note with (yd) the y'th dimension.
X=index
(1d)=X/b*c*d
X gets value X % b*c*d
(2d)=X/c*d
X gets value X % c*d
(3d)=X/d
X gets value X % d
(4d)=X
If you had the dimensions [2][2][5] you would get:
X=9;
(1d) = 9/2*5 = 0
X = 9%10 = 9
(2d) = 9/5 = 1
X = 9%5 = 4
(3d) = 4
Result: [0][1][4] is the 9th element.
To get from [0][1][4] to the index 9 , you do the reverse algorithm by multiplying:
X=(1d)*b*c + (2d)*c + 3d = 0 + 1*5 +4 =9

Resources