I'm trying to make a network of friends like in this example previous to the final correction of JenB in here, since it is more comprehensible for me and Bryan Head said it would be the way he would do it with fewer agents. I'm planning to use around 200, maybe 300 agents.
My question is... how could I do it without forming pairs? I want the agents to make friends with every agent in radius x during y ticks and with the same color (I'm still working on the tick condition). I tried with if and some conditions before finding the JenB example but it was way too heavy.
I think it isn't necessary to rework the full code. But I'll write it down for you to see my version.
to make-friends
ask agentes [
let new-friendships friends - count my-friendships
if (new-friendships > 0) [
set possible-friends other agentes in-radius sight-radius with [
(count my-friendships < friends) and (color = [color] of myself) ]
create-friendships-with n-of min (list new-friendships count possible-friends) possible-friends]
end
V2 CODE
I started to work in another piece of code since I don't fully know how to do it better. This is the last version. The random-in-range 0 12 condition is in the setup.
to make-friends
ask agentes [
let new-friends max-friends - count my-friendships
let possible-friends other agentes with [color = [color] of myself] in-radius sight-radius
if new-friends > 0 [
let chosen n-of min (list new-friends count other possible-friends) other possible-friends
create-friendships-with chosen ;in-radius sight-radius [ hide-link ]
set possible-friends other possible-friends
set friends friendship-neighbors
ask chosen [
if my-friendships = friends [ set possible-friends other possible-friends ] ]
]
]
end
Related
For my final year project I am trying to simulate how differing opinions can impact risk and overall HIV transmission. The part I have a problem with is a fairly simple code so I have each turtle with a different risk level 0-1, as well as educators with risk of 0, and misinformation spreaders with a risk of 1, then when they land on a patch they change to the mean of the patch.
We have added a switch to turn on and off my educators and misinfo spreaders (influencers?) as well as a chooser to swap between the mean of the patch vs the min and max. However now the simulation wont adjust and comes out with the same output no matter the adjustments.
can anyone help me with this part of the code? I think it might just be the order it is in, or if I need to add another switch to turn mean off?
""to be-influenced
if influenced-by = "mean" [
if any? other turtles-here [
set patch-risk mean [risky] of turtles-here
set risky patch-risk
]
]
if influenced-by = "max" [
if any? other turtles-here[
set patch-risk max [risky] of turtles-here
set risky patch-risk
]
]
if influenced-by = "min" [
if any? other turtles-here [
set patch-risk min [risky] of turtles-here
set risky patch-risk
]
]
if influencers? [
if any? other turtles-here with [influencer? = TRUE] [
ask one-of turtles-here with [influencer? = TRUE] [
set temptur [who] of self
set patch-risk [risky] of turtle temptur
]
set risky patch-risk
]]
end""
I have written a fairly complicated code for my ABM (634 agents having interactions, each having different variables some of which are lists with multiple values that are updated each tick). As I need to save the updated values for all agents, I have defined a global variable using table:make. This table has 634 keys (each key for one agent), and each key has a list of those values (from that agents-own list variable) for the correspondent agent. But when I use the name of this table to be reported as one of my outputs in Behavior Space, the result in csv file is a table with no keys and it has only a number in it: {{table: 1296}}. So, I was wondering how I could change this variable to be able to have all values.
If you're happy to do some post-processing with R or something after the fact, then table:to-list might be all you need. For example, with a simple setup example like:
extensions [ table ]
globals [ example-table ]
turtles-own [ turtle-list ]
to setup
ca
crt 3 [
set turtle-list ( list random 10 one-of [ "A" "B" "C" ] random 100 )
]
set example-table table:make
foreach sort turtles [
t ->
table:put example-table ( word "turtle_" [who] of t ) [turtle-list] of t
]
reset-ticks
end
And a to-report to clean each table item such that the first item is the key and all other items are the items in the list:
to-report easier-read-table [ table_ ]
let out []
foreach table:to-list table_ [ i ->
set out lput ( reduce sentence i ) out
]
report out
end
You can set up your BehaviorSpace experiment such that one of your reporters is that reporter, something like:
To get a .csv file like:
Where the reporter column outputs a list of lists that you can process how you like.
However, I probably wouldn't use the basic BehaviorSpace output for this, but instead have a call in the experiment to call a manual table output procedure. For example, using the csv extension to make this output-table procedure:
to output-table [ filename_ table_ ]
let out [["key" "col1" "col2" "col3"]]
foreach table:to-list table_ [ i ->
set out lput ( reduce sentence i ) out
]
csv:to-file filename_ out
end
This outputs a much more analysis-ready table if you're less comfortable cleaning the output of a list-of-lists that as far as I know is what you would get from the BehaviorSpace output. So, you can either call it at the end of your experiment, like:
To get a table like:
Which is a little nicer to deal with. You can obviously modify this to report more often if needed, for example:
which would output a table at each tick of the experiment (you can also do this in your code to make it a little easier).
Lets say we have a database of food items such as:
item1 = {name: 'item1', tags: ['mexican', 'spicy']};
item2 = {name: 'item2', tags: ['sweet', 'chocolate', 'nuts']};
item3 = {name: 'item3', tags: ['sweet', 'vanilla', 'cold']};
And we have a user looking for food recommendations, where they indicate their preference weight for some tags:
foodPref = {sweet: 4, chocolate: 11}
Now we need to calculate how well each item scores and recommend the best items:
item1 score = 0 (doesn't contain any of the tags user is looking for)
item2 score = 4 (contains the tag 'sweet')
item3 score = 15 (contains the tag 'sweet' and 'chocolate')
I have modeled the problem as a graph:
What's the correct way to get the recommendations -- a custom traversal object or just filter and count using AQL or just implement it in Foxx (javascript layer)?
Also, can you help out with a sample implementation for the methods you suggest?
Thanks in advance!
First, lets create the collections and their contents the way you specified them. We will add a second user.
db._create("user")
db._create("tags")
db._create("dishes")
db.user.save({_key: 'user1'})
db.user.save({_key: 'user2'})
db.tags.save({_key: 'sweet'})
db.tags.save({_key: 'chocolate'})
db.tags.save({_key: 'vanilla'})
db.tags.save({_key: 'spicy'})
db.dishes.save({_key: 'item1'})
db.dishes.save({_key: 'item2'})
db.dishes.save({_key: 'item3'})
Now lets create the edge collections with their edges:
db._createEdgeCollection("userPreferences")
db._createEdgeCollection("dishTags")
db.userPreferences.save("user/user1", "tags/sweet", {score: 4})
db.userPreferences.save("user/user1", "tags/chocolate", {score: 11})
db.userPreferences.save("user/user2", "tags/sweet", {score: 27})
db.userPreferences.save("user/user2", "tags/vanilla", {score: 7})
db.dishTags.save("tags/sweet", "dishes/item2", {score: 4});
db.dishTags.save("tags/sweet", "dishes/item3", {score: 7})
db.dishTags.save("tags/chocolate", "dishes/item2", {score: 2})
db.dishTags.save("tags/vanilla", "dishes/item3", {score: 3})
db.dishTags.save("tags/spicy", "dishes/item1", {score: 666})
Our relations are like this:
user-[userPreferences]->tags-[dishTags]->dishes
finding out what user1 likes can be done with this query:
FOR v, e IN 1..2 OUTBOUND "user/user1" userPreferences, dishTags
RETURN {item: v, connection: e}
if you now want to find all dishes that user1 likes best:
FOR v, e IN 2..2 OUTBOUND "user/user1" userPreferences, dishTags
FILTER e.score > 4 RETURN v
We filter for the score attribute.
Now we want to find another user that has the same preferences as user1 does:
FOR v, e IN 2..2 ANY "user/user1" userPreferences RETURN v
We go into ANY direction (forward and backward), but only are interested in the userPreferences edge collection, else 2..2 would also give use dishes. The way we do it now. we go back into the user collections to find users with similar preferences.
Whether or not creating a Foxx-service is a good option depends on personal preferences. Foxx is great if you want to combine & filter results on the server side, so client communication is less. You can also use it if you like to put your Application rather on top of microservices than on db-queries. Your application may then stay free of database specific code - it only operates with the microservice as its backend. There may be usecases where Foxx
In general, there is no "correct" way - there are different ways which you may prefer above others because of performance, code cleanness, scalability, etc.
I would like to obtain the longest path that are connected to a single parent via Neo4J Cypher query.
My current queries are like this:
MATCH p=(N1:Node)-[REL*..2]->(N2:Node) WHERE N2.RIC =~"some ticker.*" RETURN p limit 50
However, i am getting results like this
a->b->parent
b-> parent
In my own opinion , i would like to keep only the longest path.
Also, is there anyway to return the direction of the query ? IE: i can see the from/to of a relationship in the output of the query.
Thanking in advance !
If you want just the longest path then you can do:
MATCH path=(N1:Node)-[REL*..2]->(N2:Node)
WHERE N2.RIC =~"some ticker.*"
RETURN p
ORDER BY length(p) DESC
LIMIT 1
As for getting the directions, this depends on the driver that you use. In the Neo4j HTTP transaction endpoint if you specify REST for resultDataContents, it will return a directions for any path objects that you return. Here is how you set that:
http://neo4j.com/docs/stable/rest-api-transactional.html#rest-api-execute-statements-in-an-open-transaction-in-rest-format-for-the-return
Here is an example of what that looks like:
"rest": [
{
"relationships": [
"http://localhost:7474/db/data/relationship/587"
],
"nodes": [
"http://localhost:7474/db/data/node/1002",
"http://localhost:7474/db/data/node/1001"
],
"directions": [
"<-"
],
"length": 1,
"start": "http://localhost:7474/db/data/node/1002",
"end": "http://localhost:7474/db/data/node/1001"
}
]
EDIT:
Responding to your comment, in order to get the longest path for each parent:
MATCH path=(N1:Node)-[REL*..2]->(N2:Node)
WHERE N2.RIC =~"some ticker.*"
WITH N1, N2, collect(p) AS paths
ORDER BY length(p) DESC
RETURN N1, N2, paths[0] AS longest_path
I wasn't sure which side is supposed to be the parent, so I returned both N1 and N2 which should give you the longest path for each combination of those two. You can remove either one to get the longest path leading to/from the node which is left.
I compile the following graph with: dot graph.dot -Tpdf -ograph.pdf, producing:
The result is okay, but the state transition look a lot like a spagetthi monster and I have no clue what I could do to approach this problem. I tried other layouts: twopi, neato, etc. Are there parameters which allow it to force the graph to look a little bit more symmetric? Because the overall picture is okay.
To me it seems like the edges use the minimal space available to frame the edge descriptions, maybe this is the problem?
Is my graph design flawed? Should I write the different state transitions on one edge, using \n to separate the different transitions?
digraph finite_state_machine {
rankdir=LR;
edge [fontsize=26];
node [shape = doublecircle, width=2.0, fontsize=24, fixedsize=true,style=filled, colorscheme=spectral5]; New [fillcolor=3] Terminated [fillcolor=5];
node [shape = circle, width=2.0, fontsize=24, fixedsize=true, colorscheme=spectral5]; Runnable [fillcolor=4] Waiting [fillcolor=2] "Timed\nWaiting" [fillcolor=2] Blocked [fillcolor=1];
New -> Runnable [ label = "Thread.start" ];
Runnable -> Waiting [ label = "Object.wait" ];
Runnable -> Waiting [ label = "Thread.sleep" ];
Runnable -> Waiting [ label = "LockSupport.park" ];
Waiting -> Blocked [ label = "Reacquire monitor lock after\nleaving Object.wait" ]
Waiting -> Blocked [label = "Spurious wake-up"]
"Timed\nWaiting" -> Blocked [ label = "Reaquire monitor lock after\n leaving Object.wait" ]
"Timed\nWaiting" -> Terminated [ label = "Exception" ]
"Timed\nWaiting" -> Blocked [ label = "Spurious wake-up" ]
Runnable -> "Timed\nWaiting" [ label = "Object.wait" ];
Runnable -> Blocked [ label = "Contended Monitor\nEnter" ];
Blocked -> Runnable [ label = "Contended Monitor\nEntered" ];
Runnable -> Terminated [ label = "Thread finishes\nexecution" ]
Runnable -> Terminated [ label = "Exception" ]
Waiting -> Runnable [ label = "Object.notify\nObject.notifyAll" ]
Waiting -> Terminated [ label = "Exception" ]
"Timed\nWaiting" -> Runnable [ label = "Object.notify\nObject.notifyAll" ]
}
I don't think your design is flawed, I think it's ok. The dot syntax is readable and therefore maintainable, and the result is what an automatically generated graph looks typically alike.
Of course you can add small corrections to make this particular graph better (or at least different). Some of them may prove difficult to implement if for example the source for your graph is generated by an application. Here are some ideas:
To get the layout to be more symmetric, you may try to align the nodes Waiting and Terminated as well as Timed Waiting and Blocked by setting their group attribute to the same value (group=a and group=b).
It worked fine for Waiting and Teminated, but not so well for Timed Waiting and Blocked - probably because there are two edges between those nodes.
You may try to straighten them out by picking one of the edges which links them and set its weight attribute to a high value.
Other than that, I think the graph looks nicer over all because the edges are smoother and have less unnecessary curves, especially - but not only - between Runnable and Waiting.
The spaghetti effect is due to the splines - maybe it looks less spaghetti without splines? I tried by adding splines=compound or splines=ortho (same result):
The graph uses slightly less vertical space. It's not spaghetti, but it's not better in my opinion...
You may also try splines=compound without the group attributes, this should make the graph a little more compact (bug not necessarily prettier). Or simply play around with the weight of the edges to straighten out particularly unpleasant edges.
In some cases, concentrate can clear up graphs with lots of parallel edges - in this case it doesn't really help.