Evolving interior designs with simulated annealing and genetic algorithm
By: Eliška Svobodová
Tags: Genetic Algorithm, Artificial Intelligence, Simulated Annealing, Interior Design

My solution

I decided to tackle the problem similarly as human designers do — I divided the design process into two phases. First, I create a high-level plan of the space by deciding what part of the room will serve what function. These parts are called functional zones — rectangular spaces that each serve some function, like sleeping, dining, or working. Then I arrange the furniture inside these zones in relation to each other (and to a wall).

Design process — user inputs the requirements (room size, functions, furniture), the system plans the space by positioning functional zones, and furniture is arranged into zones.

The biggest advantage of this approach is, that I am dividing one big problem into two smaller ones. By planning the zones first, I get a more logical usage of space and fewer things to worry about when I am arranging furniture into zones.

User requirements

As human designers, our system has to accept user requirements and satisfy them. The user has to input the shape and features of the room (positions of doors and windows), the functions that the room has to fulfill, and furniture that is going to be placed inside the zones.

Zone planning

The purpose of the zones is to ensure an effective and functional high-level plan of the room. That includes:

The “flow” — how the human moves through the room. It has to be possible to walk between all zones and doors. This constraint includes the requirement for doors to be accessible.

The usage of the space — there shouldn’t be any space not covered by a zone or an aisle. Additionally, it is more important for some zones to be near a window than for the others. For example, the work zone should be by a window to get as much light as possible.

The sizes of the zones — zones have to be big enough to accommodate all of its furniture. Also, zones with more or larger furniture should take up more space than the ones with furniture with smaller areas.

These requirements are all taken into account in a cost function that evaluates the plan of the room. Because it is “bumpy” with lots of local optimums, I decided to use simulated annealing to avoid being trapped in a local minimum and find the best result possible.

Simulated annealing got its name from a metallurgic process when metal is quickly heated up and then gradually cooled down to gain better properties. We encode solutions into states in a state space and let the algorithm look through it. The algorithm simulates the temperature with a variable T that controls the amount of exploration. In every iteration, we generate a neighboring solution and if it is better we accept it as a new starting point. If it is worse we accept it with certain probability controlled by the temperature. At first, the temperature is high and the algorithm has circa 80 % chance at accepting a worse solution (and potentially get closer to even better solutions). Gradually, the temperature is decreased and we exploit a promising sector by mostly accepting only better solutions.

One solution represents the room with all zones having specific shapes and positions. The neighboring solution is generated from the current solution by moving or resizing a random number of zones. The distance by which can the zone change is limited. The step limit is, as well as temperature, high at the beginning of the algorithm and gradually decreases.

A simplified illustration of state space that is searched with simulated annealing. [green = relax zone, red = work zone, blue = sleep zone, orange = storage zone]

I distinguish between storage zones and the other zones. Storage zones contain only one piece of furniture (a wardrobe, or a shelf, etc.), on the contrary, other zones almost always contain more objects. That’s why storage zones have fixed sizes. They are also always positioned by a wall. This distinction helps to reduce the state space and speed up the searching process.

Simulated annealing starts with a random solution. One iteration consists of generating a new neighboring solution, its evaluation, and its acceptance or rejection. We perform several iterations for each value of the temperature (an epoch). The algorithm continues until there was no significant improvement in the cost of the solution for one epoch.

Pseudo-code of simulated annealing applied to zone planning.

Furniture arrangement

In this phase, functional zones are fixedly positioned in the room and we have to arrange the given furniture inside them.

Genetic algorithm searches the state space through evolution-like process. It maintains a group of solutions — a population consisting of individuals. In each iteration, some individuals are selected to pass on their genes. Their genomes are combined using crossover operator and newly created individuals are passed to the intermediate population. The rest of this population is composed of the best unchanged individuals of the previous population — the elite. Then, mutation operator is applied to a percentage of the intermediate population. The resulting population is the new population and next iteration starts. Selection operator chooses individuals to reproduce. The better ones have a higher chance at being selected. Crossover operator combines parts of the encoded solutions to create (hopefully) better solutions. Mutation operator introduces small random changes to a single solution. It ensures the diversity of a population (its genome).

One solution represents the positions of all furniture from one zone. Each zone is optimized separately from the others as one evolving population. The evaluation function consider:

Overhanging the room or the zone.

Overlapping of the objects or their free areas. Some objects need to have free space around themselves to serve their function (for example an area in front of the sofa). These free spaces are added to the shape of an object and are included in the overlapping penalty.

Proximity and arrangement of objects towards a wall.

Object relationships. The solution gets a penalty for not satisfying relationships between furniture.

I defined 3 types of relationships — next to, opposite to, and around. The relationship is between a parent and a child object and is mostly defined only on the child’s side. For example, a nightstand knows that it should be next to a bed. The only exception is the around relationship that has to be defined on both sides — child object has “around” relationship and parent object has “around center” relationship. Every relationship has a cost function and a function that can move the child object to the position where the spatial relationship is satisfied.

I use stochastic universal sampling as a selection operator. It is inspired by a roulette wheel with n equally spaced pointers. Each individual is evaluated by a cost function and assigned fitness (how good it is compared to others). Each individual gets a proportionally large part of the wheel to its fitness. When we spin the wheel, better individuals have a higher chance of being selected (even multiple times). At the same time, a few worse solutions will be also selected to preserve the diversity of the gene pool.

The crossover operator works with two individuals. Itchooses random parts of the chromosome which represent the positions of furniture inside the zone. Then it switches the positions of the corresponding objects.

The crossover operator takes two chromosomes and exchanges positions of random furniture.

Usually, the mutation is applied to a small percentage of the population (around 1 %) and makes simple random changes. This approach didn’t work for me, because the relationships between objects are too complex and the genetic algorithm wasn’t able to find an acceptable solution. So, I developed more complex mutations that better support “human-like” furniture arrangement:

Move a random piece of furniture in a random direction. If the object has a parent, move parent with the object.

Randomly change the orientation of a random object. If the object

has a parent, rotate them together.

has a parent, rotate them together. Move a random object to its nearest wall.

Move a random object to the object that is nearest to it.

Pick a random object and align it with another random object. Randomly choose whether to align their centers or one of its sides.

Randomly pick an object and arrange it according to one of its relationships.

I don’t use usual with elitism, crossover, and mutation rates. My intermediate populations consist of 70 % of elite and 30 % of newly-created individuals (by crossover). Then I apply mutation on 50 % of this intermediate population.

Results

I implemented the described system and run a series of experiments. I created 11 rectangular rooms, 14 L-shaped rooms, and 7 rooms with other shapes. They contain varying furniture and functions. The algorithms were run on each room 10 times and I hand-picked the best result.

The images below show some of the best results. The system was able to find an acceptable solution for almost every room (object relationships are satisfied, objects don’t overlap, all parts of the room are accessible).