2.16. Lecture 15: Herds, flocks, and traffic jams

Before this class you should:

  • Read Think Complexity, Chapter 10

Before next class you should:

  • Read Think Complexity, Chapter 11

Note taker: Ethan Hodge

2.16.1. Topics covered in this lecture

This lecture covered 3 main topics:

  • Traffic Jam Modelling

  • Boid Modelling

  • Emergence and Free Will

The lecture also spent time covering the code in the Boids7nb.ipynb and the chap10.ipynb files from the lab11 folder.

Previous lectures covered agents in discrete space while this lecture has agents in a continuous space.

2.16.1.1. Traffic Jams

What causes traffic jams in real life?

  • Accidents can cause major traffic delays

  • Speed traps causing drivers to suddenly slow down

  • Animals on the road

  • Sometimes traffic jams can appear for no apparent reason

2.16.2. Highway Model

The model is based on the Turtles, Termites, and Traffic Jams Highway model. The setup is a simple circular track that has a number of cars (agents) placed evenly on it to start with. Each car has the autonomy to only decide it’s acceleration based on the choose_acceleration function.

Highway Class

class Highway:
    def __init__(self, n=10, length=1000, eps=0):
            self.length = length
            self.eps = eps

            # create the drivers
            locs = np.linspace(0, length, n, endpoint=False)
            self.drivers = [Driver(loc) for loc in locs]

            # and link them up
            for i in range(n):
                j = (i+1) % n
                self.drivers[i].next = self.drivers[j]

n = number of cars
length = length of the highway
eps = amount of random noise passed to the system

As shown in the highway class above, the location of the drivers, locs, is initialized to be evenly spread along the length of the highway. The cars are then linked to form a circle where the last car points to the first car.

Highway Move

def move(self, driver):
    # get the distance to the next driver
    dist = self.distance(driver)

    # let the driver choose acceleration
    acc = driver.choose_acceleration(dist)
    acc = min(acc, self.max_acc)
    acc = max(acc, self.min_acc)
    speed = driver.speed + acc

    # add random noise to speed
    speed *= np.random.uniform(1-self.eps, 1+self.eps)

    # keep it nonnegative and under the speed limit
    speed = max(speed, 0)
    speed = min(speed, self.speed_limit)

    # if current speed would collide with next driver, stop
    if speed > dist:
        speed = 0
        self.crashes += 1

    # update speed and loc
    driver.speed = speed
    driver.loc += speed

This function is called in the Highway step function for each driver. The agent gets to decide only the distance, which is then used to calculate the acceleration. The function ensures that the calculated acceleration is within the range [-10, 1]. Then the speed is updated and random noise is added to the speed based on epsilon. Then the function checks for a collision, if there is a collision then the speed is set to 0. Finally the location is updated.

Random Perturbation

The figure below demonstrates how adding the random noise greatly decreases the max amount of cars that can travel at a given average speed.

../_images/perturbance.png

2.16.2.1. Boids

What is a boid?

A boid comes from the book Flocks, herds, and traffic jams. Boid stands for bird-oid and is pronounced like how an american might say bird. This model is used to explore the behaviour of groups of fish, cows, insects, and birds and study how they move in schools, flocks, herds, and nests. A boid agent has vision that it uses to maneuver based on the flock centre, collision avoidance, and velocity matching. The environment setup is a flock of boids and the carrot which the boids are attracted to.

Boid Functions

Center: Finds other Boids within range and computes a vector toward their centroid.

def center(self, boids, radius=1, angle=1):
   neighbors = self.get_neighbors(boids, radius, angle)
   vecs = [boid.pos for boid in neighbors]
   return self.vector_toward_center(vecs)

Avoid: Finds objects, including other Boids, within a given range, and computes a vector that points away from their centroid.

def avoid(self, boids, carrot, radius=0.3, angle=np.pi):
    objects = boids + [carrot]
    neighbors = self.get_neighbors(objects, radius, angle)
    vecs = [boid.pos for boid in neighbors]
    return -self.vector_toward_center(vecs)

Align: Finds other Boids within range and computes the average of their headings.

def align(self, boids, radius=0.5, angle=1):
    neighbors = self.get_neighbors(boids, radius, angle)
    vecs = [boid.vel for boid in neighbors]
    return self.vector_toward_center(vecs)

Love: Computes a vector that points toward the carrot.

def love(self, carrot):
    toward = carrot.pos - self.pos
    return limit_vector(toward)

Set Goal (Arbitration): Has weights for the above functions and calculates goal. The move velocity is then updated to be a mix of the current velocity and the goal velocity.

def set_goal(self, boids, carrot):
    # weights for various rules
    w_avoid = 10
    w_center = 3
    w_align = 1
    w_love = 10

    self.goal = (w_center * self.center(boids) +
        w_avoid * self.avoid(boids, carrot) +
        w_align * self.align(boids) +
        w_love * self.love(carrot))

    self.goal.mag = 1

Notebook Notes

Controls for the boid window:

Pan - shift + drag

Rotate - ctrl + drag

Zoom - Alt (option on mac)

Move carrot - click

2.16.2.2. Emergence and Free Will

Emergence in our course

Consider some of the properties of the complex systems we have studied so far:

  • The Rule 30 cellular automaton is deterministic. Yet it generates a sequence statistically indistinguishable from random.

  • The agents in Schelling’s model are not racist but their actions result in a high degree of segregation.

  • Agents in Sugarscape form waves that move diagonally even if the agents cannot.

  • Traffic jams move backward even though the cars in them are moving forward.

  • Flocks and herds behave as if they are centrally organized even though the animals within them make individual decisions based on local information.

Free Will Paradox

Free will is the ability of a person to make their own choices. However, if our bodies and brains are governed by deterministic physical laws, our choices are completely determined. Many people believe they have free will abecause they feel like they can make their own choices. This ties in with emergence as it shows that very complex actions can occur from very simple and defined rules leading to the question of if our actions are a result of very simple rules.

There have been many suggested approaches to solve this problem.

William James

William James proposed a 2-stage model that states that a random process generates the possible actions which are then deterministically chosen from.

David Hume

David Hume proposed that perception of choices is an illusion because the system that produced our actions is deterministic.

Free will Vs Determinism Crash Course video

The crash course video covers many interesting concepts in the free will vs determinism argument.

Arguments for Libertarian free will:

  • Person can have free will even if neurons actions are deterministic.

  • People feel like they have free will to make choices.

Arguments for Determinism

  • Analogies drawn to the story of Oedipus and how he couldn’t escape fate.

  • Events have a cause from past events that nothing is random (Reductionism).

  • Determinists and Reductionists have said that our actions are made of our belief, desire, and temperment which are all related to previous events.