# How to change from random walk ro self avoiding random walk in Julia

**URL:** https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268
**Category:** General Usage
**Tags:** question
**Created:** [July 25, 2021, 3:56pm UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268 "2021-07-25T15:56:47Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Struggling\_Student](https://avatars.discourse-cdn.com/v4/letter/s/ee59a6/32.png) [@Struggling\_Student](https://discourse.julialang.org/u/Struggling_Student)
#### Post date: [July 25, 2021, 3:56pm UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268/1 "2021-07-25T15:56:47Z")

</div>

Could someone help me to change the random walk to self-avoiding random walk? I tried to do that but without success. Below is the code for the random walk, that works:

```julia
using StatsBase, LinearAlgebra

# Here I defined the position in the NxN matrix
function position(vertical, horizontal, N)
            
    ud = BitArray(a == vertical for a = 1:N ) # Goes up or down
    lr = transpose(BitArray(a == horizontal for a = 1:N )) # Goes left or right

    return ud .* lr
end

function SAW(N, Iterations=3) # SAW, Self Avoiding Walk
    
    x = ceil(N/2) # x,y are the starting positions
    y = ceil(N/2)
    Mat = zeros(Int8, N , N) # this is the lattice 
    pos = zeros(Int8, N , N) # this is our position
       
    for i in 1:Iterations
        
        RandomOnes = sample(-1:2:1, 2, replace = false)[1] #gives the values -1 or 1
        ZeroOne = sample(0:1, 1, replace = false)[1] #gives the values 0 or 1
        
        #Check where a free space is and create a list accordingly
        
        
        # In order to avoid moving diagonally, only one of the two variables (x,y)
        # can have the values 1 or -1, the other one has to be 0 (e.g. if x = 1 then y = 0)       
        if ZeroOne == 1 
            x += RandomOnes
            y += 0
        else
            x += 0
            y += RandomOnes
        end
               
        Mat += position(y,x,N)
        pos = position(y,x,N)
    end
    
    for i in 1:N
        for j in 1:N
            if Mat[i,j] == 1
                Mat[i,j] += 0
            end
        end
    end
                
    return Mat, pos
end

```

I know that I have to save the last position of my walker, and see if he was already there but I have no idea how to implement it in my code

---

<div class="post-metadata">

### Author: ![ess3sq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ess3sq/32/26834_2.png) [@ess3sq](https://discourse.julialang.org/u/ess3sq)
#### Post date: [July 26, 2021, 6:22am UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268/2 "2021-07-26T06:22:02Z")

</div>

> [@Struggling\_Student](#):
>
> I know that I have to save the last position of my walker, and see if he was already there but I have no idea how to implement it in my code

Which part is confusing to you?  
You can start by creating some array or set to hold the past positions. Every time the walker moves, you save the new position inside it. Every time the walker is supposed to move, you check if the potential new position is inside the array or not, and handle accordingly.

---

<div class="post-metadata">

### Author: ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)
#### Post date: [July 26, 2021, 8:12am UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268/3 "2021-07-26T08:12:38Z")

</div>

A naive approach to implement a SAW would be to set a volume for each random walker. At each time, you have to check if the current walker is within any volume of other existing walkers. However, this approach is not practically useful. To see a review of advanced algorithms, see here for example: [simulator](https://clisby.net/projects/sm_simulator/).

---

<div class="post-metadata">

### Author: ![Struggling\_Student](https://avatars.discourse-cdn.com/v4/letter/s/ee59a6/32.png) [@Struggling\_Student](https://discourse.julialang.org/u/Struggling_Student)
#### Post date: [July 26, 2021, 10:09am UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268/4 "2021-07-26T10:09:23Z")

</div>

> [@ess3sq](#):
>
> w position inside it. Every time the walker is supposed to move, you check if the potential new position is inside the array or not, and handle accordingly.

unfortunately thats the part where I don’t know how to code, I tried a different approach for avoiding runing into itself:

```julia
   for i in 1:11
    
        RandomOnes = sample(-1:2:1, 2, replace = false)[1] #gives the values -1 or 1
        ZeroOne = sample(0:1, 1, replace = false)[1] #gives the values 0 or 1
        
    if ZeroOne == 1
       if position(y+1,x,N)[y+1,x] & position(y-1,x,N)[y-1,x] == 0
            y += RandomOnes 
            x += 0
            elseif position(y+1,x,N)[y+1,x] == 0
                y += 1
                x += 0
            elseif position(y-1,x,N)[y-1,x] == 0
                y += -1
                x += 0
            end
        return x, y
        
    if ZeroOne == 0
            if position(y,x+1,N)[y,x+1,] & position(y,x-1,N)[y,x-1] == 0
            x += RandomOnes 
            y += 0
            elseif position(y,x+1,N)[y,x+1] == 0
                x += 1
                y += 0
            elseif position(y,x-1,N)[y,x-1]== 0
                x += -1
                y += 0
            end

```

---

<div class="post-metadata">

### Author: ![ess3sq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ess3sq/32/26834_2.png) [@ess3sq](https://discourse.julialang.org/u/ess3sq)
#### Post date: [July 26, 2021, 10:34am UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268/5 "2021-07-26T10:34:05Z")

</div>

> [@Struggling\_Student](#):
>
> unfortunately thats the part where I don’t know how to code, I tried a different approach for avoiding runing into itself:

Please be more specific. Do you not know how to create an array, or how to check membership of one? Or how to put something into an array? Because those are the three things you need.

---

<div class="post-metadata">

### Author: ![Struggling\_Student](https://avatars.discourse-cdn.com/v4/letter/s/ee59a6/32.png) [@Struggling\_Student](https://discourse.julialang.org/u/Struggling_Student)
#### Post date: [July 26, 2021, 10:51am UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268/6 "2021-07-26T10:51:07Z")

</div>

I guess all the things you mentioned

---

<div class="post-metadata">

### Author: ![ess3sq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ess3sq/32/26834_2.png) [@ess3sq](https://discourse.julialang.org/u/ess3sq)
#### Post date: [July 26, 2021, 12:05pm UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268/7 "2021-07-26T12:05:54Z")

</div>

```julia
positions = [] # create
push!(positions, newpos) # put newpos in array
if newpos in positions
     # do stuff
end

```

The order and when to do what is for you to figure out (refer to my first comment).

---

<div class="post-metadata">

### Author: ![viraltux](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/viraltux/32/15236_2.png) [@viraltux](https://discourse.julialang.org/u/viraltux)
#### Post date: [July 26, 2021, 9:42pm UTC](https://discourse.julialang.org/t/how-to-change-from-random-walk-ro-self-avoiding-random-walk-in-julia/65268/8 "2021-07-26T21:42:19Z")

</div>

Welcome Student!

Allow me first, if I may, to advice you to consider to change your nick to Courageous\_Student 🙂

Here you have a solution I wrote quickly; I haven’t tested it thoroughly but it shows nonetheless a few of the things you can do in Julia and perhaps you can adapt it to you needs. Hopefully is self-explanatory but ask questions otherwise.

```julia
using DataStructures

function sarw(latsize::T,
              start::Tuple{T,T},
              nsteps::T) where T<: Integer

    # Ordered Dictionary to store a `from` `to` lattice 
    # of size latsize x latsize
    lat = OrderedDict{Tuple{T,T},Tuple{T,T}}()

    # possible movements
    up(pos) = (pos[1],pos[2]+1)
    down(pos) = (pos[1],pos[2]-1)
    left(pos) = (pos[1]-1,pos[2])
    right(pos) = (pos[1]+1,pos[2])

    # returns free positions to move from pos
    function free(pos,latsize)
        frl = []
        check(dir) = (1<= dir[1] <= latsize) && (1<= dir[2] <= latsize) &&
                     !haskey(lat,dir) && push!(frl,dir)
        check(up(pos))
        check(down(pos))
        check(left(pos))
        check(right(pos))
        frl
    end

    # nsteps number of steps
    for i in 1:nsteps
        fw = free(start,latsize)
        if length(fw) == 0
            @info "no free places to move"
            return lat
        end
        start = lat[start] = rand(fw)
    end

    lat
end

```

If we run the code we have

```julia
using Random
Random.seed!(36)

# self-avoiding random walk starting at (50,50) in a lattice of 100x100 
# and performing 1000 steps or stopping when the random walk is blocked.
rw = sarw(100,(50,50),1000)

[ Info: no free places to move
OrderedDict{Tuple{Int64, Int64}, Tuple{Int64, Int64}} with 59 entries:
  (50, 50) => (50, 51)
  (50, 51) => (49, 51)
  (49, 51) => (49, 52)
  (49, 52) => (49, 53)
  [...]

```

We can also plot the walk with Julia

```julia
using Plots
plot()
for (k,v) in rw
    plot!([k[1],v[1]],[k[2],v[2]],arrow=true,color=:black,
          linewidth=2,label=nothing)
end
current()

```

![image](https://global.discourse-cdn.com/julialang/original/3X/d/b/db282cd79a6f0cb52d251d8b3d7464bbfe3d4eac.png)
