I am creating a supply chain simulation with NetLogo. I am putting a list of lists from NetLogo to R, which is represented by distributor ID (agents who) and sales history (sales of all previous ticks). In R I train my neural network and make predictions. When I put back the answer in the same format list of lists. I need to specify which result goes to which agent. However, I do not know how to do it in NetLogo. I assume that there should be a function to do that, but as I understand the functions are programmed with Java and I would need to assign the values inside the raw code and not in the NetLogo environment. Moreover, I think that this training and predictions occurs multiple times (for each agent) and not only once.
Variable example:
[ [0] [ 100 200 300 100 200] ]
[ [1] [ 200 300 100 100 200] ]
Where the first index is agents who index and the second is the agent's sales history.
Maybe someone could explain how NetLogo and R can be combined for computational purpose and not only statistical analysis and plotting? I assume that NetLogo is similar to parallel programming, while my style of R programming is more linear.
The last part of your question is beyond me (and may be too broad for typical Stack Overflow questions- I'm not sure you'll get a useful answer here). However, maybe this example would get you in the right direction as to what you're trying to do.
I assume you're using the [r] extension as in your previous question, so using this setup:
extensions [r]
turtles-own [ rand-num ]
to setup
ca
crt 10 [
set rand-num random 5
]
reset-ticks
end
In this example, turtles have a rand-num instead of your sales history, but the concept is the same. First, build the list of lists where first index is the turtle [who] and the second is [rand-num], then output it to r (note that I also sort the list, but that is just for clarity and not actually needed):
to go
let l_list map [ i ->
list i [rand-num] of turtle i
] ( sort [ who ] of turtles )
r:put "list1" l_list
show r:get "list1"
Next, use r:eval to do whatever you need to do to the values in r- in this example I'm just using lapply to square the rand-num value (x[[2]])- but make sure to return x:
let modified_list ( r:get "lapply(list1, function(x) { x[[2]] <- x[[2]]^2; return(x)})" )
Now, to assign the turtles the modified values, use Netlogo's foreach to iterate over the modified list and ask the turtle of index 0 (turtle item 0 x) to set its rand-num to index 1 (set rand-num item 1 x):
foreach modified_list [ x ->
ask turtle item 0 x [
set rand-num item 1 x
]
]
end
If you check the sort [rand-num] of turtles before and after running go, you should see the rand-num of each turtle is squared after go is called.
Related
I would like to create a network in Netlogo, put 3 agents on the first node of the network and make them move to a connected node.
Specifically I'd like the agents choose the node to move to based on a probability. If there is no agent on a connected node, choose it with p = 0.5, if there is an agent on the node choose it with p = 0.7. So if - for example - the starting node has two neighbouring nodes and one of them has an other agent on it, it should be chosen with a higher probability.
I've managed to create the network and move the agents randomly, but I can't figure out how to make an agent "know" if there is an other agent on a node and set the probabilities based on this condition.
breed [nodes node]
breed [walkers walker]
walkers-own [location ]
to setup
clear-all
set-default-shape nodes "circle"
create-nodes 18 [set color white]
ask nodes [ create-link-with one-of other nodes ]
layout-circle nodes 10
create-walkers 3 [
set location node 1
move-to location
]
reset-ticks
end
to go
ask walkers [
let new-location one-of [link-neighbors] of location ;; choose a new location randomly
move-to new-location
set location new-location
]
tick
end
I thought of making an occupied? variable and update it based on the position of the agents, but it would be a nodes-own variable, which I couldn't connect to the agents (walkers).
I am new to Netlogo and not aware of all the possibilities and limitations, so it is possible I am looking at this problem all wrong. I would appreciate your help.
Sielu, a couple of points.
First, creating a link will fail silently if there is already a link between those two nodes. The result is that some of your nodes will end up with only one neighbor. If that's not ok, you need to work on your link creation logic.
Second, it may not be obvious, but some nodes will end up with more than two links,
so a walker may have many different paths to choose from.
Third, a node may have more than one occupant. For example, all the other walkers might be on it.
Given all that, I'm going to assume that what you're asking for is for each walker to start looking at its linked-nodes, set some probability based on the occupancy of the target node, select a random number, and if it's below that probability move to that node and stop looking at other possible moves. If the random number is above that probability, however, then the walker should forget about that link and move on to considering the next one. If all links fail their separate tests, the walker doesn't move.
The code below implements that. It got kind of long and messy. Here's the key features.
I added a verbose? switch that turns on or off printing out details for debugging
and it asks the user whether to be verbose or not on each setup. If you hit
go once ( not forever ) you can see what got set and if its what you wanted.
I added a count-of-walkers to each node, versus a true/false occupancy? switch
I added a sequence number ( like "who" ) to each watcher to make the output
read more sensibly
the GO step makes a LIST of nodes that are link-neighbors to the node the watcher
is standing on. Then it sorts the list into the order you want to examine
them. ( I used a list because you might care what order they are looked at, and
agent sets are randomly ordered. ) I sorted them into ascending order by the
the occupancy counts, so it will first look at the unoccupied nodes, then the
occupied ones, up to the most occupied ones.
Then it goes through that list, deciding whether to move to that node or not.
Once it does decide to move, it stops looking at the list, so some of the nodes
will not even be considered for a move.
You can see the section where probabilities are set depending on the occupancy
count of the node. I used your 0.5 and 0.7 probabilities and added a 0.9
probability if there are 2 or more watchers on the target node.
The code has a lot of comments,and if you set verbose? to true, you can
examine how each watcher considers ( or doesn't) each link and makes its
decision to move or not.
The code runs and looks ok, so far as I can tell what it is you want. Ask me
questions if it's not clear what I did.
breed [nodes node]
breed [walkers walker]
walkers-own [location seqnum ] ;; seqqnum is like who but for the walkers
nodes-own[ count-of-walkers ] ;; ADDED
globals [verbose?]
to setup
clear-all
set verbose? false ;; if true, prints a lot for debugging purposes
if user-yes-or-no? "Print debugging info on each step?" [set verbose? true]
set-default-shape nodes "circle"
create-nodes 18 [set color white]
ask nodes [ create-link-with one-of other nodes ]
layout-circle nodes 10
let seq 1 ;; start of sequence numbers for walkers
create-walkers 3 [
set size 3
set color red
set location node 1
set seqnum seq set seq seq + 1 ;; assign the sequence number
move-to location
ask location [ set count-of-walkers count-of-walkers + 1 ]
]
reset-ticks
end
to go
if verbose? [print " ================================== starting the go loop"]
ask walkers [
let candidate-set [] ;; this will be an agent set of neighboring linked nodes
ask location [set candidate-set link-neighbors ] ;; ask my node to find its neighbors
;; sort the neighbors into some order and make a list of them
;; the next line sorts them into ascending order by occupancy ( lowest first )
;; we will consider a move to each one in that order
let candidate-list sort-on [count-of-walkers] candidate-set
if verbose? [
type "walker " type seqnum
type " is checking out these neighbors: " print candidate-list
]
;; Examine each neighbor and decide whether to move there based on probabilities
;; if we find a place to move we like terminate processing the list
;; otherwise, remove that candidate neighbor from the list
;; and keep doing that until the list is empty
;;
while [length candidate-list > 0 ] [ ;; while we haven't decided to move yet
;; pop the first item off the list
let candidate first candidate-list ;; pull the first item
set candidate-list but-first candidate-list ;; and remove it from the list
;; decide what probability to use for considering THIS move
let prob-of-move 0 ;; a default value
let occupant-count [ count-of-walkers ] of candidate ;; count walkers on that node
if occupant-count = 0 [ set prob-of-move 0.5 ]
if occupant-count = 1 [ set prob-of-move 0.7 ]
if occupant-count > 1 [ set prob-of-move 0.9 ]
if verbose? [
type " ... candidate " type candidate
type " has this many walkers " type [count-of-walkers] of candidate
type " so set probability of move to " print prob-of-move
]
;; make a decision to move or not based on that probability
if-else random-float 1 < prob-of-move [
if verbose? [type " ......moving to " print candidate]
;;let new-location candidate
set candidate-list [] ;; make the list empty so this WHILE loop will exit
move-to candidate ;; move the walker on the display
;; update the counts of walkers on each affected node
ask candidate [ set count-of-walkers count-of-walkers + 1 ]
ask location [ set count-of-walkers count-of-walkers - 1 ]
;; finally, tell the walker where it is now
set location candidate
]
[if verbose? [ print " ..... was not selected for a move to this node"]]
]
if verbose? [ print " ..............done with processing walkers for this tick"]
]
tick
end
I' am doing my homework in programming, and I don't know how to solve this problem:
We have a set of n weights, we are putting them on a scale one by one until all weights is used. We also have string of n letters "R" or "L" which means which pen is heavier in that moment, they can't be in balance. There are no weights with same mass. Compute in what order we have to put weights on scale and on which pan.
The goal is to find order of putting weights on scale, so the input string is respected.
Input: number 0 < n < 51, number of weights. Then weights and the string.
Output: in n lines, weight and "R" or "L", side where you put weight. If there are many, output any of them.
Example 1:
Input:
3
10 20 30
LRL
Output:
10 L
20 R
30 L
Example 2:
Input:
3
10 20 30
LLR
Output:
20 L
10 R
30 R
Example 3:
Input:
5
10 20 30 40 50
LLLLR
Output:
50 L
10 L
20 R
30 R
40 R
I already tried to compute it with recursion but unsuccessful. Can someone please help me with this problem or just gave me hints how to solve it.
Since you do not show any code of your own, I'll give you some ideas without code. If you need more help, show more of your work then I can show you Python code that solves your problem.
Your problem is suitable for backtracking. Wikipedia's definition of this algorithm is
Backtracking is a general algorithm for finding all (or some) solutions to some computational problems, notably constraint satisfaction problems, that incrementally builds candidates to the solutions, and abandons a candidate ("backtracks") as soon as it determines that the candidate cannot possibly be completed to a valid solution.
and
Backtracking can be applied only for problems which admit the concept of a "partial candidate solution" and a relatively quick test of whether it can possibly be completed to a valid solution.
Your problem satisfies those requirements. At each stage you need to choose one of the remaining weights and one of the two pans of the scale. When you place the chosen weight on the chosen pan, you determine if the corresponding letter from the input string is satisfied. If not, you reject the choice of weight and pan. If so, you continue by choosing another weight and pan.
Your overall routine first inputs and prepares the data. It then calls a recursive routine that chooses one weight and one pan at each level. Some of the information needed by each level could be put into mutable global variables, but it would be more clear if you pass all needed information as parameters. Each call to the recursive routine needs to pass:
the weights not yet used
the input L/R string not yet used
the current state of the weights on the pans, in a format that can easily be printed when finalized (perhaps an array of ordered pairs of a weight and a pan)
the current weight imbalance of the pans. This could be calculated from the previous parameter, but time would be saved by passing this separately. This would be total of the weights on the right pan minus the total of the weights on the left pan (or vice versa).
Your base case for the recursion is when the unused-weights and unused-letters are empty. You then have finished the search and can print the solution and quit the program. Otherwise you loop over all combinations of one of the unused weights and one of the pans. For each combination, calculate what the new imbalance would be if you placed that weight on that pan. If that new imbalance agrees with the corresponding letter, call the routine recursively with appropriately-modified parameters. If not, do nothing for this weight and pan.
You still have a few choices to make before coding, such as the data structure for the unused weights. Show me some of your own coding efforts then I'll give you my Python code.
Be aware that this could be slow for a large number of weights. For n weights and two pans, the total number of ways to place the weights on the pans is n! * 2**n (that is a factorial and an exponentiation). For n = 50 that is over 3e79, much too large to do. The backtracking avoids most groups of choices, since choices are rejected as soon as possible, but my algorithm could still be slow. There may be a better algorithm than backtracking, but I do not see it. Your problem seems to be designed to be handled by backtracking.
Now that you have shown more effort of your own, here is my un-optimized Python 3 code. This works for all the examples you gave, though I got a different valid solution for your third example.
def weights_on_pans():
def solve(unused_weights, unused_tilts, placement, imbalance):
"""Place the weights on the scales using recursive
backtracking. Return True if successful, False otherwise."""
if not unused_weights:
# Done: print the placement and note that we succeeded
for weight, pan in placement:
print(weight, 'L' if pan < 0 else 'R')
return True # success right now
tilt, *later_tilts = unused_tilts
for weight in unused_weights:
for pan in (-1, 1): # -1 means left, 1 means right
new_imbalance = imbalance + pan * weight
if new_imbalance * tilt > 0: # both negative or both positive
# Continue searching since imbalance in proper direction
if solve(unused_weights - {weight},
later_tilts,
placement + [(weight, pan)],
new_imbalance):
return True # success at a lower level
return False # not yet successful
# Get the inputs from standard input. (This version has no validity checks)
cnt_weights = int(input())
weights = {int(item) for item in input().split()}
letters = input()
# Call the recursive routine with appropriate starting parameters.
tilts = [(-1 if letter == 'L' else 1) for letter in letters]
solve(weights, tilts, [], 0)
weights_on_pans()
The main way I can see to speed up that code is to avoid the O(n) operations in the call to solve in the inner loop. That means perhaps changing the data structure of unused_weights and changing how it, placement, and perhaps unused_tilts/later_tilts are modified to use O(1) operations. Those changes would complicate the code, which is why I did not do them.
New NetLogo User and first-time poster here, with some cannibalistic turtles on my hands.
About my model:
My turtles have a bodysize (bsize), and a breed (male, female, juvenile turtles). They move around in a random fashion and encounter each other on patches. When two turtles land on the same patch, my little beasts size each other up, and depending on a probability of cannibalism (PrCan) specific to the larger turtle's breed and the body size ratio (bsize_ratio) between the two, the bigger one eats the smaller one.
I don't think this is relevant, but I have created a table (PrCanTable) of 3 lists with two keys (body size ratio, breed, and probability of cannibalism) using table:make from instructions I found on this stack overflow answer.
To continue, the bigger turtle looks up the probability of cannibalizing (PrCanT) in the table (PrCanTable), then picks a random number (random-float) and compares it to the probability (PrCanT). If the random number is less than or equal to the probability, the little turtle dies. So sad!
Unfortunately, my bloodthirsty turtles are misbehaving. I am running into a problem:
There is no agent for MYSELF to refer to.
error while fa 25 running MYSELF
called by procedure CANNIBALIZE
called by procedure GO
called by Button 'go'
NetLogo has helpfully highlighted the last instance of myself in my code...but I don't know why. I think this is a problem with my own understanding of myself vs. self. I have read as much as I can, but honestly am still stumped. Can anyone take a look at this code and let me know?
to-report get-PrCan_T [ bsize_ratio_T breed_T ]
report table:get (table:get PrCanTable bsize_ratio_T) breed_T
end
to cannibalize
if ( any? turtles-here with [bsize > [bsize] of myself])
and ( random-float 1 <= get-PrCan_T ( precision( bsize / bsize of myself ) 1 ) ( [breed] of self ) )
[die]
end
Yeah, self and myself are confusing at first, but once you get the hang of it, it's really not that hard. What you need to understand is that every piece of NetLogo code runs into a "context". That context, by default, is the observer, but some primitives can introduce a new context.
ask is the most obvious way to introduce a new context: the command block that you pass to ask (delimited by [ and ]) puts NetLogo in the context of a turtle. Inside that context, self refers to the current turtle.
But sometimes you introduce a new turtle context inside an existing turtle context! Inside that new context, self changes meaning: it now refers to the turtle from the inner context. But what if you still want to refer to the turtle from the outer context? That's what myself is for.
Assuming that cannibalize is a procedure that is run by a turtle, your use of myself in turtles-here with [bsize > [bsize] of myself] is correct: the turtle running the with block is self (which you don't need to specify) and turtle running cannibalize (the "outer" turtle) is myself. The inner context was introduced by with.
But in the second part of your if condition (everything that follow and) there is no inner context anymore: you're not inside the with block anymore. So myself is not defined anymore. There is only self.
Your code is also made harder to debug by the fact that you're trying to pack everything in the same long if condition. Try splitting it up by using multiple local variables:
to cannibalize
let bigger-turtles-here turtles-here with [ bsize > [ bsize ] of myself ]
if any? bigger-turtles-here [
let cannibal one-of bigger-turtles-here
let ratio precision ([ bsize ] of cannibal / bsize) 1
let p get-PrCan_T ratio breed
if random-float 1 <= p [ die ]
]
end
One final note: in both your version and mine, the turtle running the cannibalize procedure is the one that gets eaten! That's confusing. I would either rename the procedure to get-cannibalized or switch things around so that the turtle running the procedure is the one that does the eating. (Naming is important!)
Is it possible to solve this without iterating over the array?
Suppose I have an array having 4 slots, [] [] [] []
and I know 2 points [x] [x] [] [] , is it possible to have a formula that tells us the coordinates of the other two empty spots? (using a mathematical formula, (not if this then that or iterate and fin the empty spots)) I think in most cases we get lazy and instead of trying to find a real solution to problems we tend to do it the easy way, by using conditions and iterations :/
No your not given enough information. You don't know what the other two points should be. All you can tell with A[x1][x2][][] is that the last two coordinated lie on a subset that is intersected be x1 and x2
Example
Let Word be an array that give us a representation of a word in a book
Word [page][line][number of words into line]
Now if I only gave you the page of the book and the line in the page there's no way you can tell me the word you need more information
I have a netlogo question. I have some graph structures of nodes connected with (undirected) links. I need to figure out which is the smallest subgraph within one of these structures. Basically subgraph means which nodes are all connected between each other. So if I have a structure of 5 nodes and node 1 is connected to 2 and 3; node 2 to 3, 1 and 4; and node 3 to 1, 2 and 5 I need to detect the subgraph of nodes 1, 2 and 3 since they're all interconnected.
Is there an easy way to do this or is it basically not computationally possible?
Edit: I figured out that if I use the netlogo extension nw I can use the nw:maximal-cliques method to calculate what I want. Although now I have another problem. I'm trying to fill up a list of the lists of the cliques this way
let lista-cliques [nw:maximal-cliques] of turtles with [guild = g]
lista-cliques is usually of length two but the first element which should be a list of the turtles of the clique is a list like this
[[[nobody] [nobody] [nobody] [nobody]...etc
with a length of 300 when the graphs made by turtles with guild = g are around 2-8 turtles in length. Is the call to nw:maximal-cliques well made?
Any ideas of what am I doing wrong?
Edit 2: I figured how to fix the length of the list by doing this
let lista-cliques (list ([nw:maximal-cliques] of turtles with [guild = g]))
Now the list is not of 300 nodes but equal to the amount of nodes on the graph with nodes with guild = g.
That means that
length item 1 lista-cliques
is equal to
count turtles with [guild = g]
which is also evidently wrong since I can see graphs with nodes connected to only one or two nodes. I think I'm getting closer but I don't know why nw:maximal-cliques is not creating a list of the maximal-cliques but a list of all the nodes on the graph.
Any ideas?
Thanks
Your usage of nw:maximal-cliques is not quite correct.
I think that what you are trying to express by specifying of turtles with [guild = g] is something like "taking into account only the turtles that are part of guild g", but what it actually means to NetLogo is "run the reporter that precedes of for each turtle that are part of guild g and make a list out of that". (Just like, e.g., [color] of turtles will run the [color] reporter block once for each turtle and build a list of colors with the results.)
nw:maximal-cliques is a primitive that operates on the whole network, so you don't want to run it once for each turtle. And just like most primitives in the nw extension, you need to tell it which turtles and links to operate on by using the nw:set-snapshot primitive.
I think you can achieve what you want by simply doing:
nw:set-snapshot (turtles with [guild = g]) links
let lista-cliques nw:maximal-cliques
(Note that nw:set-snapshot takes a static "picture" of your network on which further calls to nw primitives operate. If something changes in your network, you need to call nw:set-snapshot to take a new picture. This will probably change in a future version of the extension.)