The parenting challenges of a pandemic induced lockdown

The hardest aspect of COVID19 has been the impact on our 3yr old daughter, Gess. She’s at that age where she knows something is not right but not yet old enough to understand why. It’s been really…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Behavioral systems

This article describes how we can use behavioral algorithms and agent-based models to further abstract the relationship between a set of input parameters and a set of solutions in a design space. To create such a system we define a collection of agents who follow a set of rules or behaviors over a series of time steps. These behaviors dictate how the agents interact with other agents and their environment, and how these interactions affect the internal state of the agents.

In computer science, such systems are often called agent-based models and we can easily implement them using Object-oriented programming (OOP). To do so we create a class which defines the structure of the agent, with local variables that define its states and a set of methods which define its behaviors. Then we create a set of instances of this Class and let the instances play out their behaviors over a series of time steps. Because such a system has to play out over multiple time steps, it is called a dynamic system, as opposed to static systems which can be computed directly in one step.

Agent-based systems are often used to model complex behaviors in nature, which are also typically defined by the interaction of a large number of agents who are driven by a relatively simple set of rules. Examples of such systems include the flocking of birds, the organization of ants, the growth of slime mold, and the construction of termite mounds. These types of systems are often called emergent because of their ability to develop highly complex behaviors and structures from a set of relatively simple behaviors.

Flocking is a typical complex behavior which can be simulated through agent-based programming

In the context of Generative Design, we can use such agent-based systems to define solutions within a design space by parameterizing the behaviors of a set of agents, allowing the behaviors to play out over a series of time steps, and then taking the final state of the agents as the design solution. This provides a direct yet complex mapping between the input parameters and the design solutions which can be explored by the optimization algorithm to find the best solutions within the design space.

This method of parameterizing a design space is similar to the way that forms develop in nature. We can think of the genome of each organism as encoding the behaviors of its cells and component, which are played out over the lifetime of the organism, leading to the development of its physical form or phenotype.

As with the recursive systems described previously, this is an example of an indirect control strategy which abstracts the way the input parameters control the phenotype of each design solution. This approach offers two opportunities for crafting design spaces:

To create a CA you have specify the following components:

We will begin by creating a ghPython component with five inputs that define the CA system:

ghPython component with five inputs and one output

The first four inputs can be set with number sliders while the last one can be set with a Gene Pool component. Double-clicking on the Gene Pool component allows you to set the number of parameters in the Gene Pool along with the number of decimal places and the minimum and maximum value of each parameter.

To guide the behavior of the CA system, the rule set describes the next state of a cell based on every possible configuration of the current states of the cell and its neighbors. The range of these values is based on the number of possible states of the cells.

In this case our cells will have two possible states, so we want each rule parameter to output either a 0 or 1. Although the node allows you to use integers directly by setting Decimals to zero, in practice the Galapagos genetic algorithm built into Grasshopper has an easier time working with floats. Thus we will specify two decimal places and a range of [0.00, 1.99] for the parameters. Then we will use the F (Floor) output of the Round node to round the values down to either 0 or 1.

To determine the number of rule parameters we need, we need to calculate the number of possible state configurations given the number of possible states of each cell and the number of cells we are considering in a group. This permutation can be calculated by raising the number of states to the power of the number of cells. In this case we have two possible states and five cells in a group (the cell itself and it’s four neighbors) so we need 2⁵ = 512 rules.

Setting of parameters for the Gene Pool component

Along with the five input parameters, the ghPython component also needs one output to send out the final states of the cells so we can visualize them in Grasshopper.

Now double-click on the ghPython component and copy and paste to following code into it:

The first block of code starting with class Cell is the class definition which defines four methods or behaviors for the Cell object:

So the next state of the cell would be the value of the 21st rule in the rule set.

Once the cells are created we set the state of the first cell to 1, which defines the initial condition of the system before any behavior has played out. Otherwise, if all the cells start in the same state the system will stagnate because each cell would be stuck following the same rules at each time step. The choice of this initial state can be arbitrary or can be based on the specifics of your model or design problem. You can even experiment with using the initial state as a parameter in your design space model.

In the next block of code, we iterate over the 2d structure of the ‘cells’ list to specify the neighbors of each cell. In this case the neighbors of each cell will be the four cells immediately above, below, to the left, and to the right. This is known as the cell’s ‘4-neighbors’, as opposed to the ‘8-neighbors’ which also include the four cells on the diagonal.

4-neighbor vs. 8-neighbor relationship
In a continuous world the cell on the edge has four neighbors while in a constrained world it has three

The reason we need to separate the calculation and setting of the next state is because we want each cell to calculate its next state based on the starting states of all cells at the beginning of each iteration. Otherwise, the behavior would not be controlled directly by the rule set and would depend heavily on the order of the cells in the grid.

Once the behavior of the system has played out the specified number of steps, we create an empty list called ‘states’ to output the state of each cell back to our Grasshopper definition. We then iterate over all the cells and append their final state to this list. Once we have this data we can visualize the grid of cells with some additional Grasshopper nodes:

Visualization of cell grid with Grasshopper

First we create a grid of points at the same resolution as the grid of cells, then use a Gradient component to assign colors based on the cell state, and visualize the grid by placing a dot of the right color at each point using the Dots component. Right click the Gene Pool component and select Randomize 100% to create a random rule set. Now you can scrub through the slider attached to the steps input of the ghPython node to play out the CA simulation for that rule set:

CA behavior played out over 20 time steps

This completes our simple implementation of CA, but to test it within a Generative Design context we need to establish a goal for the process to optimize toward. In a real application this goal should relate to the design problem you are trying to solve. However, for demonstration purposes we will create a simple score based on the final state of the cells. We will then see how the Genetic Algorithm is able to tune our rule set and the number of steps to maximize this score.

This calculates the score for an individual cell with a simple conditional:

Now, at the end of the script, add some code to initialize a score variable to store the total score of the system and then loop through all the cells to calculate their scores and add them to the total score:

This creates a goal which tries to maximize the number of cells of state 0 (the red cells in the graphic above) which have a maximum of cells around it with state 1 (the blue cells). Without the wrapping condition at the boundary, or with an even number of cells in both axes, the best solution would be a checker-board (try this to be sure). However, with the wrapping condition and an odd number of cells the best solution is a bit more complex since in a checkerboard the 0 cells at the boundaries will also have 0 neighbors.

Predictability of maximum score based on boundary condition and grid resolution

Let’s see if we can use optimization to find the best solution within this design space. Start by creating a Galapagos component and connecting the Gene Pool component and the slider connected to the steps input to the Genome and the score output to the Fitness. Remember that you connect things to Galapagos by clicking and dragging from the nodes on the Galapagos component, and you can hold Shift to connect multiple inputs. Since Galapagos only supports single objective optimization you can only connect one value to Fitness.

Galapagos setup

Now double-click on the Galapagos component to open the optimization interface. Keep all the default settings on the Options tab, then switch to Solvers, make sure the Evolutionary Solver is enabled, and then run the optimization until it converges on a solution.

With such a small system, the advantages of an indirect parameterization through CA are not so obvious. After all, we need 512 input parameters to enumerate all possible rules, while we could use only 25 input parameters to directly control the states of each cell in the grid. In this case, such a direct parameterization would be able to find the same solution, perhaps even faster than our CA system. However, the real opportunity of behavioral systems is that they are scale independent, since we are parameterizing a single set of rules which can be used to control any number of agents. This means that we can apply the same strategy to a much larger system which would be impractical to parameterize directly.

Let’s try this by changing the resolution of the grid to 50 x 50. To parameterize this system directly would require 50 x 50 = 2,500 individual input parameters. However, in our case we can use the same exact rule set of 512 parameters, since the number of states and the number of neighbors each cell considers stays the same.

CA system scaled up to 50 x 50 grid

This article described how you can use agent-based behavior to abstract the relationship between a set of input parameters and a set of designs within a design space. As an example we used the Cellular Automata (CA), one of the oldest agent-based systems developed to simulate growth in nature. Such systems can be used in a variety of architectural applications, for example the structuring of a facade or the layout of floor plans or urban neighborhoods. However, CA’s are not the only type of agent-based system. Over the years a variety of such systems have been developed to model a range of behaviors in nature — for example the flocking of birds, ant trails, slime mold growth, even traffic patterns. You should explore these algorithms on your own and think how you can apply their logics to the design of your own complex design spaces.

Add a comment

Related posts:

Are you tired of centralized exchanges controlling your trades and restricting your access to certain assets?

Are you tired of centralized exchanges controlling your trades and restricting your access to certain assets? Say hello to Injective Protocol, the ultimate solution for decentralized trading of any…

Better review history

Something went wrong? You don’t like the last post you published? No problem: you can now rollback to any previous version of your records! What’s the difference? Easy: you can create more content…

Both Sides Now

During my business trip, I lived in an Airbnb flat with a bookshelf. So, I came across a book, or rather an album by Chinese artist Peng Wei “Letters From a Distance”. She made Chinese ink paintings…