CO538 Anonymous Questions and Answers Keyword Index |
This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.
To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.
Keyword reference for random
2012 |
Submission reference: IN2208
I have been trying for a while to try and use the random function to generate random eating values. I cannot see an issue with my code, but strangely when running it will run for a short time and then it will just seem to freeze. My code for this section is as follows.
... [snip code] PROC philosopher (VAL INT id, seed, CHAN BOOL left!, right!, down!, up!, SHARED CHAN P.PHIL report!) INITIAL INT t.seed IS seed: INITIAL INT e.seed IS seed: INT pID: INT thinkMax: INT eatMax: INT thinkTime: INT eatTime: SEQ thinkMax := max.think.time MINUS min.think.time eatMax := max.eat.time MINUS min.eat.time pID := 42*id e.seed := e.seed PLUS pID t.seed := t.seed PLUS pID WHILE TRUE SEQ eatTime, e.seed := random(eatMax, e.seed) thinkTime, t.seed := random(thinkMax, t.seed) eatTime := eatTime + min.eat.time thinkTime := thinkTime + min.think.time ... [snip code] pause(thinkTime * second) ... [snip code] pause(eatTime * second) :
According to my understanding, this should take the seed (which is the seed generated in PROC q7) add to this pID and then use this seed to generate a value between 0 and (max-min) for that particular process. It should add the minimum value to this thus giving me a range between the maximum and minimum values.
This then is passed to pause (which is taken from exercise q4) as its value * second (which is declared at the top of the file we were given as VAL INT second IS 1000000).
The issue seems to be with the random value generated as I changed eatTime and thinkTime to actual int values and it seems to work fine.
If my understanding is incorrect could you tell me where i'm going wrong and if my understanding is correct help me figure out why it isn't working as it should. I've been staring at this for two days now.
The code you have there looks sensible, and yes, random does behave in mostly the way you think. However, the two seed values here (e.seed and t.seed) will be the same: they start the same and go through random() in the same way together. You only really need one random seed here, rather than two. That though should not produce any odd behaviours; if the '.think.time' and '.eat.time' constants are the same, then the thinking and eating delays will be the same, which may look a little odd in the display, but shouldn't produce overly long pauses. Check the values for these though, which should sensibly be expressed in seconds.
It's possible that you have some sort of deadlock, which is only arising a result of particular timings of interaction (more likely to happen with random timeouts than without). Check the usage of CLAIM blocks in particular, the only thing inside these should be outputs on the particular shared channel (in this program) — trying to do other things may lead to deadlocks as other processes won't be able to claim that shared channel at the same time.
Failing that, mail your code to your seminar leader to have a quick look for obvious errors.
2011 |
Submission reference: IN2078
hye, ive been racking my brains for ages trying to figure out hows to set the minuum number in the randm feature, ive set the maximum, but at the minute i have an if statement that checks whether the number is big enough, and if not, gnerates another one, i can't help thinking that there is a better way of doing this thhats more efficient.
PLEASE make an attempt to write English when asking these questions. Writing is an important part of the engineering process and correct use of spelling and grammar is necessary in order to be understood. English (and all natural language) is imprecise and full of ambiguities even when well written. Poor English makes things so much worse. When working for real money, poor English will not be accepted! (End of rant.)
To choose a number randomly between min and max, you are correct to be concerned that using an IF (or some loop) is inelegant and inefficient. Instead: use the random function to choose a number randomly between 0 and (max - min) and, then, add min to it.
Referrers: Question 47 (2011)
Submission reference: IN2069
This question is related to the dining philosophers project. Currently as it stands the philosophers and forks individually print to the screen when claimed ("thinking, eating, on.table, left.held, right.held") and the security prints the number of philosophers sitting. Theoretically this works however, I am having issues making the philosophers behave randomly as at the moment they do indeed act randomly but the process is rendering really fast for anything to be visibly coherent.
I am using the pause (INT delay) process used in previous exercises to cause the thinking and eating delays, but making this random and at a speed comprehensible is difficult and something I cannot seem to gain.
The following code fragment is from my philosopher process up to claiming the shared report channel to think:
... code omitted thinking, s:= random (15, s) ... code omitted pause (thinking) ... code omitted
Your call to random returns a pseudo-random integer between 0 and 14. Your call to pause with that value means a delay of somewhere between 0 and 14 microseconds! Try:
thinking, s:= random (15*SECONDS, s)
where:
VAL INT SECONDS IS 1000000:
2008 |
Submission reference: IN1628
I've read through the previous answers, but I'm still having trouble setting the seed. I understand that the seed is declared in the q7 process in order to receive a value from the keyboard, so are we expected to find a way of passing the seed to the philosophers from within the q7 process? Also, should our animation (modelled on a7-basic) still work without the seed set?
I don't understand what you mean by: "the seed is declared in the q7 process in order to receive a value from the keyboard"?
A seed should be declared and initialised in the q7 process in order to pass unique seeds to the philosophers, which they use in generating random numbers for setting randomised thinking and eating periods. Code for declaring and initialising such a seed is given in your starter file.
Passing the seed to the philosophers is easy: pass it (as a VAL INT parameter) to secure.college and secure.college passes it on (as a VAL INT parameter)to each philosopher, when it instances each philosopher (in a replicated PAR).
The secure.collegeshould also pass a unique id number to each philosopher. Adding that id to its given seed results in a unique seed for each philosopher.
Everyone should trawl through the anon Q&As for information. For instance, check out the keyword index pages for random and q7 and use your browser to search for "seed". You may find Question 55 (2006) particularly helpful.
Finally, if you don't set a seed and pass it on properly, your animation will not be randomised. The random number function requires a seed argument and returns an updated seed value as the second part of its answer (the first part being, of course, the random number it choose for you). Make sure you know how to use this function properly.
2007 |
Submission reference: IN1351
I have a bit of a problem in terms of the random
function.
I've read through the answers on here already concerning this function,
but when I use it ... it always seems to return the initial seed.
I have the following code to make the robot turn a random amount:
INT number: VAL INT maxvalue IS 30: INITIAL INT seed IS 15: IF some.condition SEQ ... code omitted number, seed := random (maxvalue, seed) ... code omitted other.condition ... whatever
I'm pretty sure it's always getting the same number. Have I used it in the correct way?
If that really is an extract from your code, then no!
If the above is inside some loop, each time round the seed
is re-declared and re-initialised to 15
.
So, that number is presented each time as the seed to the random
function and each time it will compute the same results – not very random!
Your three declarations must be made just the once, before entering the loop:
INT number: VAL INT maxvalue IS 30: INITIAL INT seed IS 15: SEQ ... any other initialisation code WHILE still.running SEQ ... stuff IF some.condition SEQ ... code omitted number, seed := random (maxvalue, seed) ... code omitted other.condition ... whatever
Now, the first time around, random
will be called with
a seed value of 15
.
But it returns two values: one is the pseudo-random number
computed and the other is an updated value for the seed.
The next time around, random
will be called with that
updated seed ... and so on.
Note: please see Question 55 (2006) about warming up the random number generator (which is simple and effective, but you have to treat it right) first! See also this same question and Question 79 (2003) for clues about better ways to set the initial value for the random number seed.
2006 |
Submission reference: IN1029
Am I defining my random numbers seeds correctly?
PROC philosopher (VAL INT id, CHAN BOOL left!, right!, down!, up!, CHAN INT state!) INT waiting.time, seed: TIMER tim: SEQ tim ? seed seed := (seed >> 2) + (id + 1) WHILE TRUE ... :
The philsophers all seem to start off with the same thinking time? So I'm a bit confused as to what I've done wrong.
All your philosophers will start in the same few microseconds – possibly all in the
same microsecond! So, all get the same initial seed
value from the timer.
That is shifted right by 2 bits, which makes it positive but also makes it even more
likely the result (so far) is the same. Finally, the philospher's id
,
plus 1, is added which makes it very likely they all go into their loops with different
seed
s. However, if philosophers with lower id
s were scheduled
after those with higher ones, they could still go into their loops with the same
seed
s.
To ensure they start with different seeds, compute an initial seed just once
(using the timer, as in your code above) and before starting any philosophers
(e.g. before starting the whole college). Pass this same initial seed into each
philosopher and get them to add in their id
number. Now, each philosopher
is guaranteed to start its loop with a different seed.
However, random number generation is a black art. Starting from consecutive initial
seeds, it takes some of them (like the cheap-but-fast one used by the course library's
random
function) a little while to diverge. So, I'm not surprised they all
start off with the same thinking time.
To combat that, warm up your generator before first using it! Here is an example routine to do that:
PROC warm.up.random (VAL INT warm.up.count, INT seed) SEQ i = 0 FOR warm.up.count INT dummy: dummy, seed := random (42, seed) :
A warm.up.count
of 1000
will suffice.
Referrers: Question 29 (2008) , Question 33 (2007)
2005 |
Submission reference: IN629
Hi, I was just wondering what kind of delays should we put in between the philosophers thinking and eating. If we set them to eat for longer than think, then you'll see the security flag up as a 5th tries to sit, however if you set them to think for longer then you'll very rarely see the security go up, if at all. What should the time delays roughly be?
The delays should be random. See the other questions under the random keyword for details on how to use it.
However, you are right that the eating times should be a bit longer, mostly, than the thinking times ... to get a chance to see a hungry philosopher who is blocked by security.. Suggest making eating times random between 6 and 15 seconds, with the thinking times random between 2 and 8 seconds. If the action still seems a bit slow, reduce by a factor of 10 - experiment!
2003 |
Having problems with q7. In our seminar we were told to use:
i, seed := random (n, seed)
to create a random number. Can you explain what each of the elements are, also can you give a basic example.
This part of the Philosopher proc is going to be a base for all 5 philosophers, but there is the problem of each having the same random number for each one. Do we need to have a different value of `n' and `seed' each time the PROC is run? Or is this dealt with by the random function ?
The `seed' is there to initialise the random number generator. More specifically, it is the internal state of the `random' function -- functions cannot retain their own state.
Before you call `random' for the first time, you need to initialise `seed' to a number between 1, and the maximum positive integer minus one. When you call `random' for a second time, use the new `seed' returned by the first call, and so on.
Yes, you need a different starting seed for each philosopher (hint: each philosopher has a different `id').
`n' is the range of the random number generated. i.e. `random' will return a random value between 0 and (n-1); in your example, assigned to `i'.
Referrers: Question 33 (2007)
2002 |
Could you please explain a little more how you would go about implementing the random time delay? I have read through the previous questions on it but I'm still a little lost. Is the time delay between philosophers doing different actions or in the display process?
It's in the philosopher processes - not the display.
The question says:
Thinking and eating by the philosophers should be modelled by random (but finite!) delays
In the "philosopher" process there are two folds:
<!--{{{ think--> SKIP <!--}}}-->
and:
<!--{{{ eat--> SKIP <!--}}}-->
You should replace the SKIPs by random delays.
Keywords: q7 , random , timers
The random function says that it needs an integer at least 1. At the moment my seed is:
id + modified.time
I know that my id can equal zero. You said that time could be negative, so I assume that it can equal zero as well. At the moment my modified time is:
t /\ #7FFFFFFC
I have a vague understanding ofhow this works, but it looks to me that my modified.time can equal zero aswell, making it possible to break the random function. Do I need to change the bitvalue that I /\ with t?
Your id and the timer value could both be zero - the latter could be negative as well! So, your concerns about the ideas above are valid. Check out the answer to Question 69 (2000), especially David Wood's suggestion at the end.
On a general point, you are strongly advised to browse through the anonymous questions and answers from previous years. On animating the Dining Philosophers, there was much discussion and plenty of good advice. For example, look at Question 68 (2000) ... and lots of others.
2001 |
The function:
random (maxvalue, seed)
returns an (INT, INT) value. How can I assign the first INT in the pair to one variable, and the second to another? I have tried:
INT number, seed: SEQ ... (number, seed) := random (maxvalue, seed)
But I imagined it would cause an error ... and it did.
If you look at the syntax of the function declaration:
INT, INT FUNCTION random (VAL INT upto, seed)
you will see that it returns an INT, INT - i.e. no brackets! The correct syntax, therefore, is:
number, seed := random (maxvalue, seed)
For further information on this function, see Question 77 (2000). For general questions about animating the Dining Philosphers' problem, see last year's Question 66 (2000) onwards.
2000 |
Ok, I am confused. What's the deal with all the seed things? Also what's the deal with the animation? Where can I find some examples of some coding for screen display?
[I'm combining this question with the following one (PHW)]
Please could you tell me how to generate a random number in occam? I've forgotten and can't find it in the notes. Thanks.
All these things have been explained in your seminar groups. I'll just point you at Question 76 (2000) for information about implementing the screen display and:
/usr/local/work/co516/libsrc/random.occ
for information about the random number generating FUNCTION, for which you need to set up and maintain a seed variable.
Referrers: Question 21 (2001)
In a post, Fred says that the maximum negative 32 bit int is -2147483648, so I have coded appropriately ...
-- ensure seed is positive & legal IF seed = (-2147483648) <---------ERROR!!! seed := 2147483647 seed < 0 seed := -seed seed = 0 seed := 1 TRUE SKIP
But I get an error on the line arrowed above which says:
Overflow when evaluating constant expresssion
Help!! Have I done something wrong or is the info on cs2 wrong?
The compiler treats -2147483648 as an expression, so it gets an error when trying to evaluate 2147483648 (which is larger than the largest INT). If it got past that, it would get another error trying to negate it.
occam has a special way of naming the largest and smallest of any of its number types. For example,
MOSTNEG INT MOSTPOS INT
give you, respectively, the most negative and positive integers. Other ways we can write MOSTNEG INT are:
#80000000 1 << 31
But ... my colleague, David Wood, suggests you might like to consider:
TIMER tim: INT seed: SEQ tim ? seed seed := (seed >> 2) + 1
Keywords: inverting , int , random , q7
Referrers: Question 29 (2002)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. |