#The “More Pizza” Problem
The “More pizza” problem has been described in a recent post and in this article – as promised – I’m going to describe the Simulated Annealing algorithm that I used to solve it.
First, this kind of problems is well known in Computer Science Literature as Knapsak 0/1.
Let’s consider an empty knapsack with a maximum capacity M and a group of N generic objects Obj[0], Obj[1], …, Obj[N-1]. Each object Obj[k] has a weight W[k]. The user is allowed to choose at most one of each item so that the sum of the items weights does not exceed the maximum capacity M.
The Knapsack 0/1 can be solved in different ways. In other words, you can easily find algorithms that are simpler than my proposal. Nevertheless, I want to reward you with some additional information that will help you to increase your chance to pass the Google Hash Code Qualification round.
#Qualification round: some considerations
Basing on my experience, during the Google Hash Code Qualification round, the time is your worst enemy.
The “More pizza” problem is not the challenge. The Google Team suggests to solve this problem to make practice and feel more comfortable with their platform. Therefore, even if you solve this problem, do not feel like you have passed an exam. Solving this problem does not mean passing the Qualification round. Finding the solution to this problem does not represent the real finish line.
For this reason, the best algorithm does not always provide the perfect solution. The best algorithm provides an acceptable solution immediately.
Your goal is to find an acceptable solution that is the best among the ones being uploaded by all teams around the world.
- “immediately” provide a feasible solution, even if this solution has the minimum score.
- always store in a file (in the format described by Google) any feasible solution that it generates, if it is better than the initial one.
- always calculate the score for each calculated solution, so that it is easier to label files to upload to the Judge System.
- avoid to be trapped in corner cases: your script will run indefinitely without providing any better results.
- If working with C++, avoid recursive functions. You will have 100% a stack-overflow when dealing with large amount of data.
- be as fast as possible: please, avoid brute-force solutions.
- be correct.
- the perfect solution might not exist. Do not search for it!
- read carefully the description of the problem (every single word is important).
- be a team player: listen ideas coming from other people!
#How to solve the pizza… sorry, the qualification round?
#How the code should be structured
- Data initialization: this part of your code is responsible to read data from a file.
- Body of the algorithm: this is what you are looking for!
- Validation of the solution
- Save data to a file in the format required by Google
#This is why this challenge help you to improve coding skills
- Reading data from files
- Writing data to files
- Structures and data containers
- Most used utility functions to manage your data for the programming language you are using (e.g., for C++, it is important to study STL functions … )
#The Simulated Annealing algorithm
#Choice of the algorithm
A good algorithm should allow to solve the “More pizza” problem as any other combinatorial problem proposed by Google (remember, your goal is to pass at least the Qualification Round!).
A good algorithm should allow to explore the space of solutions, in a good way.
For these reasons, I decided to use a Simulated Annealing algorithm. The optimization algorithm is based on a Physical Annealing analogy, where a solid is heated until particles are randomly arranged in a liquid state, followed by slow cooling. At each temperature, enough time is spent for the solid to reach thermal equilibrium, where energy levels follow Boltzmann distribution. As temperature decreases, the probability tends to concentrate on low energy states. Care must be taken to reach thermal equilibrium prior to decreasing the temperature.
#The main challenge
For each solution, generally there is always an associated score.
Two solutions are equivalent if they provide the same score.
The exploration of the space of solution is not an easy task.
In the “More pizza” problem, you can imagine that there are many combinations of pizza orders providing the same score. For this reason, it is possible that passing from one solution to another having higher score is not easily achievable. If the algorithm is not properly designed, the exploration might stop in a local trap and a suboptimal score is provided.
In addition, it is possible that, when exploring a set of equivalent solutions, the algorithm returns to a previous analyzed solution. If this occurs, the algorithm is trapped in a loop.
Therefore, it should be possible to jump from any solution to a new one to get a better score, even if there are too many equivalent solutions.
Sometimes, to avoid being trapped in certain regions of the space solutions corresponding to sub-optimal solutions, long jumps are required.
The ability to intensify the search process in proximity of a given solution is generally called exploitation.
#Representation of the solution
#The flowchart

#The algorithm
- each index is unique
- the total amount of slices of the solution does not exceed the given maximum value
Long jumps can be achieved swapping more than one index at a time.
A Simulated Annealing algorithm has an important feature: it allows to jump from a solution to another one with a better score passing through solutions with a lower score in a certain amount of steps.
- The initial temperature T0
- The math formula used to update the temperature
- The probability of acceptance
The probability of acceptance is the probability to accept a solution having a score lower than the best score. This best temporary solution will be used to generate new “neighbors”, i.e. new solutions that are close to the original one. The probability of acceptance should be calculated at each iteration since it depends on the current temperature value.
where deltaScore = BestTmpScore – TmpScore and T is the current temperature value. The value deltaScore is expected to be greater or equal than zero when this probability is being calculated.
#Save always best solutions
#A further stopping condition
#Time required to implement this algorithm
#Finally, what about the implemented code?
You can find the C++ code of the algorithm described in this post here: Simulated annealing - C++ implementation
