Difficulty in building a self-organized network in NetLogo - network-programming

I'm new to netlogo and I'm trying to build a network where nodes have a random number that changes with each tick, and connect randomly to other nodes. Once the connection is established I need that: if the number between the two nodes is the same then the link crystallizes and changes color, otherwise it is deleted for that tick, the procedure is repeated until all nodes have the same random value.
Thanks in advance

Following the clarification in the comments...
The thing you mentioned can be done in a fairly simple way, so hopefully you can use the explanation and keywords below to browse the NetLogo Manual (and in particular the NetLogo Dictionary) and become fully familiar with what is going on.
First, let's setup a few things
globals [
; You'll probably want to declare these two variables directly
; in the Interface with a slider or something, but here I'll
; set them up from within the Code section.
number-of-turtles
level-of-randomness
]
turtles-own [
my-number
connected?
]
to setup
clear-all
reset-ticks
set-globals
create-turtles number-of-turtles [
setxy random-xcor random-ycor
set connected? false
]
end
to set-globals
set number-of-turtles 500
set level-of-randomness 1000
end
So far you have a number of turtles scattered in their environment, a couple of global variables that everyone can access, and a couple of variables belonging to each turtle to keep track of their state.
Based word for word on what you described, you could go on as:
to go.v1
; This first block of commands below is to get rid of the links that
; emerged in the previous iteration of 'go.v1', but that
; you don't want to keep because they link turtles with
; different 'my-number'. You will also need to include the
; stop condition that best suits you.
ask links with [color != green] [
die
]
; Insert here a stop condition.
ask turtles with [connected? = false] [
set my-number random level-of-randomness
]
; The 'let' command creates a local variable.
ask turtles [
let target one-of other turtles
create-link-with target
; The statement below containing "[who] ..." is how you need to
; call a link: 'who' is a built-in turtle-own variable reporting
; the ID number of the turtle, and to report a link you will need
; to give it the two IDs of the two turtles being connected.
if (my-number = [my-number] of target) [
ask link ([who] of self) ([who] of target) [
set color green
]
if (connected? = false) [
set connected? true
]
if ([connected?] of target = false) [
ask target [
set connected? true
]
]
]
]
tick
end
The code above does what you said: each turtle always creates the link with another turtle, then the condition is tested, and based on that condition (the result of which is stored as the link's color: only the good links become green) the link is kept or eliminated at the beginning of the following iteration of go.v1.
However, although you may have reasons to do it in the way above, you might just be happy with an alternative which requires less computation:
to go.v2
; Insert here a stop condition.
ask turtles with [connected? = false] [
set my-number random level-of-randomness
]
ask turtles [
let target one-of other turtles
if (my-number = [my-number] of target) [
create-link-with target [
set color green
ask both-ends [
if (connected? = false) [
set connected? true
]
]
]
]
]
tick
end
This way, turtles evaluate the potential companion before creating any link, and they only proceed to create it if my-number is the same.
That way, there is no need to create and then eliminate all the unwanted links (and the my-number condition had to be tested anyway even in go.v1).

Related

How to skip some input parameters' set in MT4 StrategyTester optimization mode, if constraints were not met?

I've 3 different input parameters : P1 [1..10], P2 [1..10] and P3 [3..10]. The constraints are the following : P1 < P2 < P3.
Some potential solutions should be discarded right away when the constraints are not respected. For instance when P1 = 2, P2 = 1 and P3 = 4.
Is there a way to accomplish such thing with MetaTrader optimization ?
( eventually using an OnTesterPass() function ? )
I'm losing a lot of time during my optimization because of that and I'd like to find a way to discard or skip directly the potential solution when the constraints are not respected.
Thanks for your help
int OnInit(){
if(P1<P2 && P2<P3){} // OK
else{
printf("%i %s - parameters SKIPPED, !(P1<P2<P3)",__LINE__,__FUNCTION__);
return(INIT_FAILED);
}
}
That is all.
The printf() is not called during optimization.
Either INIT_FAILED or INIT_PARAMTERS_INCORRECT stop the optimization of a particular set and the [ MT4 Strategy Tester ] goes right to the next set of parameters.
You do not need OnTesterPass() because it is called after test is done, OnInit() is automatically called Event-handler right upon entering a new set of optimisation parameters into such a test run.

Converting list into agents in foreach loop

Here is a fraction of code that cause trouble.
to update-trustt
let rank-tvmratio sort-on [tvmratio] turtles
foreach rank-tvmratio tvmratio -> ask rank-tvmratio [set trustt (trustt + tvmratio)]
end
In this code, "rank-tvmratio" is supposed to bring list which looks like :
[(turtle 56) (turtle 23) ... (turtle 9)]
What I want to do is to make each of those turtles to update "trustt" variable
respectively, which is written in the 3rd line.
Following Bryan's advice I inserted "->" and specified "who" is doing "what".
Still, there's a new error message "Nothing name -> has been defined"
How can I solve this problem? I need your wise advice.
(Actually variable tvmratio is coming from program R, using RNetLogo package. Is that have something to do with this?)
Thank you
I think this is probably want you're looking for:
to update-trustt
let rank-tvmratio sort-on [tvmratio] turtles
foreach rank-tvmratio [ t ->
ask t [
set trustt (trustt + rank-tvmratio)
]
]
end
There was a couple problems with your code. First, the command given to foreach needs to include an argument. You do this with the -> syntax. The t (for turtle) before the -> is the variable that each item in the list will be passed in as. Second, you need to explicitly ask t since foreach, unlike ask, doesn't have the agents run the command, it just runs the command with the items passed in one at a time as the argument to the command.

NETLOGO: Making network with exact number of links

I need to do the network when agents will be connected with links and i want it make so that there will be exact number (variable) of links going from each agent. Lets say for example that i want 3 links going from each agent to another. No more, no less. I was trying to use this code:
let num-links (links * number) / 2
while [count links < num-links ]
[
ask one-of turtles
[
let choice (min-one-of (other turtles with [not link-neighbor? myself])
[distance myself])
if choice != nobody [ create-link-with choice ]
]
]
Where "number" is the number of nodes and "links" is number of links i want to go from each agent- But this code unfortunately works so that "links" is really just an average degree of node. So if I want 3 links, i could get all agent (except for example two) with 3 links going from them, but one of them would have only 1 link and another 5 (average is 3 then). Is there some way How to do it.
And is there some way how to do it so that each "link" would be actually two directed links, one going from the node and one going to the node?
And one last question. I want to give this links a variable, but i need to do it so that sum of these variables from each agent is exactly 100 (as percents).
Any help? Thank you very much.
Here is how I create a fixed degree network for a small network (easy to understand)
to make-legal
create-turtles 100 [setxy random-xcor random-ycor]
let target-degree 5
while [ min [ count my-links ] of turtles < target-degree ]
[ ask links [die]
makeNW-Lattice target-degree
]
end
to makeNW-Lattice [DD]
ask turtles
[ let needed DD - count my-links
if needed > 0
[ let candidates other turtles with [ count my-links < DD ]
create-links-with n-of min (list needed count candidates) candidates
]
]
end
See NetLogo Efficient way to create fixed number of links for more efficient methods for larger networks.
Please ask separate questions for separate issues
UPDATE to ensure all nodes have required degree, in response to comment
Based on the following code, the basic generator does a legal network a little under 50% of the time. Therefore I simply threw the original code in a while loop and regenerated if not legal. This is not a good solution for larger networks, but is a reasonable hack.
to setup
let mins (list 0 0 0 0 0 0)
repeat 100
[ ask turtles [die]
ask links [die]
makeNW-lattice
let this-min min [ count my-links ] of turtles
set mins replace-item this-min mins (item this-min mins + 1)
]
print mins
end

New lines in word definition using interpreter directives of Gforth

I am using the interpreter directives (non ANS standard) control structures of Gforth as described in the manual section 5.13.4 Interpreter Directives. I basically want to use the loop words to create a dynamically sized word containing literals. I came up with this definition for example:
: foo
[ 10 ] [FOR]
1
[NEXT]
;
Yet this produces an Address alignment exception after the [FOR] (yes, I know you should not use a for loop in Forth at all. This is just for an easy example).
In the end it turned out that you have to write loops as one-liners in order to ensure their correct execution. So doing
: foo [ 10 [FOR] ] 1 [ [NEXT] ] ;
instead works as intended. Running see foo yields:
: foo
1 1 1 1 1 1 1 1 1 1 1 ; ok
which is exactly what I want.
Is there a way to get new lines in the word definition? The words I would like to write are way more complex, and for a presentation I would need them better formatted.
It would really be best to use an immediate word instead. For example,
: ones ( n -- ) 0 ?do 1 postpone literal loop ; immediate
: foo ( -- ten ones ) [ 10 ] ones ;
With SEE FOO resulting in the same as your example. With POSTPONE, especially with Gforth's ]] .. [[ syntax, the repeated code can be as elaborate as you like.
A multiline [FOR] would need to do four things:
Use REFILL to read in subsequent lines.
Save the read-in lines, because you'll need to evaluate them one by one to preserve line-expecting parsing behavior (such as from comments: \ ).
Stop reading in lines, and loop, when you match the terminating [NEXT].
Take care to leave >IN right after the [NEXT] so that interpretation can continue normally.
You might still run into issues with some code, like code checking SOURCE-ID.
For an example of using REFILL to parse across multiple lines, here's code from a recent posting from CLF, by Gerry:
: line, ( u1 caddr2 u2 -- u3 )
tuck here swap chars dup allot move +
;
: <text>  ( "text" -- caddr u )
here 0
begin
refill
while
bl word count s" </text>" compare
while
0 >in ! source line, bl c, 1+
repeat then
;
This collects everything between <text> and a </text> that's on its own line, as with a HERE document, while also adding spaces. To save the individual lines for [FOR] in an easy way, I'd recommend leaving 0 as a sentinel on the data stack and then drop SAVE-MEM 'd lines on top of it.

How to PARSE a sequence of items where items not in blocks are handled like single element blocks?

I've got a situation where I want an equivalence, such that:
[
{Foo}
http://example.com/some/stuff.html
separator
]
...is handled just as if you had written:
[
[{Foo}]
[http://example.com/some/stuff.html]
[separator]
]
Adding a little to the complexity is that if you put the item in a block, then it can have arguments:
[
[{Foo} /some-refinement]
[http://example.com/some/stuff.html {stuff caption} 3]
[separator dashed-line]
]
I'd like a PARSE-based engine that can run the same handler for {Foo}, [{Foo}], and [{Foo} /some-refinement] (let's call it STRING-HANDLER), and have it merely invoked with the right number of parameters.
To write this without PARSE is easy... a single element is wrapped in a temporary block (in the case it's not a block). Then the first item is tested in a CASE statement. But I'd like to convert this to be PARSE-based, where one branch uses INTO while another does not, without repeating code.
It will need to support nesting, so you might wind up processing something like:
[http://example.com/some/stuff.html [{Foo} /some-refinement] 3]
I hope the following can be the basis for your solution.
The following performs exactly the same in both R2 and R3. PARSE's 'into operation is VERY different between the two so I put a simple guard [.here.: block! :.here.] which fixes different bug situations in both platforms.
I used hook functions which allow to cleanly separate the data browsing from the data evaluation. If you look closely, you will notice that the =enter-block?=: rule is global and that the code which switches its meaning is setup BEFORE running the emit-value function... so in some cases, you might actually want to use emit-value to setup a different rule.
note that I'm not assuming any kind of known structure as your explanation seems to be meant for unstructured datasets.
Also note that test B is setup as a string, so we can use the wrapper directly on string input data:
rebol [
author: "Maxim Olivier-Adlhoch"
date: 2014-02-08
license: "public domain"
]
A: [
[{Foo}]
[http://example.com/some/stuff.html]
[separator]
]
B: {[
{Foo}
http://example.com/some/stuff.html
separator
]}
C: [
[{Foo} /some-refinement]
[http://example.com/some/stuff.html {stuff caption} 3]
[separator dashed-line]
]
D: [http://example.com/some/stuff.html [{Foo} /some-refinement] 3]
depth: ""
enter-block: func [][
prin depth
print "["
append depth "^-"
]
quit-block: func [][
remove depth
prin depth
print "]"
]
emit-value: func [value][
prin depth
probe value
]
=enter-block?=: none
=block=: [
(
=enter-block?=: [into =block=] ; we enter blocks by default
enter-block
)
some [
.here.: block! :.here. ; only enter blocks (R3/R2 compatible)
(if 1 = length? .value.: first .here. [ =enter-block?=: [skip] emit-value first .value. ])
=enter-block?=
| set .value. skip ( emit-value .value. )
]
(quit-block)
]
STRING-HANDLER: func [data][
if string? data [
data: load data
]
parse data =block=
]
STRING-HANDLER A
STRING-HANDLER B
STRING-HANDLER C
STRING-HANDLER D
ask "press enter to quit ..."

Resources