Update Birth and death rates in an SIR model - netlogo

i would like to simulate the disease spread using agent base model by using NetLogo software.
how to Update Birth and death rates in an SIR model.

As a starting point you could try the http://ccl.northwestern.edu/netlogo/models/SimpleBirthRates
that has a method reproduce which adjusts the fertility of the different populations
to reproduce
ask turtles
[
ifelse color = red
[
set fertility floor red-fertility
set fertility-remainder red-fertility - (floor red-fertility)
]
[
set fertility floor blue-fertility
set fertility-remainder blue-fertility - (floor blue-fertility)
]
ifelse (random-float 100) < (100 * fertility-remainder)
[ hatch fertility + 1 [ wander ]]
[ hatch fertility [ wander ]]
]
end
For the SIR model see https://en.wikipedia.org/wiki/SIR_model#The_SIR_model
You probably want three different populations blue(S susceptible), red(I infectious), and green(R recovered). You want to change the code so that you change beta I S blues into reds and change nu I reds into greens. beta and nu are model parameters. It might be easier to start by killing and hatching equal numbers of blues and reds.
The following code implements this. I have three different sets of turtles, initially many more blue than the other colours. The main part happens in the reproduce which turns blues to reds:
ifelse color = blue
[
if (random-float 100) < (beta * red-count * blue-count ) / 1000000
[set color red]
]
and reds to greens
ifelse color = red
[
if (random-float 100) < (nu * red-count ) / 10000
[set color green]
]
The full code is. You need to add sliders for beta and nu, add a line in the graph for green-count and a monitor for green-count. The numbers have been chosen by guess work which seem to show a good effect.
globals
[
red-count ; population of red turtles
blue-count ; population of blue turtles
green-count ; population of green turtles
]
turtles-own
[
]
to setup
clear-output
setup-experiment
end
to setup-experiment
cp ct
clear-all-plots
reset-ticks
crt carrying-capacity
[
setxy random-xcor random-ycor ; randomize turtle locations
ifelse who < (carrying-capacity / 10) ; start out with equal numbers of reds and blues
[ set color red ]
[
ifelse who < (2 * carrying-capacity / 10) ; start out with equal numbers of reds and blues
[ set color green ]
[ set color blue ]
]
set size 2 ; easier to see
]
reset-ticks
end
to go
reproduce
tick
end
to reproduce
ask turtles
[
ifelse color = blue
[
if (random-float 100) < (beta * red-count * blue-count ) / 1000000
[set color red]
]
[
ifelse color = red
[
if (random-float 100) < (nu * red-count ) / 10000
[set color green]
]
[
]
]
]
end

Related

NetLogo - Have an agent identify one of two other types of agent closest to it and perform actions conditional on which agent type is identified

Suppose I have 2 breeds of agents, sharks (stars and dots) and fish. The stars (large sharks) can eat dots (smaller sharks) and fish that are in-radius 0.5 of a star. A star should eat what is closest to it, either a dot or fish. For simplicity purposes, agents cannot move, and whether or not a star can feed depends on its spatial proximity to dots and fish during setup.
But i'm struggling to get the code to work. Specifically,
I am encountering an "expected reporter" error message in my code and i cannot figure out how to solve this, although I don't know if fixing the code will achieve the aim. Any help is greatly appreciated.
Below is my code:
; Create the agents
breed [sharks shark]
breed [fishes fish]
sharks-own
[
energy
]
fishes-own
[
x0 ; Starting x-cor
y0 ; Starting y-cor
]
to setup
; Always start with this
clear-all
reset-ticks
ask patches [set pcolor gray]
create-sharks 666
[
set color blue
set energy 100
ifelse who >= 15
[
set shape "dot" set size 2.5
]
[
set shape "star" set size 3.5
]
setxy random-xcor random-ycor
]
create-fishes 300
[
setxy random-xcor random-ycor
set x0 xcor
set y0 ycor
set shape "fish"
set size 2.5
set color white
]
; this procedure gives an "expected reporter' error
if shape = "star"
[
ifelse min-one-of turtles with [shape = "dot"]
[
ifelse any? sharks with [shape = "dot"] in-radius 0.5 ; namely here
[
fd 0
]
[
set energy (energy + 100)
set color green
] ; End of 2nd ifelse
]
[
if min-one-of turtles with [shape = "fish"]
[
ifelse any? fishes with [shape = "fish"] in-radius 0.5
[
fd 0
]
[
set energy (energy + 1)
set color yellow
]
]
] ; End of 1st ifelse
] ; End of 1st if
end
You core issue is you are using ifelse min-one-of turtles with [shape = "dot"] as though min-one-of will give a true/false, but it will report a turtle. The error message NetLogo is giving is not great in this case. What I think you want to use any? in those cases (there are two of them that I see).
After those are resolved you have a context error, where you are checking if shape = "star" , but you aren't inside an ask [...] block where that check would have a turtle context to be valid. Maybe that's just a copy/paste issue in getting this question code ready, but I thought I'd note that, too.
Ok after many hours of blood, sweat and tears I finally arrived at the solution. In case the issue/objective is of interest to anyone else, the working code is as follows:
; Create the agents
breed [sharks shark]
breed [fishes fish]
sharks-own
[
energy
]
fishes-own
[
x0 ; Starting x-cor
y0 ; Starting y-cor
]
to setup
; Always start with this
clear-all
reset-ticks
ask patches [set pcolor gray]
create-sharks 666
[
set color blue
set energy 100
ifelse who >= 10
[
set shape "dot" set size 2.5
]
[
set shape "star" set size 3.5
]
setxy random-xcor random-ycor
]
create-fishes 300
[
setxy random-xcor random-ycor
set x0 xcor
set y0 ycor
set shape "fish"
set size 2.5
set color white
]
ask turtles [
if shape = "star"
[
let turtleID min-one-of other turtles [distance myself] ; Create a variable that identifies nearest turtle to apex
ifelse [shape] of turtleID = "dot" ; Evaluate whether the nearest turtle is a small meso
[
ifelse distance turtleID < 0.5 ; check if prey is still close enough
[
; do this if within radius 0.5
set color green
]
[
; do this if not within radius 0.5
set color yellow
]
]
[
if [shape] of turtleID = "fish" ; Evaluate whether the nearest turtle is a fish
[
ifelse distance turtleID < 0.5
[
; do this if within radius 0.5
set color red
]
[
; otehrwise do this if not within radius 0.5
set color orange
]
]
]
]
]
end

NETLOGO: Iterate over agents with a variable set on a slider

I'm trying to iterate over agents to change them randomly.
Basically there ar "n" number of coins (n is defined by a slider that creates those n number of agents)
The function to change them that I'm trying is the following
to tossing
if any? coins with [color = white] [
ask coins [
let coin-toss random-float 1.0
if coin-toss > 0.5 [
print "hi"
;set shape "coin tails"
set color lime
set flip 1
]
if coin-toss < 0.5 [
set color pink
set flip 0
]
]
]
if not any? coins with [color = white] [
ask coins [
set color white
set flip 3
]
]
end
This doesn't even change the colors, and I'm sure it won't change each coin differently.
I've been searching how to approach this but can't find a thing.
Edited solution and adding previous procedure:
to go
ifelse (any? turtles with [color = red]) [
print "red"
restart
;ask coins [ tossing ]
]
[
ask one-of cryptographers [ update ]
wait 0.6
ask coins [ tossing ]
;recolor
]
tick
end
to tossing
if any? coins with [shape = "circle"] [
ask coins [
;let a random-float 1
ifelse (flip = 3) and (random-float 1 > 0.5) [
;print "hi"
set shape "coin tails"
set color lime
set flip 1
]
[
set shape "coin heads"
set flip 0
set color pink
]
wait 0.2
]
]
end

How can I make the model run?

I am essentially trying to combine elements of the 'Segregation' model and 'Rebellion' model to form a model that is representative of alliance forming.
Here is what I have so far- when I attempt to run it I receive the error: THREATS breed does not own variable ACTIVE?
error while threat 0 running ACTIVE?
called by procedure GO
called by Button 'go'
breed [ agents an-agent]
breed [ threats threat ]
globals [
k ; factor for determining attack probability
threshold ; by how much must D - BS > A to make a state burden share
percent-similar ; on the average, what percent of a turtle's neighbors
; are the same color as that turtle? Likely to ally
percent-unhappy ; what percent of the turtles are unhappy? Or percieve threats?
visualization
]
agents-own [
allied-states ; R, fixed for the agent's lifetime, ranging from 0-1 (inclusive)- for each turtle, indicates whether at least %-similar-wanted percent of
; that turtle's neighbors are the same color as the turtle
perceived-threat ; T, also ranging from 0-1 (inclusive)- how many have a turtle of another color?
active? ; if true, then the agent is actively allied
; if false, then the agent is free-riding
conflict ; how many turns in conflict remain? (if 0, the agent is not in conflict)- sum of previous two variables
total-nearby ; sum of previous two variables
]
patches-own [
neighborhood ; surrounding patches within the vision radius
]
to setup
clear-all
; set globals
set k 2.3
set threshold 0.1
ask patches [
; make background a slightly dark gray
set pcolor gray - 1
; cache patch neighborhoods
set neighborhood patches in-radius vision
]
if initial-threats-density + initial-agent-density > 206 [
user-message (word
"The sum of INITIAL-THREATS-DENSITY and INITIAL-AGENT-DENSITY "
"should not be greater than 206.")
stop
]
; create threats
create-threats round (initial-threats-density * .01 * count patches) [
move-to one-of patches with [ not any? turtles-here ]
display-threats
]
; create agents
create-agents round (initial-agent-density * .01 * count patches) [
move-to one-of patches with [ not any? turtles-here ]
set heading 0
set allied-states random-float 1.0
set perceived-threat random-float 1.0
set active? false
set conflict 0
display-agent
]
; start clock and plot initial state of system
reset-ticks
end
to go
if all? turtles [ active? ] [ stop ]
move-unhappy-turtles
update-turtles
update-globals
tick
end
; unhappy turtles try a new spot
to move-unhappy-turtles
ask turtles with [ not active? ]
[ find-new-spot ]
end
; move until we find an unoccupied spot
to find-new-spot
rt random-float 360
fd random-float 10
if any? other turtles-here [ find-new-spot ] ; keep going until we find an unoccupied patch
move-to patch-here ; move to center of patch
end
to update-turtles
ask turtles [
; in next two lines, we use "neighbors" to test the eight patches
; surrounding the current patch
set allied-states count (turtles-on neighbors) with [ color = [ color ] of myself ]
set perceived-threat count (turtles-on neighbors) with [ color != [ color ] of myself ]
set total-nearby allied-states + perceived-threat
set active? allied-states >= (percent-similar * total-nearby / 100)
; add visualization here
if visualization = "old" [ set shape "default" set size 1.3 ]
if visualization = "square-x" [
ifelse active? [ set shape "square" ] [ set shape "X" ]
]
]
end
to update-globals
let similar-neighbors sum [ allied-states ] of turtles
let total-neighbors sum [ total-nearby ] of turtles
set percent-similar (similar-neighbors / total-neighbors) * 100
set percent-unhappy (count turtles with [ not active? ]) / (count turtles) * 100
; Agents engaged in conflict have the duration reduced at the end of each clock tick
ask agents [ if conflict > 0 [ set conflict conflict - 1 ] ]
; update agent display
ask agents [ display-agent ]
ask threats [ display-threats ]
; advance clock and update plots
tick
end
; AGENT AND THREAT BEHAVIOR
; move to an empty patch
to move ; turtle procedure
if movement? or breed = threats [
; move to a patch in vision; candidate patches are
; empty or contain only jailed agents
let targets neighborhood with [
not any? threats-here and all? agents-here [ conflict > 0 ]
]
if any? targets [ move-to one-of targets ]
]
end
; AGENT BEHAVIOR
to determine-behavior
set active? (burden-sharing - allied-states * estimated-conflict-probability > threshold)
end
to-report burden-sharing
report perceived-threat * (1 - alliance-protection)
end
to-report estimated-conflict-probability
let t count (threats-on neighborhood)
let a 1 + count (agents-on neighborhood) with [ active? ]
; See Info tab for a discussion of the following formula
report 1 - exp (- k * floor (t / a))
end
to alliance
if any? threats [attack]
set active? true
end
; THREAT BEHAVIOR
to attack
if any? (agents-on neighborhood) with [ active? ] [
; arrest suspect
let suspect one-of (agents-on neighborhood) with [ active? ]
move-to suspect ; move to patch of the jailed agent
ask suspect [
set active? false
set conflict random conflict-term
set color pink
]
]
end
; VISUALIZATION OF AGENTS AND COPS
to display-agent ; agent procedure
set color cyan
set shape "triangle"
end
to display-active?
set color pink
set shape "triangle"
end
to display-threats
set color red
set shape "circle 2"
end
The problem is that you have two breeds of turtles, agents and threats, and only agents "own" the variable active?. turtles is a superset of all breeds, so when the all? primitive tries to query the active? variable of literally all turtles, it tries to query active? for threats too, and can't find it. The line should be
if all? agents [ active? ] [ stop ]

Netlogo , How to display number of ticks

Hi I am writing simulation which uses ticks to represent time in simulation environment . Is it possible to display tick counter in monitor GUI? Also I have tried to input the code but it is not working.
My sample code:
if [agents count = 0]
show "count ticks"
This should show tick exactly value when agent unit value is zero. For example if agent = 0 at tick 200 it should display 200 on monitor even the whole simulation run on 500 ticks.
whole code is
patches-own[
nest?
nest-scent
food
food-source-number
chemical
]
breed [agents agent] ;agent is ant
breed [antiagents a-antiagent] ;antiagent spider
antiagents-own[energy]
agents-own[venom]
;;;;;;;;;;;;;;;;;;;;;;;;;; Setup ;;;;;;;;;;;;;;;;;;;
to setup
clear-all
set-default-shape agents "ant"
create-agents initial-ants ;; create the ants, then initialize their variables
[
set color orange
set size 2 ;; easier to see
set venom (ant-venom-strength)
]
set-default-shape antiagents "spider"
create-antiagents initial-spiders ;; create the spider, then initialize their variables
[
set color yellow
set size 3 ;; easier to see
set energy (spider-health)
setxy random-xcor random-ycor
]
setup-patch
display-labels
reset-ticks
end
;;;;; nest food patch;;;
to setup-patch
ask patches
[ setup-nest
setup-food
recolor-patch ]
end
;;;;; setup nest
to setup-nest ;; patch procedure
;; set nest? variable to true inside the nest, false elsewhere
set nest? (distancexy 0 0) < 5
;; spread a nest-scent over the whole world -- stronger near the nest
set nest-scent 200 - distancexy 0 0
end
to setup-food ;; patch procedure
;; setup food source one on the right
if (distancexy (0.6 * max-pxcor) 0) < 5
[ set food-source-number 1 ]
;; setup food source two on the lower-left
if (distancexy (-0.6 * max-pxcor) (-0.6 * max-pycor)) < 5
[ set food-source-number 2 ]
;; setup food source three on the upper-left
if (distancexy (-0.8 * max-pxcor) (0.8 * max-pycor)) < 5
[ set food-source-number 3 ]
;; set "food" at sources to either 1 or 2, randomly
if food-source-number > 0
[ set food one-of [1 2] ]
end
to recolor-patch ;; patch procedure
;; give color to nest and food sources
ifelse nest?
[ set pcolor violet ]
[ ifelse food > 0
[ if food-source-number = 1 [ set pcolor cyan ]
if food-source-number = 2 [ set pcolor sky ]
if food-source-number = 3 [ set pcolor blue ]
if food-source-number = 4 [ set pcolor brown ] ]
;; scale color to show chemical concentration
[ set pcolor scale-color green chemical 0.1 5 ] ]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;; GO ;;;;;;;;;;;;;;;;;;;;;;
to go ;; forever button
;;;;;;;;;;;;Spider ;;;;;;;;
ask antiagents [
setup-spider-movemonet ; option for user to select spider movement
;move-spider
catch-ant
spider-death
]
;;;;;;;;;; Ant ;;;;;;;;;;;;
ask agents
[ if who >= ticks [ stop ] ;; delay initial departure
ifelse color = orange
[ look-for-food ] ;; not carrying food? look for it
[ return-to-nest ] ;; carrying food? take it back to nest
wiggle
fd 1 ]
diffuse chemical (diffusion-rate / 100)
ask patches
[ set chemical chemical * (100 - evaporation-rate) / 100 ;; slowly evaporate chemical
recolor-patch ]
tick
display-labels
;;;;;;;;;;; Stop function ;;;;;;;;;;
if count agents = 0 [stop]
if count patches with [pcolor = blue] = 0 [stop]
end
;;;;;;;;;;;;;;;;;;;;;;;;;; function in go ;;;;;;;;;;;;;;;
to look-for-food ;; turtle procedure
if food > 0
[ set color green + 1 ;; pick up food
set food food - 1 ;; and reduce the food source
rt 180 ;; and turn around
stop ]
;; go in the direction where the chemical smell is strongest
if (chemical >= 0.05) and (chemical < 2)
[ uphill-chemical ]
end
;;;;;;;;;;; ant function ;;;;;;;;;;
;; sniff left and right, and go where the strongest smell is
to uphill-chemical ;; turtle procedure
let scent-ahead chemical-scent-at-angle 0
let scent-right chemical-scent-at-angle 45
let scent-left chemical-scent-at-angle -45
if (scent-right > scent-ahead) or (scent-left > scent-ahead)
[ ifelse scent-right > scent-left
[ rt 45 ]
[ lt 45 ] ]
end
to return-to-nest
ifelse nest?
[ ;; drop food and head out again
set color orange
rt 180 ]
[ set chemical chemical + 60 ;; drop some chemical
uphill-nest-scent ] ;; head toward the greatest value of nest-scent
end
to wiggle ;; turtle procedure
rt random 40
lt random 40
if not can-move? 1 [ rt 180 ]
end
to uphill-nest-scent
let scent-ahead nest-scent-at-angle 0
let scent-right nest-scent-at-angle 45
let scent-left nest-scent-at-angle -45
if (scent-right > scent-ahead) or (scent-left > scent-ahead)
[ ifelse scent-right > scent-left
[ rt 45 ]
[ lt 45 ] ]
end
to-report chemical-scent-at-angle [angle]
let p patch-right-and-ahead angle 1
if p = nobody [ report 0 ]
report [chemical] of p
end
to-report nest-scent-at-angle [angle]
let p patch-right-and-ahead angle 1
if p = nobody [ report 0 ]
report [nest-scent] of p
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;; Spider-Function ;;;;;;;;;;;;;;;;;;;;;;
to move-spider
rt random 360
lt random 360
fd 3
end
to spider-death ;; turtle procedure
if energy <= 0 [ask antiagents-here [die]]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
to catch-ant
let prey one-of agents-here
if prey != nobody
[ ask prey [ die ]
set energy (energy - ant-venom-strength)]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; GUI Function ;;;;
to display-labels
ask antiagents [ set label "" ]
if show-spider-health [
ask antiagents [ set label round energy ]
]
end
;;;;;;; Spider movement GUI ;;;;;;
to setup-spider-movemonet
if setup-spider-movement
[
ask antiagents [ move-spider ]
]
end
To make a monitor that displays the tick count, the complete code to put in the monitor is:
ticks
That's all.
If you want the monitor to show the tick count when there are no agents, but be blank otherwise, you would put this code in:
ifelse-value any? agents
[ "" ]
[ ticks ]
Your syntax is incorrect. You could however include in an observer procedure (e.g., your go procedure) the following: if (count agents = 0) [show ticks]. This would display in the area above the command line.
However it sounds like you are looking for user-message, rather than show. E.g., if (count agents = 0) [user-message (word ticks)]. http://ccl.northwestern.edu/netlogo/docs/dict/user-message.html
If you want to update the monitor each tick but only when there are agents, you need to create a separate global variable (called counter below) and update that instead. The ticks internal variable will always increase so monitoring it will always increment. This is because the ticks variable is the simulation clock, it reports the passage of time.
globals [counter]
to setup
...
set counter 0 ; note, not required as initialise to 0 but helps readability
reset-ticks
end
to go
...
if any? turtles [ set counter counter + 1 ]
...
tick
end
Then create a monitor with just counter (and 0 decimal places etc)

Optimal Path on a given graph

I am working on a project in netLogo in which i have a random network in which each and every link is assigned a bandwidth. The algorithm chooses a random Source and Destination by itself and after which it has to choose an optimal path between these two.
My question is how to choose the optimal path by exploring all the possible paths.
hereby attaching the sourcecode of my model:
breed[nodes node]
breed[ants ant ]
globals [nodename nodenumbersource nodenumberdestination relaynode dead-network num ]
nodes-own[visited ]
links-own[visit bandwidth]
ants-own
[
distance-gone
distance-to-go
target-node
current-node
]
to cr11
ask nodes with [label = "Source"]
[
set num count (link-neighbors)
]
create-ants num ;num-ants
[
let n one-of nodes with [label = "Source"]
setxy ([xcor] of n) ([ycor]of n)
set current-node n
set color white set size 0.95
set distance-gone 0
set distance-to-go 0
set target-node one-of nodes with [ label = "Relay Node" ] ;nobody
]
end
to face-targets
ask ants ;with [ target-node]; = node 4 ] ;nobody ]
[
let d 0
face (one-of nodes with [ label = "Relay Node" ]);target-node
ask current-node [
set d distance (one-of nodes with [ label = "Relay Node" ]);target-node)
]
set distance-to-go d
]
end
to move-forward
face-targets
ask ants [
while [ distance-gone < (distance-to-go )]
[
fd 1
set distance-gone (distance-gone + 1)
]
]
ask ants [
if distance-gone < distance-to-go
[
set current-node target-node
setxy ([xcor] of current-node) ([ycor] of current-node)
set distance-gone 0
set distance-to-go 0
]
]
end
;This is used to design the Network
to setup
setup1
setup-spatially-clustered-network
ask links [set color white
set visit false
set bandwidth (5 + random 10) ;min bw 5 max 15
]
end
to setup1
__clear-all-and-reset-ticks
set dead-network 0
create-nodes number-of-nodes
[
setxy (random-xcor * 0.95) (random-ycor * 0.95)
set shape "circle"
set color green
set visited false
set label who
]
end
;Links are created for the nodes
to setup-spatially-clustered-network
let num-links (6 * number-of-nodes) / 2
while [count links < num-links ]
[
ask one-of turtles
[
let choice (min-one-of (other turtles with [not link-neighbor? myself])
[distance myself])
if choice != nobody [ create-link-with choice
]
]
]
repeat 10
[
layout-spring turtles links 0.3 (world-width / (sqrt number-of-nodes)) 1
]
end
;This is to Generate Message for nodes
to test1
ask one-of nodes
[
set color red
set label "Source"
set nodenumbersource who
]
ask one-of nodes with [color = green]
[
set color red
set label "Destination"
set nodenumberdestination who
]
cr11
end
to test3
ask turtles with [label = "Source"]
[
set label "ants moving"
ask my-links
[
set color green
]
ask link-neighbors
[
set color blue
]
ask min-one-of turtles with [color = blue and my-links] [distance turtle nodenumberdestination ]
[
ask max-one-of my-links [bandwidth ]
[
set color red
]
set color white
set relaynode who
set label "Relay Node"
]
; face-targets
move-forward
end
to test4
ask turtle nodenumberdestination
[
while [color != white]
[
ask turtle relaynode
[
set label ""
ask my-links
[
set color green
]
ask link-neighbors
[
set color yellow
]
]
ask turtles with [color = yellow]
[
set color violet
]
ask turtles with [color = violet] with [visited = false]
[
set color magenta
]
ask min-one-of turtles with [color = magenta] [distance turtle nodenumberdestination]
[
set color white
set relaynode who
set label "Relay Node"
set visited true
]
move-forward
]
]
end
to test6
ask nodes ; turtles
[
set color green
set visited false
set label ""
]
ask links
[
set color white
set visit false
]
end
to test5
test1
test3
test4
end
You can use the NW-Extension for that! Just download it and stick it in NetLogo's extensions folder. Then, in your model, you can start using by adding
extensions [ nw ]
to the top of your code. Then you can use one of the weighted-path-to primitives to get the turtles or links along the shortest path between two nodes.
Note that the nw extension is under active development, though it is well tested. You also must be using the latest version of NetLogo.
If you want to implement it yourself, Dijkstra's algorithm is the classic solution if you have nonnegative weights in your graph.