Following on from How can I increase speed up simulation of my least-cost path model, I try to find a way to speed up my least-cost path model that runs at a large spatial scale. My landscape has an extent of 100kmĀ² (1000 patches x 1000 patches with 1 patch = 1 pixel).
For the moment, my code seems to work but it runs very slow: my code takes several hours to draw one least-cost path. The problem is that my model evolves according to discrete time steps of two minutes during 100 days and I have 1000 wolves in my landscape. For each wolf and at each time step, my model has to build the least-cost path between a polygon (composed of several patches) where there is a wolf and all polygons that are situated in a radius of 3km around the wolf.
I used the new version of NW-extension and I tried to optimize my model by saving all costs that have already been calculated to avoid to re-draw the least-cost paths. Unfortunately, my code is yet too slow and I don't know how to speed up it. Here is my code to calculate the cost of one least-cost path (If need be, I can provide more code to someone)
to-report path-cost-between-polygons [ID-polygon-1 ID-polygon-2]
let path-cost -1
;; Define polygon edges
ask patches with [ID-polygon != ID-polygon-1] [
ask neighbors with [ID-polygon = ID-polygon-1] [
ask nodes-here [
set color red ] ] ]
ask patches with [ID-polygon != ID-polygon-2] [
ask neighbors with [ID-polygon = ID-polygon-2] [
ask nodes-here [
set color red ] ] ]
;; Calculate path cost
foreach sort ( (nodes-on patches with [ID-polygon = ID-polygon-1]) with [color = red] ) [
let node-on-polygon-1 ?
foreach sort ( (nodes-on patches with [ID-polygon = ID-polygon-2]) with [color = red] ) [
let node-on-polygon-2 ?
ask node-on-polygon-1 [
let cost nw:weighted-distance-to node-on-polygon-2 "link-cost"
if path-cost = -1 or cost < path-cost [
set path-cost cost ] ] ] ]
;; Save path cost between polygons
set list-ID-polygons lput (list ID-polygon-1 ID-polygon-2) list-ID-polygons
set list-path-costs-between-polygons lput path-cost list-path-costs-between-polygons
ask nodes with [color = red] [ set color white]
report path-cost
end
Thanks very much for your help.
I'm currently working on a new version of the NW-extension that will be much faster. Unfortunately, for weighted paths, it won't be available till NetLogo 5.0.6 comes out.
Until then, you could code your own least-cost path code. A* would be perfect for your situation. Implementing would definitely be somewhat tricky, but doable. If I have the time, I'll give it shot and post it here.
Related
I have to make turtles go faster when being on a green patch, and when they are on a blue patch the speed should go down. I added part of the code that I tried, but it doesn't work. Could someone please help me?
Thanks in advance!!
turtles-own [speed]
to go
ask turtles [
left 60
right random 60
forward 1
if any? neighbors with [pcolor = green]
[
set speed speed + 1
]
if any? neighbors with [pcolor = blue]
[
set speed speed + 0.1
]
]
reset-ticks
I think what user2901351 was getting at was that you are using neighbors in your example code. If you look at the dictionary entry for neighbors, you'll see that it references the 8 patches around the current patch. If you instead want the turtle to check the patch it's currently on, you can use the patch-here primitive or, as a shortcut, just ask the turtle to check a patch-owned variable directly. Below is a toy example that shows an example of this at work- more details in the comments.
turtles-own [speed]
to setup
ca
crt 5 [ set speed 1 ]
ask n-of 20 patches [
ifelse random-float 1 < 0.5
[ set pcolor green ]
[ set pcolor blue ]
]
reset-ticks
end
to go
ask turtles [
; Since 'pcolor' is a patch variable, if the turtle queries pcolor
; it will check the patch's variable directly.
if pcolor = green [ set speed speed + 0.5 ]
if pcolor = blue [ set speed speed - 0.5 ]
; Make sure that the turtles are moving forward by their speed value,
; rather than the hard-coded value of "1" in the example code. Also,
; I've included a check here so the turtles don't either stop moving
; or start moving backwards.
if speed < 1 [ set speed 1 ]
rt random-float 60 - 30
fd speed
show speed
]
tick
end
I am modelling a big warehouse operations (see below pic).
I have implemented a vertex on each patch (green dots) and link them so that I could compute the shortest path (using dijkstra algorithm) from each vertex to all other vertices, stored in a table (dictionary) of each vertex. This process is done during setup stage and is quite time-consuming. Then the yellow inventory cells (rectangle) will issue the demand request for task fulfillment.
The forklift truck (some in the path) is assuming to stay put on one of the vertex (node) when it's not busy. When get the demand request, it will ask its current standing vertex (node) to get the starting_node and the end_node of the inventory cell it is going to. Then the forklift ask the starting_node to get the shortest path from its table to get the shortest path (combination of nodes) and drive to the end_node (the yellow cell).
Currently, the yellow cells just randomly pick free forklift truck in the warehouse. As a further development, I want to add the function that allows the yellow cell to identify the free truck that is closest to it based on the actual distance (not the euclidean distance built in Netlogo). As there are many trucks so it's not good to use "foreach" to loop through all available trucks and compute the actual distance using above method. You could use primitive "distance myself" to locate the truck quickly but that's not accurate. Is there a good way to identify the closest truck with a faster computational method?
I don't know if this would work with your current setup, but you may also find the nw extension helpful. For example, try this setup (I apologize for the length, just approximating your world):
extensions [ nw ]
breed [ nodes node ]
breed [ trucks truck ]
breed [ cells cell ]
to setup
ca
resize-world -29 29 -14 14
ask patches with [ ( pxcor mod 5 = 0 or pycor = 0 ) ] [
set pcolor grey
sprout-nodes 1 [
set size 0.5
set shape "circle"
set color green
]
]
ask nodes [
create-links-with turtles-on neighbors4 [
set color green
]
]
ask n-of 5 nodes [
hatch 1 [
set size 1
set color red
set breed trucks
set shape "car"
]
]
ask n-of 2 trucks [
set color blue
]
ask one-of nodes [
ask one-of neighbors with [ pcolor = black ] [
sprout-cells 1 [
set size 1.5
set shape "box"
set color yellow
]
]
]
reset-ticks
end
Gives a simple world like this:
You can use the nw extension to calculate the distances on the fly, rather than storing them in a per-cell table, and have the forklifts (trucks, here) follow the shortest path. More details in comments:
to summon-nearest-truck
; Treat blue trucks as 'empty' and ready to go to a cell
let ready-trucks trucks with [ color = blue ]
; Get the nodes associated with those ready trucks
let truck-proxies turtle-set map [ i -> [nodes-on patch-here] of i ] sort ready-trucks
; Randomly ask one of the cells to
ask one-of cells [
; Choose one of the neighboring road nodes as a proxy for distance calculation
let node-proxy one-of nodes-on neighbors4
; Get the node proxy to:
ask node-proxy [
; Find the nearest (by network distance) trucks, and select the node
; located on the same patch as that truck
let my-truck-proxy min-one-of truck-proxies [length ( nw:turtles-on-path-to myself) ]
; Get that truck-proxy node to generate the path to the original asking node
; and have the appropriate truck follow that path
ask my-truck-proxy [
; Generate the path to follow
let path-to-follow nw:turtles-on-path-to myself
; Highlight that path for visualization
ask turtle-set path-to-follow [
set color orange
]
; Get the truck ready to move
let ready-truck one-of trucks-here with [ color = blue ]
ask ready-truck[
set color yellow
]
; Move that truck along the path-to-follow
ask ready-truck [
foreach path-to-follow [
n ->
face n
move-to n
; For visualization only
wait 0.1
]
]
]
]
]
end
This has the yellow box summon the nearest truck based on the length of nw:turtles-on-path-to that is returned. That truck follows the path to the summoning node:
I'm currently working on research centring around the Travelling Salesman Problem. More precisely I'm working with sample data using the EUC_2D edge weight type. Like the following:
1 11003.611100 42102.500000
2 11108.611100 42373.888900
3 11133.333300 42885.833300
I am able to produce a tour order. For example, 2-3-1.
I'd like to be able to create some simple graphics which represent a point set for a given problem, and then a point set with a tour over the top. Could anyone recommend a simple method of achieving this - what software should I be looking at to achieve this.
Thanks
Just to give you a quick demo on how the usual scientific plotting-tools would work (assuming i understood your task correctly):
Plot-only code using python & matplotlib:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, sharex=True, sharey=True) # Prepare 2 plots
ax[0].set_title('Raw nodes')
ax[1].set_title('Optimized tour')
ax[0].scatter(positions[:, 0], positions[:, 1]) # plot A
ax[1].scatter(positions[:, 0], positions[:, 1]) # plot B
start_node = 0
distance = 0.
for i in range(N):
start_pos = positions[start_node]
next_node = np.argmax(x_sol[start_node]) # needed because of MIP-approach used for TSP
end_pos = positions[next_node]
ax[1].annotate("",
xy=start_pos, xycoords='data',
xytext=end_pos, textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3"))
distance += np.linalg.norm(end_pos - start_pos)
start_node = next_node
textstr = "N nodes: %d\nTotal length: %.3f" % (N, distance)
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
ax[1].text(0.05, 0.95, textstr, transform=ax[1].transAxes, fontsize=14, # Textbox
verticalalignment='top', bbox=props)
plt.tight_layout()
plt.show()
Output:
This code is based on data of the following form:
A 2d-array positions of shape (n_points, n_dimension) like:
[[ 4.17022005e-01 7.20324493e-01]
[ 1.14374817e-04 3.02332573e-01]
[ 1.46755891e-01 9.23385948e-02]
[ 1.86260211e-01 3.45560727e-01]
[ 3.96767474e-01 5.38816734e-01]]
A 2d-array x_sol which is our MIP-solution marking ~1 when node x is followed by y in our solution-tour, like:
[[ 0.00000000e+00 1.00000000e+00 -3.01195977e-11 2.00760084e-11
2.41495095e-11]
[ -2.32741108e-11 1.00000000e+00 1.00000000e+00 5.31351363e-12
-6.12644932e-12]
[ 1.18655962e-11 6.52816609e-12 0.00000000e+00 1.00000000e+00
1.42473796e-11]
[ -4.19937042e-12 3.40039727e-11 2.47921345e-12 0.00000000e+00
1.00000000e+00]
[ 1.00000000e+00 -2.65096995e-11 3.55630808e-12 7.24755899e-12
1.00000000e+00]]
Bigger example, solved with MIP-gap = 5%; meaning: the solution is guaranteed to be at most 5% worse than the optimum (one could see the sub-optimal part in the right where some crossing is happening):
Complete code including fake TSP-data and solving available here.
I going to recommend Baby X. (It's my own windowing system).
It's a windows system that runs on either Linux or MS Windows, and is designed for exactly this type of problem - quickly prototyping a program with a few simple graphics.
Baby X exposes rgba surfaces. You then draw into the buffer, either using your own routines, the Baby X basic routines (lines and polygons), or the Baby X graphics context (fully fledged Bezier-based 2D graphics). It's very quick to set up. You'll obviously have to scale your graph to pixel space, plot symbols for the cities, then draw lines between them to represent the tour.
https://github.com/MalcolmMcLean/babyx
However there are several graphics systems out there. You just have to choose one that runs on your hardware pltform.
I try to make my first ABM using NETLOGO. I would like to show in an easy way how an election works.
So I create 3 types of turtles : young people, adults and senior (I create this because of candidate's preferences are not the same, one's are more social than others more liberal...).
So I would like to make them move, and changing the p-color of the patch into they move with probability.
For example in 2012 young people vote (in a simply way) 30% social (color 136), 30% liberal (color 97), 20% extreme-right (color 104) and 10% extreme-left (red).
So, I would like in my code to introduce probability when turtles move to patches and change color.
This is the interesting part of my code :
to chose-color-young
ask jeunes
[if pcolor = white [set pcolor one-of [136 97 104 15]]]
end
I would like to do something like that 136 with probability = 0.3 ;97 with probability = 0.3 ; 104 with probability = 0.20 and 15 with probability = 0.10.
The rnd extension does exactly what you need:
let probs [[136 0.3] [97 0.3] [104 0.20] [15 0.10]]
ask jeunes [
if pcolor = white [
set pcolor first rnd:weighted-one-of-list probs last
]
]
See this other answer for more explanations on the rnd extension.
I want to, given a list of turtles, export the part of the view that contains those turtles as an image. Being able to export part of the view specified by a set of boundaries would solve this problem. That is, a function like export-view-of-turtles list-of-turtles or export-view-rectangle min-xcor max-xcor min-ycor max-ycor would be ideal.
Obviously, a solution that works entirely in NetLogo would be best, but I find that unlikely: export-view is the only function I know of that exports an image of the view at all, and that only does the whole view. However, if there's a plugin for this, that would be awesome.
My last resort is to just export the view and then run a script that clips it accordingly. If there isn't a better solution, I'll do this, and post the script.
Alright, this is kind of dirty, but it seems to work. Basically, the below exports the world state in a temp file, records the data about the turtles in question, resizes the view based on the distance of those turtles from the center, recreates just those turtles from the recorded data, exports the view, then restores the original world state. Here's the code:
to export-view-of-turtles [ filename the-turtles ]
let center-patch min-one-of patches [ sum [ (distance myself ^ 2) ] of the-turtles ]
let turtle-props [ (list
(- distance center-patch * sin towards center-patch) ; xcor relative to center patch
(- distance center-patch * cos towards center-patch) ; ycor relative to center patch
heading size shape label color
) ] of the-turtles
let max-x max map [ first ? + item 3 ? ] turtle-props
let min-x min map [ first ? - item 3 ? ] turtle-props
let max-y max map [ item 1 ? + item 3 ? ] turtle-props
let min-y min map [ item 1 ? - item 3 ? ] turtle-props
let world-state-backup (word "temp-world-" date-and-time ".csv")
export-world world-state-backup
resize-world min-x max-x min-y max-y
foreach turtle-props [
crt 1 [
setxy first ? (item 1 ?)
set heading (item 2 ?)
set size (item 3 ?)
set shape (item 4 ?)
set label (item 5 ?)
set color (item 6 ?)
]
]
export-view filename
import-world world-state-backup
file-delete world-state-backup
end
Example of use. Given:
Calling export-view-of-turtles "test.png" [ turtles in-radius 5 ] of turtle 85 gives:
Notes:
This perfectly supports world wrapping.
It will ONLY show the given turtles. Patches, drawing layer, and other turtles will not be shown. That said, it could easily be modified so that they patches and other turtles are shown.
As with any code that uses import and export world (not recommended for this kind of thing), this will likely break in many corner cases.