Don’t leave Money on the Table — Optimize
“Great presentation! Are you sure you’ve found the best solution for our business?”
These words, or questions of a similar nature, are heard time and time again in most meetings where simulation has been presented. Most of the time systems are so complex, that finding the “right solution” is easier said than done. To find the exact combination of conditions that will give you the ‘best’ possible system performance, you need to examine multiple scenarios. Every situation can require some modification of your simulation model. The sheer number of parameters and combinations can create thousands or even hundreds of thousands of possible experiments. You’re left facing an impractical task. And yet potential improvements are never realized due to a lack of time for experimentation.
With ProcessModel, the task just became a whole lot easier. ProcessModel has an optimizer that automates the process of creating, running and analyzing experiments. You give ProcessModel a goal or an objective, and the software will adjust the parameters of the model to meet that goal. For example, you set a goal of reaching the highest throughput with the minimum number of resources and the lowest WIP. ProcessModel runs experiments, changes the parameters, compares the output and shows you the best settings of parameters to achieve your goal…while you work on another project!
When to Use Process Optimization
When should I use optimization? Well, I run optimization when the number of choices exceeds the number of experiments I am willing to run to find the answer. For me, if the number of experiments will exceed 15, then I would setup an optimization. It only takes a few minutes set up and I can do other things while the computer is running experiments. In the case where there could be large numbers of experiments then I might let the optimizer run while I go to lunch or home for the night. When you return, the optimizer will have identified the best solution. It just doesn’t get any better than that!
How will I know how many experiments might be needed?
It depends on the number of factors and the number of choices for each of those factors. To figure out the number of experiments required, multiply number of possible options for one choice by the number of possible options of the next choice. For example if there are 3 job functions (factors) and each of the personnel in those job functions can vary by 5 (i.e. vary from 15 to 20) then the number of possibilities would be 125.
Think of it like this: you have 5 choices for the first factor. For each of those choices, there are 5 choices for the second factor, making 5 * 5 = 25. For each of those 25 combinations, there are 5 choices for the third factor, and so on. Thus, we get 125. It is easy to see how easily the number of experiments can get completely out of hand. If you have only 6 factors, with five choices each, then the number of experiments would be almost to 16,000! If two more factors are added then the number of possible experiments exceeds 390,000.
What about design of experiments?
Good question. First, in a complex system, design of experiments is used to limit the number of possible trials to save time and money. That means some experiments won’t be run because of an arbitrarily decision not to try those combinations. Rather than artificially eliminate possibilities, why not let the computer eliminate possible trials based on the response achieved? That is what simulation optimization does. It does a smart design of experiments, and evolves along the way. It is kind of like the selection process for the Tsetse fly. The weak ones die off and the strong ones mate and proliferate. In an optimization I performed, there were over 400,000 possible experiments. The optimization found a great solution after running 270 experiments! That’s intelligent automated design of experiments.
Second, design of experiments wasn’t really designed to handle a range of possibilities for each factor (i.e. 15 to 20). If a range of possibilities is used then the number of experiments grows dramatically. Now, we are back to analyzing large numbers of experiments to figure out which is best. This is a bad choice, because you still do the work to analyze the results. In a complex system this could mean hundreds of hours of pouring over data find the “best” result
How To Do Optimization – It’s really not that hard
- Prepare a validated model
- Insert scenario parameters
- Run the model — Launch SimRunner
- Set the goal of the optimization
- Select the parameters to adjust
- Plug optimization values into the model
Step 1 — Prepare a validated model
Since this article is not on validating models, I am not going to spend much time on validating and verifying your model. That being said, don’t optimize unless the model is validated. It is kind of like kissing the wrong girl. The outcome is uncertain and probability of failure is high.
Some of the simple things that you can do include:
- Watch the animation to determine that the model performs all intended functions.
- Make certain that the data going into the model is correct
- Test all distributions (see the Model Object Miscellaneous – verify distribution values)
- Export model data to Excel and check each time value, time units, capacities, queue sizes, move times, etc. I use a red pen to check-off each entry
- Compare the overall output to real data from company systems. This is one of the vital reasons for doing a model of the as-is system…you can gain confidence in the predictive capability of the model before making changes.
- Compare critical parts of the model with known or estimated data.
Step 2 – Insert Scenario Parameters into your Model
Now that you have a validated model to work with, create scenario parameters for each aspect of the model that you want to change. To help the learning process, we are going to use a very simple model to illustrate the steps used. The same procedure will apply to complex models.
In this simple model Items arrive every 20 minutes. The first process takes 1 hour to complete, while the second process takes 3 hours to complete. The goal of this model will be to Maximize Throughput with the Minimum Resources. You could easily calculate in your head that 3 workers would be needed at the first process, while 9 would be needed at the second process. Obviously, you wouldn’t do simulation on model that you already knew the answer for, but I think you will find this simple example illustrative and helpful to your understanding.
First, define the scenario parameters for the elements that will be changed in the model. Scenario parameters are like a control levers used to set the number of resources (or any other parameter you want to change). When used with the optimizer, they are automatically adjusted through a range that you specify.
The scenarios dialog is found on the simulation menu.
We will be adding a scenario parameter for each of the workers. I always start the scenario parameters with “s_” so that I can spot them in my model. I immediately know that parameter is for scenarios rather than an a variable or attribute.
I am defining 2 scenario parameters. One scenario parameter will be used for each resource type.
The Default Value acts as a starting point for the optimizer. Although we already know the answer, I am going to pretend that I don’t know the answer and set the default values to 2 and 8 respectively.
The scenario parameter then needs to be placed in the dialog where the adjustments will be made. Since quantity of resources will be changed, we will go to the resource dialog. Delete the contents of the quantity field and right-mouse-click in the same field. Use the key words selection to select the appropriate scenario parameter.
Since the Worker is assigned to the activity titled Process, we need to make certain that the capacity of the activity is large enough to handle the assigned workers. Without making the change to the Capacity of the Activity it is as if we have a lot of resources but no workspace for them to perform their tasks. To make this change, delete out the contents of the capacity field and right-mouse-click in the same field. Use the key words selection to select the appropriate scenario parameter.
Repeat the procedure for Worker2 and the activity where that resource is assigned.
Step 3 — Run the model and Launch SimRunner
With scenario parameters in place the model, run the model and save the output.
This important because when the output is saved it creates a “map” of the things that can be compared by the optimizer. This “map” will allow us to set a target for which the optimizer can then hunt.
Launch SimRunner from the tools menu.
Step 4 – Set the goal of the optimization
The objective function is an expression used to quantitatively evaluate a simulation model’s performance. In other words, you are going to create a target that SimRunner will aim for.
By measuring various performance characteristics and taking into consideration how you weigh them, SimRunner can measure how well your system operates. However, SimRunner knows only what you tell it via the objective function. For instance, if your objective function measures only one variable, Total_Throughput, SimRunner will attempt to optimize that variable. If you do not include an objective function term to tell it that you also want to minimize the total number of workers used, SimRunner will assume that you don’t care how many workers you use. Since the objective function can include multiple terms, be sure to include all of the response statistics about which you are concerned.
In our example we are going to maximize the items processed while minimizing the number of resources.
In the Response Category field, select Entity. The statistics for Entities that can be used in the objective are now shown the Response Statistic field. Double-click on the “Item – Qty Processed” to move it into the Objective Function (to make it part of the targeting formula). Weighting could be added to adjust the relative importance of each response statistic.
We are not going to be making changes to the weighting factors in this example, but a brief explanation will help to show how it will be used. Weights serve as a means of load balancing for statistics that might bias the objective function. Since most simulation models produce a variety of large and small values, it is often necessary to weight these values to ensure that the objective function does not unintentionally favor any particular statistic. For example, suppose that a run of your model returns a throughput of .72 and an average WIP of 4.56. If you maximize throughput and minimize WIP by applying the same weight to both (W1=W2), you will bias the objective function in favor of WIP:
Maximize[(W1)*(Throughput)] = .72
Minimize[(W2)*(WIP)] = 4.56
In this case, since you want to ensure that both statistics carry equal weight in the objective function, you will apply a weight of 6.33 (W1=6.33) to throughput and 1.0(W2=1.0) to WIP to make them of equal weight in the objective function.
Maximize[(W1)*(Throughput)] = 4.56
Minimize[(W2)*(WIP)] = 4.56
In situations where it is necessary to favor one statistic over another, balancing the statistics first will make it easier to control the amount of bias you apply. For example, if you apply a weight of 12.67 (W1=12.67) to throughput and 1.0 (W2=1.0) to WIP, the objective function will consider throughput to be twice as important as WIP
The other two statistics that need to be part of the Object Function are the number of resources. In the Response Category field, select Resource. Double-click on “Worker – Units” and “Worker2 – Units.” Both of these statistics need to be minimized. To minimize the number of Workers, click on the line in the objective function that needs modification. Select the Min (minimize) radio button and select the Update button, as show below.
Do the same for Worker2.
Step 5 – Select the parameters to adjust
Now that the “Target” has been identified, set the range for which scenario parameters are allowed to change. All Scenario Parameters defined in your model are displayed in SimRunner as Macros. In this article, macros will consistently be referred to as Scenario Parameters. SimRunner will use these Scenario Parameters to improve the value of your objective function.
The reason for setting the range is twofold: first, by limiting the range, the number of experiments is reduced allowing the targeting system to find a result faster; second, the system being optimized may have physical limitations that cannot be exceeded. An example physical limitation would be space constraints for the number of machines. The physical layout may restrict the number of machines to three. To allow the number of machines to vary from 1 to 5 would be useless unless building changes were going to be allowed as part of the project. In the more conservative case, the range of the changes would be restricted from 1 to 3.
Select the Define Inputs button and select the Scenario Parameter (Macros) to be adjusted in this optimization.
Select each Scenario Parameter in turn (in the Macros Selected as Input Factors field) and set a Lower Bound and Upper Bound then select the Update button.
Set the bounds as shown above.
There are a lot of capabilities that that won’t be covered in this tutorial. As a matter of fact the whole area dealing pre-analysis of the model to determine the warm-up length and number of replications will be covered in a future newsletter.
Step 6 – Optimize
With a few final settings the optimizer is ready to run. Select the Optimize button off of the top tool bar.
Optimization profile — SimRunner provides three optimization profiles: Aggressive, Moderate, and Cautious. The optimization profile is a reflection of the number of possible solutions SimRunner will examine. For example, the cautious profile tells SimRunner to consider the highest number of possible solutions—to cautiously and more thoroughly conduct its search for the optimum. As you move from aggressive to cautious, you will most often get better results because SimRunner examines more results—but not always. Depending on the difficulty of the problem you are trying to solve, you may get solutions that are equally good. If you are pressed for time or use relatively few input factors, a more aggressive approach—the aggressive profile—may be appropriate
Convergence percentage – With every experiment, SimRunner tracks the objective function’s value for each solution. By recording the best and the average results produced, SimRunner is able to monitor the progress of the algorithm. Once the best and the aver-age are at or near the same value, the results converge and the optimization stops. The convergence percentage controls how close the best and the average must be to each other before the optimization stops. A high percentage value will stop the search early, while a very small percentage value will run the optimization until the points converge.
What more is there to learn?
The remaining options are very straight forward, so I won’t spend time on those fields.
The next step is to hit the Optimize button and then the Run button.
SimRunner tries to maximize the objective function. It just so happens that this model found the best results on experiment number 1. That won’t happen often. We had a simple problem with a limited number of experiments and the algorithm guessed correctly. In this simple example is easy to see how the objective function was reached. The objective function was given 108 points (one for each entity that exited the model) and lost a point for each of the workers (minus 3 for Worker and 9 for Worker2), leaving the final objective function at 96. Note that experiment number 8 had the same number of Items processed, but lost one additional point because of having an additional worker.
Step 7 – Plug the Best Results into ProcessModel
The optimization should not be the final run of the model. Take the time to try the results in the simulation model, turn on the animation and watch the simulation run. This provides additional assurance that the model is working correctly with the new values. It also provides an opportunity to identify other areas for improvement not included in the objective function.
SimRunner intelligently and reliably seeks the optimal solution to your problem based on the feedback from your simulation model by applying some of the most advanced search techniques available today.
The SimRunner optimization method is based upon Evolutionary Algorithms. Evolutionary Algorithms are a class of direct search techniques based on concepts from the theory of evolution. The algorithms mimic the underlying evolutionary process in that entities adapt to their environment in order to survive. Evolutionary Algorithms manipulate a population of solutions to a problem in such a way that poor solutions fade away and good solutions continually evolve in their search for the optimum. Search techniques based on this concept have proven to be very robust and have solved a wide variety of difficult problems. They are extremely useful because they provide you with not only a single, optimized solution, but with many good alternatives.