This is my first attempt to do something "serious" in Netlogo, and I am trying to do the following:
after a certain tick, my turtles start buying stuff and they fill a list of the prices they paid (the list is individual). I would like them to stop buying if the mean of the list stays below a certain threshold for a certain amount of ticks.
My question is: how can I count ticks in such a case?
This is what I thought:
ifelse mean exePriceList < exePrice [set exitList lput who exitList]
[set exitList []]
if length exitList > exitTime [set buy false set sell false set pass
true]
Basically that's what I do: I add an element (I only care of the length of the list) to another list called exitList (which is not a global variable but it's a turtles-own), and I empty the list if the mean becomes higher than the threshold. Then, if the list is longer than the desired amount of ticks, the turtle stops.
It is not working, because the exitList is not filled properly.
What can I do? Is there a smarter way to manage time? This is the code of the whole procedure:
to bull-strategy
ask turtles with [bull = true] [
set color green
if ticks >= HFAentranceTime + startChecking [
if mean exePriceList > exePrice + (exePrice * stopLossBull) [set buy false
set sell false set pass true]
ifelse mean exePriceList < exePrice [set exitList lput who exitList] [set
exitList []]
if length exitList > exitTime [set buy false set sell false set pass
true]
]
]
end
I think I could post the solution to my problem, if someone finds himself in the same situation.
It was just a (pretty basic) error in the code, probably due to inexperience (and/or lack of attention), I only noticed it the following day: there was an "ask" in excess. I asked the turtles to follow a procedure and then, in the procedure, I repeated the "ask" command by mistake.
So basically the turtles were asked to ask things to each other... thus the abnormal increase of the counter.
Thanks for your help.
Related
I have got a data-management problem. I have a database where "EDSS.1","EDSS.2",... represent a numeric variable, scaled from 0 to 10 (0.5 scale), where higher number stand for higher disability. For each EDSS variable, I have a "VISITDATE.1", "VISITDATE.2",...
EDSS
VISITDATE
Now I am interested in assessing the CONFIRMED DISABILITY PROGRESSION (CDP), which is an increased i 1 poin on the EDSS. To make things more difficult, this increment need to be confirmed in the subsequent visit (e.g. EDSS.3) which has to be >= 6 months (which is, VISITDATE.3 - VISITDATE.2 > 6 months.
To do so, I am creating a nested ifelse statement, as showed below.
prova <- prova %>% mutate(
CDP = ifelse(EDSS.2 > EDSS.1 & EDSS.3>=EDSS.2 & difftime(VISITDATE.3,VISITDATE.2,
units = "weeks") > 48,
print(ymd(VISITDATE.2)),0))
However, I am facing the following main problems:
How can I print the VISIT.DATE of my interest instead of 1 or 0?
How can I shift my code to the EDSS.2,EDSS.3, and so on? I am interested in finding all the confirmed disability progressions (CDPs).
Many thanks to everyone who find the time to answer me.
I'm new to NetLogo.
My question is simple. I have a variable, let's call it c , which I need to use in a condition for turtles.
I want this variable c to distribute randomly following a normal distribution inside a range of values (in my case from 0 to +1 ) and I would like to be able to set the mean value and the standard deviation by means of two separate sliders in my interface.
So pratically speaking: Through the sliders I decide the mean and the s.d. , netlogo computes random values according to these charateristics and then these values are used in a mathematical condition, turtles evaluate the condition and only the turtles which satisfy the condition will execute a command (in my case they will just move forward and change color).
I've set the condition thanks to the people who helped my in my last question, now I need to insert this random variable c inside the condition.
I was thinking to use random-normal but apparently it only reports values, I can't use them in my condition.
Hope it was clear.
UPDATE FOLLOWING COMMENT
The example I provided in the first version of the answer (see below) is actually the base (which you have to adapt to your case) of what you need to do in order to have your turtles calculating a value using a normal distribution, and using the result as a condition for moving.
First of all, two important points:
You said "I don't need to report or print anything". Be aware that a reporter in NetLogo is not something that outputs a value to some interface When I used print in my example below it was a completely separate thing: only to provide a minimal but fully working example that would actively show how the computed values could be correctly used in an if-statement ("I need to use those values inside a mathematical condition". The fact that you could see the two sentences being printed in succession in the Command Center was simply a check showing that everything was going smoothly). A reporter is instructions for computing a value, which the agent then “reports” to whoever asked it. For example, random and ticks are reporters, because they give you values that you (or turtles or whoever) can use for your purposes. While random and ticks are primitive reporters, you can create your own reporters with to-report (just as, while forward is a primitive command, you can create your own commands with to).
When you need to draw numbers from a distribution, NetLogo does not create such distribution that is stored somewhere and from which you sample a value every time you need.
On the contrary, every time you need a random value according to a certain distribution, you will have to generate the value using one of the random reporters.
In your case, you will have the distribution's mean and standard deviation as global variables (which you will set with sliders, but for practical purposes I'm setting them here in-code since there are no sliders on SO).
Also, I understand that your turtles will have some turtles-own variable(s) that they will use in the calculation.
Good, all you need to do is to use to-report and write there the calculation that you want (which will include both the random value generated with random-normal according to the sliders, and the turtles-own variable which will be passed as input) in order to obtain the-value. The procedure you create with to-report will have to use report in order to actually make that value usable by agents (see here how to use to-report).
Then, if you'll let turtles run that procedure, each of them will be able to use their very own calculated the-value in a condition (each turtle will execute to-report the-value on its own, which means that each turtle will draw a separate randomly-distributed value and will use its own my-variable value when performing the calculation).
As below
globals [
mn ; In the actual project, use a slider to set this.
std ; In the actual project, use a slider to set this.
]
turtles-own [
my-variable ; This represents the turtles-own variable that you want to use in the calculation.
]
to setup
clear-all
set mn 0.5
set std 0.2
create-turtles 10 [
setxy random-xcor random-ycor
set my-variable (random 100)
]
end
to go
ask turtles [
if (the-value > 600) [ forward 10 ]
]
end
to-report the-value
report (random-normal mn std + ln my-variable + my-variable + random-float 1000)
end
Note: I arbitrarily put 600 in the if-statement simply because, with the current example, it is a value that sometimes lets the condition be fulfilled, and some other times doesn't - which means that you'll be able to visually check that sometimes turtles move, and some other times they don't.
FIRST VERSION OF THE ANSWER
random-normal is in fact the right thing to use.
As you said, random-normal only reports a value; so you can just use that value in your condition.
Here are two examples of how to do it.
The two examples are equivalent in practice (as I understand from here), so up to you to adopt the style you prefer.
globals [
mn
std
]
to setup
set mn 0.5
set std 0.2
end
to test
ifelse (random-normal mn std < 0.5)
[print "it's less than 0.5"]
[print "it's at least 0.5"]
end
Or
globals [
mn
std
]
to setup
set mn 0.5
set std 0.2
end
to test
ifelse (the-value < 0.5)
[print "it's less than 0.5"]
[print "it's at least 0.5"]
end
to-report the-value
report random-normal mn std
end
In any case, basically just see (random-normal mean standard-deviation) as any other variable storing a number.
The code examples are gonna be in Lua, but the question is rather general - it's just an example.
for k=0,100 do
::again::
local X = math.random(100)
if X <= 30
then
-- do something
else
goto again
end
end
This code generates 100 pseudorandom numbers between 0-30. It should do it between 0-100, but doesn't let the loop go on if any of them is larger than 30.
I try to do this task without goto statement.
for k=0,100 do
local X = 100 -- may be put behind "for", in some cases, the matter is that we need an 'X' variable
while X >= 30 do --IMPORTANT! it's the opposite operation of the "if" condition above!
X = math.random(100)
end
-- do the same "something" as in the condition above
end
Instead, this program runs the random number generation until I get a desired value. In general, I put all the codes here that was between the main loop and the condition in the first example.
Theoretically, it does the same as the first example, only without gotos. However, I'm not sure in it.
Main question: are these program codes equal? They do the same? If yes, which is the faster (=more optimized)? If no, what's the difference?
It is bad practice to use Goto. Please see http://xkcd.com/292/
Anyway, I'm not much into Lua, but this looks simple enough;
For your first code: What you are doing is starting a loop to repeat 100 times. In the loop you make a random number between 0 and 100. If this number is less than or equal to 30, you do something with it. If this number is greater than 30, you actually throw it away and get another random number. This continues until you have 100 random numbers which will ALL be less than or equal to thirty.
The second code says: Start a loop from 0 to 100. Then you set X to be 100. Then you start another loop with this condition: As long as X is greater than 30, keep randomizing X. Only when X is less than 30 will your code exit and perform some action. When it has performed that action 100 times, the program ends.
Sure, both codes do the same thing, but the first one uses a goto - which is bad practice regardless of efficiency.
The second code uses loops, but is still not efficient - there are 2 levels of loops - and one is based on psuedo-random generation which can be extremely inefficient (maybe the CPU generates only numbers between 30-100 for a trillion iterations?) Then things get very slow. But this is also true for you're first piece of code - it has a 'loop' that is based on psuedo-random number generation.
TLDR; strictly speaking about efficiency, I do not see one of those being more efficient than the other. I could be wrong but it seems the same things is going on.
you can directly use math.random(lower, upper)
for k=0,100 do
local X = math.random(0, 30)
end
even faster.
As I see this pieces of code do the same, but using goto always isn't the best choice (in any programming language). For lua see details here
In a course I am taking we recently had to learn the programming language Scheme. I get all of the basics, which is pretty much all that we have gone though. I'm just having trouble learning to think in the different way that Scheme consists of.
I was given an assignment and really do not even know how to start. I have sat here for a few hours trying to figure out how to even get started, but I'm kind of stumped. For the record, I'm not asking for the code to solve this problem, but more of some thoughts to get me on the right track.
Anyway, here is the gist of the assignment...
We are given a list of ten numbers that represent a voter's votes. The numbers are -1, 0 or 1. Then we are given a list of lists of Candidates, with a name and then ten numbers corresponding to that candidate's votes. These numbers are also -1 0 and 1.
So for example.
'(0 0 0 -1 -1 1 0 1 0 -1)
'(Adams 0 1 -1 0 1 1 0 -1 -1 0 0)
We are asked to implement a function called best_candidates that will take in a list of numbers (Voter) and a list of lists of Candidates. Then we have to compare the votes of the voter against the list of each candidate and return a list of names with the most common votes.
So far, I've come up with a few things. I'm just confused on how I will check the values and retain the name of the voter? I guess I'm still stuck in thinking C/Java and it's making this very tough.
Any suggestions to help get me started?
I would consider this a standard search problem where you're looking for items that have minimal difference (i.e. "the most common").
That is, given a list of items x_0, x_1, ..., x_n, I think you want to write a function that computes a corresponding set of disagreement numbers d_0, d_1, ..., d_n.
Once you can compute these d_i disagreement numbers, find out which one (or ones!) are smallest: these correspond to maximal agreement.
If you can do that, then the corresponding x_i's are the list items you want to collect.
Nothing about the description above is dependent on programming language. If you're more comfortable with another language, code it up in that language first! You should gain enough confidence and understanding of the problem to make the extra work worthwhile. At the very least, you'll have another implementation that you can use to test against your Scheme implementation to make sure you get agreement.
I need to generate 500 numbers, 250 1s and 250 0s, randomly located. Below is what I do now. But it does not feel right while the output is correct.
trialNo=500
RandomSample#Flatten[Table[#, {trialNo/2}] & /# {0, 1}]
I'd actually do something slightly different. Since you're looking for a random permutation of Flatten[{ConstantArray[0,250], ConstantArray[1,250]}], I'd generate the permutation and use Part to get the list you're looking for. As follows,
perm = RandomSample[Range[trialNo]];
Flatten[{ConstantArray[0, trialNo/2], ConstantArray[1, trialNo/2]}][[ perm ]]
This isn't operationally different than what you're doing, but I think it captures mathematically what your trying to accomplish better.
Here is another way to do this.
Round[Ordering[1~RandomReal~#] / N##]& # 500
Now with more magic for the guys in Chat.
Mod[RandomSample#Range##, 2] & # 500