How to speed up a while loop with many list filtering procedures each of 200 turtles runs on 2600 patches

huangapple go评论46阅读模式
英文:

How to speed up a while loop with many list filtering procedures each of 200 turtles runs on 2600 patches

问题

To improve the performance of your model and make the decisionforprofit loop faster, you can consider the following optimizations:

  1. Precompute Patch Lists: Instead of creating the list of available patches and their characteristics within the loop for each turtle, you can precompute this list once before the loop starts and update it only when necessary (e.g., when patches become unavailable due to ownership changes). This way, you avoid recomputing the same information multiple times.

  2. Parallel Processing: Depending on your simulation environment, you may be able to take advantage of parallel processing to distribute the workload among multiple cores or processors. This can significantly speed up the execution of your model, especially if you have a large number of turtles and patches.

  3. Data Structures: Consider using more efficient data structures to store and manipulate your data. For example, use dictionaries or arrays to store patch information so that you can quickly access patches based on their characteristics without iterating through the entire list.

  4. Reduce Redundant Checks: Look for opportunities to reduce redundant checks within your code. For example, if a patch's suitability doesn't change within a tick, you don't need to recheck it for every turtle. You can store suitability values and update them when necessary.

  5. Profile Your Code: Use profiling tools to identify performance bottlenecks in your code. Profiling will help you pinpoint which parts of your code consume the most time and need optimization.

  6. Limit Unnecessary Operations: Analyze your code to identify any unnecessary operations or conditions that can be skipped to save computation time. For instance, if a turtle has insufficient investable money for a particular land use change, you can skip processing that option.

  7. Batch Processing: Instead of processing each turtle one at a time, consider batch processing multiple turtles at once. This can reduce overhead and improve efficiency.

  8. Use Agentsets: Agentsets can help you organize and manipulate turtles and patches efficiently. Use them to filter and select agents based on specific criteria.

  9. Simplify Decision Logic: If possible, simplify the decision-making logic within your loop. Complex conditional statements can slow down execution. Try to minimize the number of conditions that need to be checked.

  10. Optimize Patch Queries: Ensure that patch queries, such as any? and with, are as efficient as possible. Avoid unnecessary nested queries and use agentsets when appropriate.

  11. Reduce the Number of Turtles: If your model's performance remains an issue, consider reducing the number of turtles in your simulation. This can lead to a significant improvement in execution speed.

Implementing these optimizations should help you make your model run faster and more efficiently. Remember to profile your code and measure the impact of each optimization to ensure you're making effective improvements.

英文:

I am working in a decision-making ABM, my turtles must identify the best land use change strategy based on the characteristics and availability of patches suitable to make the best decisions. However the code I have takes a lot of time to process the decision of the agent.

this is a list of potential land use changes :

   set landuselist [
    ;; in the list  
    ;;    +------------------------ landusechange
    ;;    |     +------------------ cost
    ;;    |     |    +------------- expectedprofit
    ;;    |     |    |  +---------- maize
    ;;    |     |    |  |    +----- expectedprofit(formodification)
    ;;    |     |    |  |    |
    [ "MEA1"  200  450  6  450 ] ;; maintenance of mechanized agriculture in patches with high suitability for mechanized agriculture
    [ "TRA1"   50  350  3  350 ] ;; maintenance of traditional agriculture to traditional agriculture in patches with high suitability for traditional agriculture
    [ "CAT1"  100  350  0  350 ] ;; maintenance of cattle ranching in any suitability except for null
    [ "AGF1"   50  600  1  600 ] ;; Maintenance of agroforestry with an age over or equal to 6 year on suitability over null for agroforestry
    [ "MEA2"  200  450  6  450 ] ;;  conversion of forest to mechanized agriculture in patches with high suitability for mechanized agriculture
    [ "TRA2"  100  300  3  300 ] ;;  conversion of forest to traditional agriculture in patches with high suitability for traditional agriculture
    [ "CAT2"  600  300  0  300 ] ;;      change from forest to cattle ranching in any patch with suitability over null suitability
    [ "AGF2"   50   50  1   50 ] ;; Maintenance of agroforestry with an age below 6 year on suitability over null for agroforestry
    [ "MEA3"  200  450  6  450 ] ;;  conversion of land uses different than forest and mechanized agriculture into mechanized agriculture in patches with high suitability for mechanized agriculture
    [ "TRA3"   50  200  3  200 ] ;;  conversion of land uses different to forest or traditional agriculture to traditional agriculture in patches with high suitability for traditional agriculture
    [ "CAT3"  600  300  0  300 ] ;;      change of land uses diferent to forest and cattle ranching to cattle ranching in any level of suitability
    [ "AGF3"  350   50  1   50 ] ;;      change from land uses different from forest and agroforestry  to agroforestry in any suitability level exepct for null for agroforestry
    [ "MEA4"  250  300  5  300 ] ;; maintenance of mechanized agriculture in patches with medium suitability for mechanized agriculture
    [ "TRA4"   50  200  2  200 ] ;; maintenance of traditional agriculture to traditional agriculture in patches with medium suitability for traditional agriculture
    [ "MEA5"  250  300  5  300 ] ;;  conversion of forest to mechanized agriculture in patches with medium suitability for mechanized agriculture
    [ "TRA5"  100  200  2  200 ] ;;  conversion of forest to traditional agriculture in patches with medium suitability for traditional agriculture
    [ "MEA6"  250  300  5  300 ] ;;  conversion of land uses different than forest and mechanized agriculture into mechanized agriculture in patches with medium suitability for mechanized agriculture
    [ "TRA6"   50  150  2  150 ] ;;  conversion of land uses different to forest or traditional agriculture to traditional agriculture in patches with medium suitability for traditional agriculture
    [ "MEA7"  250  250  4  250 ] ;; maintenance of mechanized agriculture in patches with low suitability for mechanized agriculture
    [ "TRA7"   50  150  1  150 ] ;; maintenance of traditional agriculture on patches with traditional agriculture in patches with low suitability for traditional agriculture
    [ "MEA8"  250  250  4  250 ] ;;  conversion of forest to mechanized agriculture in patches with low suitability for mechanized agriculture
    [ "TRA8"  100  100  1  100 ] ;;  conversion of forest to traditional agriculture in patches with low suitability for traditional agriculture
    [ "MEA9"  250  250  4  250 ] ;;  conversion of land uses different than forest and mechanized agriculture into mechanized agriculture in patches with low suitability for mechanized agriculture
    [ "TRA9"   50  100  1  100 ] ;;  conversion of land uses different to forest or traditional agriculture to traditional agriculture in patches with low suitability for traditional agriculture
    ]

this is my while loop :

to decideforprofit            ;;;; procedure to create the decision model based.
                              ;;;;           It is a secondary process after maize self-consumption
set ownedpatcheslist []                   ;; used to create a list of patches owned by each agent
while [investablemoney >= 50] [           ;; defined as the smallest cost to do a land use change
    create-patch-types                    ;; create a list of available patches in its respective procedure to have only the available patches and their potential benefit in land use change
    set alternatives filter [parches -> member? (item 0 parches) patch-types] landuselist ;;; to work with a list for each turtle that we can modify, it filters the global list based on the lo
create-patch-types list
     let landuselist1 filter [lista -> item 1 lista <= investablemoney] alternatives;;; filter based on the budget of each turtle 
     let landuselist2 sort-with [ l -> item 2 l ] landuselist1 ;;; sort the alternatives of each turtle to find the most profitable one

ifelse empty? landuselist2 [ ;;; when there are not more patches then to continue the procedure as normal for the next turtle
      ;handle the case where there are no suitable patches
      ;show "NO AVAILABLE PATCHES"
]  [;;; if it is not empty then
  let highest-value first landuselist2 ;;; chose the most profitable land use change from the nested list 
  let value item 0 highest-value ;;; define the land use change "MEA1", "MEA2"... 
  set chosevalue value ;;; the turtle receive the order 
  let costs item 1 highest-value ;;; extract the cost of the decision from the list
  let income item 2  highest-value ;;; extract the income of the decision form the list
  set investablemoney (investablemoney - costs);; discount the cost to the variable investablemoney of turtles
  set savings (savings + income) ;;; add the income of the decision to the savings variable
  applydecisions;;;  procedure that execute the order in chosevalue
  ]

  if empty? landuselist2 or investablemoney < 50 [
      ;exit the while loop if there are no suitable alternatives or there is not enough investable money
      ;show "I am stopping#"
       stop
       ]
  ]
  ;;; end of the while
end
;;;decideforprofit()

this is the procedure to create a list of available patches and land use change options :

to create-patch-types   ;; this creates a list of patches
                        ;;      based on the patch suitability
                        ;;      current land use and ownership
  set patch-types []
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; choices for traditional agriculture

  if any? patches with [(land-use = "TRA") and (OwnerId = [who] of myself) and (TRAsuitability = 3) and (inuse = 0)] [set patch-types lput "TRA1" patch-types]
  if any? patches with [(land-use = "TFM") and (OwnerId = 999) and (TRAsuitability = 3) and (inuse = 0)] [set patch-types lput "TRA2" patch-types]
  if any? patches with [member? land-use ["MEA" "CAT" "AGF"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (TRAsuitability = 3) and (inuse = 0)] [set patch-types lput "TRA3" patch-types]
  if any? patches with [(land-use = "TRA") and (OwnerId = [who] of myself) and (TRAsuitability = 2) and (inuse = 0)] [set patch-types lput "TRA4" patch-types]
  if any? patches with [(land-use = "TFM") and (OwnerId = 999)  and (TRAsuitability = 2) and (inuse = 0)] [set patch-types lput "TRA5" patch-types]
  if any? patches with [member? land-use ["MEA" "CAT" "AGF"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (TRAsuitability = 2) and (inuse = 0)]  [set patch-types lput "TRA6" patch-types]
  if any? patches with [(land-use = "TRA") and (OwnerId = [who] of myself) and (TRAsuitability = 1) and (inuse = 0)]  [set patch-types lput "TRA7" patch-types]
  if any? patches with [(land-use = "TFM") and (OwnerId = 999) and (TRAsuitability = 1) and (inuse = 0)] [set patch-types lput "TRA8" patch-types]
  if any? patches with [member? land-use ["MEA" "CAT" "AGF"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (TRAsuitability = 1) and (inuse = 0)] [set patch-types lput "TR9" patch-types]

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; choices for mechanized agriculture

  if any? patches with [(land-use = "MEA")  and (OwnerId = [who] of myself) and (MEAsuitability = 3) and (inuse = 0)] [set patch-types lput "MEA1" patch-types]
  if any? patches with [(land-use = "TFM") and (OwnerId = 999) and (MEAsuitability = 3) and (inuse = 0)] [set patch-types lput "MEA2" patch-types]
  if any? patches with [member? land-use ["TRA" "CAT" "AGF"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (MEAsuitability = 3) and (inuse = 0)] [set patch-types lput "MEA3" patch-types]
  if any? patches with [(land-use = "MEA")  and (OwnerId = [who] of myself) and (MEAsuitability = 2) and (inuse = 0)] [set patch-types lput "MEA4" patch-types]
  if any? patches with [(land-use = "TFM") and (OwnerId = 999) and (MEAsuitability = 2) and (inuse = 0)] [set patch-types lput "MEA5" patch-types]
  if any? patches with [member? land-use ["TRA" "CAT" "AGF"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (MEAsuitability = 2) and (inuse = 0)] [set patch-types lput "MEA6" patch-types]
  if any? patches with [(land-use = "MEA")  and (OwnerId = [who] of myself) and (MEAsuitability = 3) and (inuse = 0)] [set patch-types lput "MEA7" patch-types]
  if any? patches with [(land-use = "TFM") and (OwnerId = 999)  and (MEAsuitability = 1) and (inuse = 0)] [set patch-types lput "MEA8" patch-types]
  if any? patches with [member? land-use ["TRA" "CAT" "AGF"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (MEAsuitability = 1) and (inuse = 0)] [set patch-types lput "MEA9" patch-types]

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; choices for cattle ranching

  if any? patches with [(land-use = "CAT") and (OwnerId = [who] of myself) and (CATsuitability  > 0) and (inuse = 0)] [set patch-types lput "CAT1" patch-types]
  if any? patches with [(land-use = "TFM") and (OwnerId = 999)   and (CATsuitability  > 0) and (inuse = 0)] [set patch-types lput "CAT2" patch-types]
  if any? patches with [member? land-use ["MEA" "TRA" "AGF"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (CATsuitability  > 0) and (inuse = 0)] [set patch-types lput "CAT3" patch-types]

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; choices for agroforestry

  if any? patches with [(land-use = "AGF") and (OwnerId = [who] of myself) and (AGFsuitability > 0) and (inuse = 0) and (age >= 6)] and any? patches with [(land-use = "AGF") and (OwnerId = [who] of myself) and (AGFsuitability > 0) and (inuse = 0) and (age >= 6)]  [set patch-types lput "AGF1" patch-types]
  if any? patches with [(land-use = "AGF") and (OwnerId = [who] of myself) and (AGFsuitability > 0) and (inuse = 0) and (age < 6)]  and any? patches with [(land-use = "AGF") and (OwnerId = [who] of myself) and (AGFsuitability > 0) and (inuse = 0) and (age < 6)] [set patch-types lput "AGF2" patch-types]
  if any? patches with [member? land-use ["MEA" "CAT" "TRA"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (AGFsuitability > 0) and (inuse = 0)] and any? patches with [member? land-use ["MEA" "CAT" "TRA"] or (land-use = "FAL" and age > 4) and (OwnerId = [who] of myself) and (AGFsuitability > 0) and (inuse = 0)] [set patch-types lput "AGF3" patch-types]

end
;;;create-patch-types()

There is another procedure that executes on each land use change option.<br>
this is an example :

to applydecisions
  if (chosevalue = &quot;TRA1&quot;) [move-to one-of patches with [land-use = &quot;TRA&quot; and (OwnerId = [who] of myself) and TRAsuitability = 3 and inuse = 0]
    ask patch-here [set land-use &quot;TRA&quot; set OwnerId [who] of myself set breedowner [breed] of myself  set inuse 1 ]
                           set ownedpatcheslist lput patch-here ownedpatcheslist ]
  if (chosevalue = &quot;TRA2&quot;) [move-to one-of patches with [land-use = &quot;TFM&quot; and OwnerId = 999 and TRAsuitability = 3 and inuse = 0]
                           ask patch-here [set land-use &quot;TRA&quot;  set OwnerId [who] of myself set breedowner [breed] of myself set age 1 set inuse 1]
                           set ownedpatcheslist lput patch-here ownedpatcheslist]
end
;;;applydecisions()

How to make my model faster? What I have identified is that it takes long time for each turtle to run the while procedure because they must build a different list every time in the loop and per tick.

I would like to identify the best way to make the decisionforprofit loop faster in order that my turtles consider the money they have and the available patches (not owned by other turtles or already owned by the same turtle) to make land use change: currently I have 200 turtles and 2600 patches varying in three levels of suitability for each land use type.

答案1

得分: 1

考虑编程中的DRY原则。

不要重复自己。

如果您可以在代码中找到重复的模式,您将找到减少执行指令数量的机会。

考虑owner-id = [who] of myself

首先,[who] of myself被多次运行。我们可以考虑将其存储在一个本地变量中,然后在查询中使用它。但是,在这种情况下,将myself分配给owner-id是不好的NetLogo风格。在这种情况下,只需在乌龟声明贴片时将myself分配给owner-id。

接下来,测试owner-id = myself

再次运行此测试会对所有贴片多次运行。这是数千次不必要的测试!让我们将查询的一部分存储在一个本地变量中。

我们现在已经删除了数千次的测试。您可能会看到显着的性能改进。

其他可能的改进:

  • 看看是否可以避免测试member?
  • 看看是否可以使用数值代码而不是字符串。
  • 看看是否可以避免重建不变的事物。
  • 看看是否可以安排数据,以便不需要过滤。
  • 看看是否可以将搜索转化为查找。

这是一个开始。希望有人会添加更多的想法。

我现在没有时间详细说明这个建议,但您可以考虑使用其他乌龟作为对象来保存和查询您的土地使用属性。

英文:

Consider the DRY principle of programming.

Don't Repeat Yourself.

If you can find repeating patterns in your code, you will find opportunities to reduce the number of instructions being executed.

Consider owner-id = [who] of myself

First, [who] of myself is run many, many times. We might consider storing that in a local variable, then use that in the queries. But, using WHO as an ID is poor NetLogo style. In this case, just assign myself to the owner-id when the turtle claims the patch.

Next, the test 'owner-id = myself`

Again this test is run against all the patches many times. That's thousands of unnecessary tests! Let's store that part of the query in a local variable.

We have now removed thousands and thousands of tests. You likely will see significant performance improvement.

Other possible improvements:

  • See if you can avoid testing member?.
  • See if you can use numeric codes instead of strings.
  • See if you can avoid rebuilding thing that don't change
  • See if you can arrange your data so filtering isn't needed
  • See if you can transform searches into look-ups

That's a start. Hopefully someone will add more to ideas.

I don't have time to expand on this suggestion right now, but you may consider using other turtles as objects to hold and query your land use properties.

huangapple
  • 本文由 发表于 2023年5月17日 13:57:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76268947.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定