How make a list of cumulative sum in netlogo

2019-02-15 14:16发布

问题:

How can i make a list of cumulative sum of a other list?

i tried it that way:

;;all temperatrue-values around the turtle saved in list 
set temperature_values (list [(output-heat + 1)^ Freedom] of neighbors) 


;;build cumulative value of temperatures and put each value in list 
let tempsum 0 
set tempsum_list [] 
foreach temperature_values 
[set tempsum (tempsum + ? ) 
set tempsum_list fput tempsum tempsum_list 

] 

but it doesn't work. can anyone fix this problem? it says that "+ excepted a input but gets a list instead".

回答1:

your code for a cumulative sum works (except that I think you need lput rather than fput. You can see it with this:

to test
  let ll [1 2 3 4] 
  let tempsum 0 
  let tempsum_list [] 
  foreach ll 
  [ set tempsum (tempsum + ? ) 
    set tempsum_list lput tempsum tempsum_list 
  ]
  print tempsum_list
end

Did the error highlight the line set temperature_values (list [(output-heat + 1)^ Freedom] of neighbors)? Try putting a space after between ) and ^. NetLogo is picky about space around mathematical operators.



回答2:

As Jen suggested, you can use foreach. Another nice approach is reduce:

to-report partial-sums [#lst]
  set #lst (fput [0] #lst)  ;;prepare for reduce
  report butfirst reduce [lput (?2 + last ?1) ?1] #lst
end


回答3:

This is like Alan's solution, just abstracted a bit further. (Perhaps too far, depending on your taste! I like JenB's solution as well.)

Let's first define a thing like reduce, but that keeps all the intermediate results:

to-report scan [fn xs]
  report reduce [lput (runresult fn ?2 last ?1) ?1]
                (fput (list first xs) butfirst xs)
end

Now we can use it to compute partial sums:

observer> show scan task + [1 2 3 4 5]
observer: [1 3 6 10 15]

but we are also free to swap in a different operation:

observer> show scan task * [1 2 3 4 5]
observer: [1 2 6 24 120]


回答4:

Similar to Alan's solution (Just an update for the recent version of NetLogo that replaces ? with -> for anonymous procedures.)

to-report partial-sums [lst]
report butfirst reduce [[result-so-far next-item] -> lput (next-item + last 
result-so-far) result-so-far] fput [0] lst
end