Preferential Attachement Netlogo - social-networking

I'm trying to adapt the (simple) Preferential Attachment Network model (available in the Netlogo Models library) to include a slider variable that determines network structure. According to the theory of the Preferential Attachment model (or 'Opinion Leader' model) each individual in the network is assigned a number of ties, k, according to the distribution p(k) ∝ k^−γ, and connected randomly to this number of people. I thus want to have a slider for which i can adapt γ.
In the heart of the original code partners and links are chosen randomly, as such:
to go
if count turtles > num-nodes [ stop ]
;; choose a partner attached to a random link
;; this gives a node a chance to be a partner based on how many links it has
;; this is the heart of the preferential attachment mechanism
let partner one-of [both-ends] of one-of links
;; create new node, link to partner
create-turtles 1 [
set color red
;; move close to my partner, but not too close -- to enable nicer looking networks
move-to partner
fd 1
create-link-with partner
]
;; lay out the nodes with a spring layout
layout
tick
end
I'm a bit lost on how I should include this parameter.
Anyone who could help?
Thanks in advance.
EDIT: still can't get this to work. I got as far as making a 'normal' preferential attachment model in setup rather than go (again adapted from the models library). But still can't get my head around how I should adapt this code to include the gamma parameter. My code:
to create-new-nodes [n]
clear-all
ask patches [ set pcolor white ]
create-nodes n [
set color red
set shape "circle"
]
reset-ticks
end
to wire-pref-attach
create-new-nodes 2 ; create the first two nodes (0 and 1)
ask node 0 [ create-edge-with node 1] ; link them together
create-nodes num-nodes - 2 [
create-edge-with [one-of both-ends] of one-of edges ; pref select old node with more links
set color red
set shape "circle"
]
radial-layout
end
to radial-layout
layout-radial nodes edges (node 0)
end
Help is very much appreciated!

I think you have missed the point of my original comment, there is no place in the Barabasi-Albert (BA) algorithm to insert any such parameter. You need to build the network in an entirely different way. That is, you need to work out the method or process or algorithm for building the network, and then worry about writing the code to implement that method.
I think you need the algorithm described in Dorogovtsev et al (2000) Structure of Growing Networks with Preferential Linking (see https://journals.aps.org/prl/pdf/10.1103/PhysRevLett.85.4633 if you have access). In the BA algorithm, the nodes in the existing network for the new node to attach to are selected with probability proportional to in-degree (or k in your question). In the extended algorithm, each node has an inherent attractiveness A and the probability of selection is instead A+k.
Equation 12 in the paper describes the relationship between the exponent (your parameter gamma as: gamma = 2 + A/m where m is the out-degree (the number of edges being attached with each node).

Related

Godot : How to instantiate a scene from a list of possible scenes

I am trying to create a game in which procedural generation will be like The Binding of Isaac one : successive rooms selected from a list. I think I will be able to link them together and all, but I have a problem : How do I choose a room from a list ?
My first thought is to create folders containing scenes, something like
zone_1
basic_rooms
room_1.tscn
room_2.tscn
special_rooms
...
zone_2
...
and to select a random scene from the folder I need, for example a random basic room from the first zone would be a random scene from zone_1/basic_rooms.
The problem is that I have no idea if this a good solution as it will create lots of scenes, and that I don't know how to do this properly. Do I simply use a string containing the folder path, or are there better ways ? Then I suppose I get all the files in the folder, choose one randomly, load it and instanciate it, but again, I'm not sure.
I think I got a little lost in my explainations, but to summarize, I am searching for a way to select a room layout from a list, and don't know how to do.
What you suggest would work.
You can instance scene by this pattern:
var room_scene = load("res://zone/room_type/room_1.tscn")
var room_instance = room_scene.instance()
parent.add_child(room_instance)
I'll also remind you to give a position to the room_instance.
So, as you said, you can build the string you pass to load.
I'll suggest to put hat logic in an autoload and call it where you need it.
However, the above code will stop the game while it is loading the scene. Instead do Background Loading with ResourceLoader.
First you need to call load_interactive which will give you a ResourceInteractiveLoader object:
loader = ResourceLoader.load_interactive(path)
Then you need to call poll on the loader. Until it returns ERR_FILE_EOF. In which case you can get the scene with get_resource:
if loader.poll() == ERR_FILE_EOF:
scene = loader.get_resource()
Otherwise, it means that call to poll wasn't enough to finish loading.
The idea is to spread the calls to poll across multiple frames (e.g. by calling it from _process).
You can call get_stage_count to get the number of times you need to call poll, and get_stage will tell you how many you have called it so far.
Thus, you can use them to compute the progress:
var progress = float(loader.get_stage()) / loader.get_stage_count()
That gives you a value from 0 to 1. Where 0 is not loaded at all, and 1 is done. Multiply by 100 to get a percentage to display. You may also use it for a progress bar.
The problem is that I have no idea if this a good solution as it will create lots of scenes
This is not a problem.
Do I simply use a string containing the folder path
Yes.
Then I suppose I get all the files in the folder, choose one randomly
Not necessarily.
You can make sure that all the scenes in the folder have the same name, except for a number, then you only need to know how many scenes are in the folder, and pick a number.
However, you may not want full randomness. Depending on your approach to generate the rooms, you may want to:
Pick the room based on the connections it has. To make sure it connects to adjacent rooms.
Have weighs for how common or rare a room should be.
Thus, it would be useful to have a file with that information (e.g. a json or a csv file). Then your autoload code responsible for loading scenes would load that file into a data structure (e.g. a dictionary or an array), from where it can pick what scene to load, considering any weighs or constraints specified there.
I will assume that your rooms exist on a grid, and can have doors for NORTH, SOUTH, EAST, WEST. I will also assume that the player can backtrack, so the layout must be persistent.
I don't know how far ahead you will generate. You can choose to generate all the map at once, or generate rooms as the player attempt to enter, or generate a few rooms ahead.
If you are going to generate as the player attempts to enter, you will want an room transition animation where you can hide the scene loading (with the Background Loading approach).
However, you should not generate a room that has already been generated. Thus, keep a literal grid (an array) where you can store if a room has been generated. You would first check the grid (the array), and if it has been generated, there is nothing to do. But if it hasn't, then you need to pick a room at random.
But wait! If you are entering - for example - from the south, the room you pick must have a south door to go back. If you organize the rooms by the doors they have, then you can pick from the rooms that have south doors - in this example.
In fact, you need to consider the doors of any neighbor rooms you have already generated. Thus, store in the grid (the array) what doors the room that was generated has. So you can later read from the array to see what doors the new room needs. If there is no room, decide at random if you want a door there. Then pick a room at random, from the sets that have the those doors.
Your sets of rooms would be, the combinations of NORTH, SOUTH, EAST, WEST. A way to generate the list, is to give each direction a power of two. For example:
NORTH = 1
SOUTH = 2
EAST = 4
WEST = 8
Then to figure out the sets, you can count, and the binary representation gives the doors. For example 10 = 8 + 2 -> WEST and SOUTH.
Those are your sets of rooms. To reiterate, look at the already generated neighbors for doors going into the room you are going to generate. If there is no room, decide at random if you want a door there. That should tell you from what set of rooms you need to pick to generate.
This is similar to the approach auto-tile solution use. You may want to read how that works.
Now assuming the rooms in the set have weights (so some rooms are more common and others are rarer), and you need to pick at random.
This is the general algorithm:
Sum the weights.
Normalize the weights (Divide the weights by the sum, so they add up to 1).
Accumulate the normalized weights.
Generate a random number from 0 to 1, and what is the last accumulated normalized weight that is greater than the random number we got.
Since, presumably, you will be picking rooms from the same set multiple times, you can calculate and store the accumulated normalized weights (let us call them final weights), so you don't compute them every time.
You can compute them like this:
var total_weight:float = 0.0
for option in options:
total_weight = total_weight + option.weight
var final_weight:float = 0.0
var final_weights:Array = []
for option in options:
var normalized_weight = option.weight / total_weight
final_weight = final_weight + normalized_weight
final_weights.append(final_weight)
Then you can pick like this:
var randomic:float = randf()
for index in final_weights.size():
if final_weights[index] > randomic:
return options[index]
Once you have picked what room to generate, you can load it (e.g. with the Background Loading approach), instance it, and add it to the scene tree. Remember to give a position in the world.
Also remember to update the grid (the array) information. You picked a room from a set that have certain doors. You want to store that to take into account to generate the adjacent rooms.
And, by the way, if you need large scale path-finding (for something going from a room to another), you can use that grid too.

One specific turtle must stop after visiting specific point

I'm studying NetLogo and have a question about some specific point that I could not find answer. Overall, I am trying to write a program that has these features:
Two country flag
First country flag will move 1.B, 2.C, 3.D from A city (stop at D)
Second country flag will move E from G city
Second country flag will move G from D city
While first country moving these city. The flag drop army (For instance Starting 100k soldier at A . It will 90k at B and C 80k etc.)
When they meet at D city at same time first country flag lose all soldier.
I want to plot the number of soldiers depending on time. Time / Number PLOT
I need only setup and go buttons if it possible.
I am starting with just moving the first flag, based on a program that is included in the library.
In this part I am trying to create different cities with different locations.
to setup
clear-all
set-default-shape houses "house"
;; CREATE-ORDERED-<BREEDS> distributes the houses evenly
create-ordered-houses number-of-city
[ setxy 5 4 ] ;; B
create-ordered-houses number-of-city
[ setxy 1 4 ] ;; C
create-ordered-houses number-of-city
[ setxy 11 6 ] ;; D
In this part I'm trying to create flags
create-people number-of-people [
setxy -8 10 ;; A city for first flag
set target one-of houses
facexy 5 4
This is the part I'm trying to understand (Copied from library ). It's about movement of the first flag.
ask people [
;; if at target, choose a new random target
if distance target = 0
[ set target one-of houses
face target ]
;; move towards target. once the distance is less than 1,
;; use move-to to land exactly on the target.
ifelse distance target < 1
[ move-to target ]
[ fd 1 ]
When I run with this code, the first flag moves to the wrong place. I explain my problem in this picture.
Movement of my first flag
I think you are adapting code that only has one possible target. In that code, it is fine to use one-of to select the target because there's only one choice. In your adaptation, however, there's more than one choice. So when you create the flag in your second block of code...
set target one-of houses
facexy 5 4
... you are choosing a random target from any of the four houses, and then facing house B (which is at 5 4). Let's say the random choice (one-of) picked house C. You flag moves towards B because you told it to face (5 4) and then move forward, but your test for whether it gets close is distance to the target (that is, distance to C if that's the one that was randomly chosen).
Try changing that piece of code to:
set target one-of other houses
facexy target
This code will make the flag go to a randomly selected house that is not the house they are currently at. Since you actually want them to go in a particular order, you will have to do something like give each house a name (that is, create a houses-own attribute to identify each one) and then have the flag do something like set target house with [ name = 'B' ]. However, make this change after you have everything about moving working. Your general approach of adding a little bit at a time is correct - get it moving to any target and then worry about moving to the correct target.

Netlogo: choosing ranked n-of turtles to add to a certain value to a variable

I'm constructing a model to research opinion dynamics given certain network structures. In the model, there is a hypothetical 'dictator' who can hand out resources (or 'bribes') to certain nodes in the network. What I want is that the dictator can choose the top X% of nodes in the model who have the most positive opinions. (later I also want to the dictator to choose the nodes with the most network connections)
What's the best way to do this? I'm not sure how to use the n-of command for a 'ranked' n-of. Or is it better to use another term I'm not aware of?
ask n-of ??? turtles [set bribes (bribes + height-of-bribe)]
thanks!
edit:
currently, I have:
foreach sublist sort-on [(- total-motivation)] nodes 0 10 ask nodes [
set bribes (bribes + height-of-bribes)]
but I'm still getting errors. Any thoughts?
Edit 2:
Nevermind. It works. Thanks!
I think you probably want the max-n-of primitive. There is no need to sort and take the first (or last) of the list. You probably want something like
ask max-n-of 10 turtles [total-motivation] [set bribes (bribes + height-of-bribes)]
When you later want the ones with the most links, just put [count my-links] instead of [total-motivation]

NetLogo: comparing neighbors' values

during my model set up on innovation diffusion, another little programming issue occured to me in NetLogo. I would like to model that people more likely learn from people they are alike. Therfore the model considers an ability value that allocated to each agent:
[set ability random 20 ]
In the go procedure I then want them to compare their own ability value with the values from their linked neighbors.
So for example: ability of turtle1 = 5, ability of neighbor1 = 10, ability of neighbor2 = 4. Hence the (absoulute) differences are [ 5, 1]. Hence he will learn more from neighbor2 than from neighbor1.
But I don't know how to approach the problem of asking each single neighbor for the difference. As a first idea, I thought of doing it via a list-variable like [difference1, ..., difference(n)].
So far I only got an aggregated approach using average values, but this is not really consistent with recent social learning theory and might overlay situtations on which the agent has many different neighbors but one who is quite similar to him:
ask turtles
[
set ability random 20
set ability-of-neighbor (sum [ability] of link-neighbors / count link-neighbors)
set neighbor-coefficient (abs (ability - ability-of-neighbor))
;;the smaller the coefficient the more similar are the neighbors and the more the turtle learns from his neighbor(s)
]
Thank you again for your help and advice, and I really appreciate any comments.
Kind regards,
Moritz
I am having a bit of a time getting my head around what you want but here is a method of ranking link-neighbors.
let link-neighbor-rank sort-on [abs (ability - [ability] of myself)] link-neighbors
it produces a list of link neighbors in ascending order of difference of ability.
if you only want the closest neighbor use
let best min-one-of link-neighbors [abs (ability - [ability] of myself)]
I hope this helps.

NetLogo: ask link-neighbors for a tick-counter value

At the moment I am working on an agent-based model about successful innovation diffusion in social networks. So far I am a newbie in agent-based-modeling and programing.
The main idea is to model social learning among farmers, hence the agents decision to adopt an innovation mainly depends on his personal network, meaning that if he is well connected and his neighbours are using the innovation successfully, he will more likely adopt than if he is located remotely in the network.
Beside the network related arguments about social learning, I would like to implement a time dimension, for example the longer the neighbors of an agent use the innovation successfully, the more likely the agent will adopt the innovation as well. But this is exactly the point where I am stuck right at the moment. My goal is to implement the following argument. The Pseudo Code looks like the following so far.
1) a turtles-own tick counter
...
ask turtles
[
ifelse [adopted? = true]
[set ime-adopted time-adopted + 1] [set time-adopted 0]
]
...
2) In a second precedure each agent should check how long his neighbours use this innovation (in terms of "check time-adopted of neighbors").
ask turtles with [not adopted?]
[
[ask link-neigbhors with [adopted?]
[...*(Here I dont know how to ask for the time adopted value)*]
;the agent will then sum up all values he got from his neighbors from "time-adopted"
set time-neighbors-adopted [sum all "time-adopted" values of neighbors]
]
;The agent will then implement these values into his personal utility
;function which determines if he adopts the innovation or not
set utility utiltiy + 0.3 * time-neighbors-adopted
]
Many thanks for your help and advice.
Kind regards,
Moritz
To get the sum of time the neighbors have adopted the innovation you only need one line because Netlogo is amazing.
set time-neighbors-adopted sum [time-adopted] of link-neighbors with [adopted?]
like that

Resources