NetLogo: the meaning of TO-REPORT explained for dummies? - report

I have a problem to understand the role of to-report and report in NetLogo, even it seems pretty useful and I can't really find a help written in "human style" language.
In NetLogo dictionnary http://ccl.northwestern.edu/netlogo/docs/dictionary.html#report I can find definitions for to-report :
to-report procedure-name
to-report procedure-name [input1 ...]
Used to begin a reporter procedure.
The body of the procedure should use report to report a value for the procedure. See report.
and for report:
report value
Immediately exits from the current to-report procedure and reports value as the result of that procedure. report and to-report are always used in conjunction with each other. See to-report for a discussion of how to use them.
So, it seems to-report and report calculate some value and report it.
Thus, when I try add
to-report average [a b c]
report (a + b + c) / 2
end
to my code, and then use the average variable somewhere in my code p.e.:
to go
...
print average
tick
end
I've got an error: AVERAGE expected 3 inputs. When I try to create my variables [a b c] in globals [a b c] I've got an error There is already a global variable called A.
If I define my variables [a b c] within to-report procedure:
to-report average [a b c]
set a 1
set b 2
set c 3
report (a + b + c) / 2
end
My error is again AVERAGE expected 3 inputs.
Thus, how can I simply test the usefulness of to-report procedure? And where to place it correctly in my code to see what it is really doing? From Urban Suite - Economic Disparity (http://ccl.northwestern.edu/netlogo/models/UrbanSuite-EconomicDisparity) I see that to-report is used to calculate values related to each patch:
to-report patch-utility-for-poor
report ( ( 1 / (sddist / 100 + 0.1) ) ^ ( 1 - poor-price-priority ) ) * ( ( 1 / price ) ^ ( 1 + poor-price-priority ) )
end
however this reported value is not directly defined as patch variable which increase my confusion...
Thank you !

A function can take some input (usually one or more variables or values) and return some output (usually a single value). You can specify that a function returns a value using to-report in your function header and report returns the actual value.
Your error is due to the fact that you never passed in arguments to your average function
to go
...
print average
tick
end
should be
to go
...
print average 5 2 3 ;;a = 5, b = 2, c =3
tick
end
Inside your average function, you should not reassign values of a,b,and c.
You should use report whenever you want to return a result from a function.

Related

The Eight-Queen Puzzle in Programming in Lua Fourth Edition

I'm currently reading Programming in Lua Fourth Edition and I'm already stuck on the first exercise of "Chapter 2. Interlude: The Eight-Queen Puzzle."
The example code is as follows:
N = 8 -- board size
-- check whether position (n, c) is free from attacks
function isplaceok (a, n ,c)
for i = 1, n - 1 do -- for each queen already placed
if (a[i] == c) or -- same column?
(a[i] - i == c - n) or -- same diagonal?
(a[i] + i == c + n) then -- same diagonal?
return false -- place can be attacked
end
end
return true -- no attacks; place is OK
end
-- print a board
function printsolution (a)
for i = 1, N do -- for each row
for j = 1, N do -- and for each column
-- write "X" or "-" plus a space
io.write(a[i] == j and "X" or "-", " ")
end
io.write("\n")
end
io.write("\n")
end
-- add to board 'a' all queens from 'n' to 'N'
function addqueen (a, n)
if n > N then -- all queens have been placed?
printsolution(a)
else -- try to place n-th queen
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c -- place n-th queen at column 'c'
addqueen(a, n + 1)
end
end
end
end
-- run the program
addqueen({}, 1)
The code's quite commented and the book's quite explicit, but I can't answer the first question:
Exercise 2.1: Modify the eight-queen program so that it stops after
printing the first solution.
At the end of this program, a contains all possible solutions; I can't figure out if addqueen (n, c) should be modified so that a contains only one possible solution or if printsolution (a) should be modified so that it only prints the first possible solution?
Even though I'm not sure to fully understand backtracking, I tried to implement both hypotheses without success, so any help would be much appreciated.
At the end of this program, a contains all possible solutions
As far as I understand the solution, a never contains all possible solutions; it either includes one complete solution or one incomplete/incorrect one that the algorithm is working on. The algorithm is written in a way that simply enumerates possible solutions skipping those that generate conflicts as early as possible (for example, if first and second queens are on the same line, then the second queen will be moved without checking positions for other queens, as they wouldn't satisfy the solution anyway).
So, to stop after printing the first solution, you can simply add os.exit() after printsolution(a) line.
Listing 1 is an alternative to implement the requirement. The three lines, commented respectively with (1), (2), and (3), are the modifications to the original implementation in the book and as listed in the question. With these modifications, if the function returns true, a solution was found and a contains the solution.
-- Listing 1
function addqueen (a, n)
if n > N then -- all queens have been placed?
return true -- (1)
else -- try to place n-th queen
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c -- place n-th queen at column 'c'
if addqueen(a, n + 1) then return true end -- (2)
end
end
return false -- (3)
end
end
-- run the program
a = {1}
if not addqueen(a, 2) then print("failed") end
printsolution(a)
a = {1, 4}
if not addqueen(a, 3) then print("failed") end
printsolution(a)
Let me start from Exercise 2.2 in the book, which, based on my past experience to explain "backtracking" algorithms to other people, may help to better understand the original implementation and my modifications.
Exercise 2.2 requires to generate all possible permutations first. A straightforward and intuitive solution is in Listing 2, which uses nested for-loops to generate all permutations and validates them one by one in the inner most loop. Although it fulfills the requirement of Exercise 2.2, the code does look awkward. Also it is hard-coded to solve 8x8 board.
-- Listing 2
local function allsolutions (a)
-- generate all possible permutations
for c1 = 1, N do
a[1] = c1
for c2 = 1, N do
a[2] = c2
for c3 = 1, N do
a[3] = c3
for c4 = 1, N do
a[4] = c4
for c5 = 1, N do
a[5] = c5
for c6 = 1, N do
a[6] = c6
for c7 = 1, N do
a[7] = c7
for c8 = 1, N do
a[8] = c8
-- validate the permutation
local valid
for r = 2, N do -- start from 2nd row
valid = isplaceok(a, r, a[r])
if not valid then break end
end
if valid then printsolution(a) end
end
end
end
end
end
end
end
end
end
-- run the program
allsolutions({})
Listing 3 is equivalent to List 2, when N = 8. The for-loop in the else-end block does what the whole nested for-loops in Listing 2 do. Using recursive call makes the code not only compact, but also flexible, i.e., it is capable of solving NxN board and board with pre-set rows. However, recursive calls sometimes do cause confusions. Hope the code in List 2 helps.
-- Listing 3
local function addqueen (a, n)
n = n or 1
if n > N then
-- verify the permutation
local valid
for r = 2, N do -- start from 2nd row
valid = isplaceok(a, r, a[r])
if not valid then break end
end
if valid then printsolution(a) end
else
-- generate all possible permutations
for c = 1, N do
a[n] = c
addqueen(a, n + 1)
end
end
end
-- run the program
addqueen({}) -- empty board, equivalent allsolutions({})
addqueen({1}, 2) -- a queen in 1st row and 1st column
Compare the code in Listing 3 with the original implementation, the difference is that it does validation after all eight queens are placed on the board, while the original implementation validates every time when a queen is added and will not go further to next row if the newly-added queen causes conflicts. This is all what "backtracking" is about, i.e. it does "brute-force" search, it abandons the search branch once it finds a node that will not lead to a solution, and it has to reach a leaf of the search tree to determine it is a valid solution.
Back to the modifications in Listing 1.
(1) When the function hits this point, it reaches a leaf of the search tree and a valid solution is found, so let it return true representing success.
(2) This is the point to stop the function from further searching. In original implementation, the for-loop continues regardless of what happened to the recursive call. With modification (1) in place, the recursive call returns true if a solution was found, the function needs to stop and to propagate the successful signal back; otherwise, it continues the for-loop, searching for other possible solutions.
(3) This is the point the function returns after finishing the for-loop. With modification (1) and (2) in place, it means that it failed to find a solution when the function hits this point, so let it explicitly return false representing failure.

Simple subtraction in Verilog

I've been working on a hex calculator for a while, but seem to be stuck on the subtraction portion, particularly when B>A. I'm trying to simply subtract two positive integers and display the result. It works fine for A>B and A=B. So far I'm able use two 7-segment displays to show the integers to be subtracted and I get the proper difference as long as A>=B
When B>A I see a pattern that I'm not able to debug because of my limited knowledge in Verilog case/if-else statements. Forgive me if I'm not explaining the best way but what I'm observing is that once the first number, A, "reaches" 0 (after being subtracted from) it loops back to F. The remainder of B is then subtracted from F rather than 0.
For example: If A=1, B=3
A - B =
1 - 1 = 0
0 - 1 = F
F - 1 = E
Another example could be 4-8=C
Below are the important snippets of code I've put together thus far.
First, my subtraction statement
always#*
begin
begin
Cout1 = 7'b1000000; //0
end
case(PrintDifference[3:0])
4'b0000 : Cout0 = 7'b1000000; //0
4'b0001 : Cout0 = 7'b1111001; //1
...
4'b1110 : Cout0 = 7'b0000110; //E
4'b1111 : Cout0 = 7'b0001110; //F
endcase
end
My subtraction is pretty straightforward
output [4:0]Difference;
output [4:0] PrintDifference;
assign PrintDifference = A-B;
I was thinking I could just do something like
if A>=B, Difference = B-A
else, Difference = A-B
Thank you everyone in advance!
This is expected behaviour of twos complement addition / subtraction which I would recommend reading up on since it is so essential.
The result obtained can be changed back into an unsigned form by inverting all the bits and adding one. Checking the most significant bit will tell you if the number is negative or not.

How many times does this recursive function iterate?

I have a recursive function, as follows, where b >= 0
def multiply(a,b):
if b == 0:
return 0
elif b % 2 == 0:
return multiply(2*a, b/2)
else:
return a + multiply(a, b-1)
I would like to know how many times the function will run in terms of a and b.
Thanks.
If binary representation of b (call it B) ends with 1, like xxxx1 than next call to multiply has B = xxxx0.
If B ends with 0, like xxxx0 than next value of B is xxxx.
With that, digit of binary representation of b adds one call if it is 0, and two calls if it is 1. Summing that total number of calls equals to length of initial B + number of ones in initial B.
I might be wrong here, but I think your function does not work the way you intend it. In recursion the most important thing as a propper ending criteria, since it will run forever elseways.
Now your ending criteria is a==0, but with each recursive call you do not decrease a. Just make a pen & paper simulation with a=5 and check if it would stop at any point.

Explain the recursion in this algorithm?

I know this algorithm is for finding the majority element of any array if it has any. Can any one please explain the recursion calls?
if length(A) = 0 then
return null
end if
if length(A) = 1 then
return 1
end if
// "Command 7"
Call FIND-MAJORITY recursively on the first half of A, and let i be the result.
// "Command 8"
Call FIND-MAJORITY recursively on the second half of A, and let j be the result.
if i > 0 then
compare i to all objects in A(including itself);
let k be the number of times that equality holds;
if k > length(A)/2 then
return i.
end if
end if
if j > 0 then
compare j to all objects in A(including itself);
let k be the number of times that equality holds;
if k > length(A)/2 then
return j
end if
end if
return null
Is command 7 is executed until it get an single value ... and then command 8? I cannot understand these recursions. Please explain with example, thanks.
It depends what are inputs of this function.
If the array A is an input then we only search in the diminished array else if the array A is defined as global then you always search the whole array.
For example take the array A is 1,2,1,3,1,8,7,1
If the array is given as input to the function :
According to recursion we get A is 1,2,1,3 -> A is 1,2 -> A is 1
This returns i := 1.
Then A is 2, this returns j:=1.
Then we compare i to all elements of A i.e 1,2.
Then we compare j to all elements of A i.e. 1,2.
We return null from this recursive call.
After this we proceed to upper recursion i.e. 1,2,1,3 and up to the first call.
If the array is global:
According to recursion we get A is 1,2,1,3 -> A is 1,2 -> A is 1
This returns i := 1.
Then A is 2, this returns j:=1.
Then we compare i to all elements of A i.e. 1,2,1,3,1,8,7,1
we return according to the conditions.
**Remember even in this case we return all recursive calls and check the whole array for every recursive call which is not what you probably want.

Using SET with calculated values in Neo4j creates a 'not defined' error

I have a query based on a chess tournament. It runs fine, and returns a value. I apologize if it is ugly, and I'm aware I could clean it up. But for now it works fine, and returns the value 0.5.
To quickly give some context, the query looks at the opponents of someone's opponents, and aggregates the 2nd degree player's records', then creates a ranking.
MATCH (n)-[:HAS_RECORD]-(m)-[:PLAYED]-(a)-[:PLAYED]-(b)-[:HAS_RECORD]-(c)-[:HAS_RECORD]-(d)-[:PLAYED]-(e)-[:PLAYED]-(f)-[:HAS_RECORD]-(g)
WHERE n.player_id = '1'
WITH e, f,
CASE WHEN e.player_wins='1' THEN 1 ELSE 0 END AS wins_count
RETURN (toFloat(sum(win_count)) / toFloat(count(e))) * (sum(toInt(f.wins) ) / (sum(toInt(f.wins)) + sum(toInt(f.losses)) +sum(toInt(f.draws)))) AS rank
I would like to SET this calculated ranking back on the player represented in node e. But I can't do it.
I tried this, but it didn't work...I got an error, wins_count not defined:
MATCH (n)-[:HAS_RECORD]-(m)-[:PLAYED]-(a)-[:PLAYED]-(b)-[:HAS_RECORD]-(c)-[:HAS_RECORD]-(d)-[:PLAYED]-(e)-[:PLAYED]-(f)-[:HAS_RECORD]-(g)
WHERE n.player_id = '0'
WITH e, f,
CASE WHEN e.player_wins='1' THEN 1 ELSE 0 END AS wins_count,
(toFloat(sum(wins_count)) / toFloat(count(e))) * (sum(toInt(f.wins) ) / (sum(toInt(f.wins)) + sum(toInt(f.losses)) +sum(toInt(f.draws)))) AS rank
SET e.rank = rank
RETURN e
I don't know how else I can calculate rank without putting it after the CASE.
I figured since there is a problem with wins_count not being defined, maybe I need to carry things through, so I tried to put another WITH after the CASE, but then it failed...I somehow generated a table of ranks!!
Then, I tried to move the part that calculates the rank directly into the SET statement, but apparently you can't do aggregation inside a SET statement!!
Again, I apologize for the ugly code and realize I haven't supplied a minimal example. But I'm hoping since the problem is syntactic in nature, this will be clear to someone who knows what is wrong. Thanks.
When we declare variable in WITH statement we can't use it in the same WITH statement. For example, if we try to run the following query:
WITH 2 as K1, K1*3 as K2
RETURN K1, K2
we get an error: Variable 'K1' not defined.
So, we can use next query:
WITH 2 as K1
RETURN K1, K1*3 as K2
or:
WITH 2 as K1
WITH K1, K1*3 as K2
RETURN K1, K2
and the result will be:
╒═══╤═══╕
│K1 │K2 │
╞═══╪═══╡
│2 │6 │
└───┴───┘

Resources