.. _inside_outside_problem: Inside Outside Problem ---------------------- A new month, a new `DMCommunity challenge `_! In this month's challenge, we are tasked with optimizing a production process: .. admonition:: Inside Outside Problem You need to help a manufacturer decide how much of each demanded product should be produced internally and how much should be sourced from outside. Whether a product is made inside or outside, it has an associated cost. A product can consume a given amount of internal resources that have limited capacities. The general objective is to minimize the total production cost while ensuring the company meets the demand exactly or with a certain tolerance. The manufacturer wants to consider various production decisions to choose the most suitable ones based on the long-term resource availability and uncertain future demand. Here are examples of the data: Seems like a fun optimization problem, which we can easily model in cDMN. However, the description also stresses that the manufacturer wants to consider multiple decisions. To meet this requirement, we will first model the problem as-is, and then we'll add some additional options which allow a user to tweak the optimization. Let's begin with the cDMN glossary to declare the symbols of our problem domain. As per usual, we start with the types, i.e., domains of elements. In this case, this means declaring the various products and resources. .. raw:: html
Type
Name Type Values
ProductstringP1, P2, P3
ResourcestringR1, R2, R3

Next, we'll introduce our function symbols. These can be seen as a mapping from one or more types to another type. For instance, the first function (`demand of Product`) will map each Product on an Integer type. Similarly, we declare the costs of the product, the capacity of the resources, the number of resources required for each product, the number of product produced in-/outside, and finally, the total usage of each resource. .. raw:: html
Function
Name Type
demand of ProductInt
inside cost of ProductInt
outside cost of ProductInt
capacity of ResourceInt
nb Resource required for ProductInt
nb Product produced insideInt
nb Product produced outsideInt
usage of ResourceInt

Finally, we finish off our glossary by introducing a constant which we'll use to keep track of the total production costs (our minimization target). .. raw:: html
Constant
Name Type
total costInt
Now that all symbols are declared, we can (a) define those we already know using data tables, and (b) express rules and constraints over them. Let's start with the first task, and declare our data tables. .. raw:: html
Product data
D Product demand of Product inside cost of Product outside cost of Product
1 P1 250 6 8
2 P2 300 8 9
3 P3 200 3 4

Resource data
D Resource capacity of Resource
1 R1 1200
2 R2 800
3 R3 700

Resource data
D Resource Product nb Resource required for Product
1 R1 P1 5
2 R2 P1 2
3 R3 P1 0
4 R1 P2 4
5 R2 P2 4
6 R3 P2 0
7 R1 P3 3
8 R2 P3 0
9 R3 P3 6

These tables define some product data (demand and costs), the demand of the resources, and the number of resources required to make a product. With our data tables finish, we can go into the rules and constraints. The first one's pretty simple: our total production (internal + external) should meet the total demand for each product. Here, we use a constraint table (`E*`) to ensure these values match. The table reads "For each product must hold that the demand of the product is equal to its number produced inside + its number produced outside". (Note: the last two columns express that a product cannot have a non-negative production.) .. raw:: html
Meet demand
E* Product demand of Product nb Product produced inside nb Product produced outside
1 - nb Product produced inside + nb Product produced outside ≥ 0 ≥ 0

Next, we should calculate the total cost. Again, pretty straightforward. In this case, we use a count (`C+`) table: "The total cost is calculated as the sum of each product's internal production * internal cost plus external production * external cost". .. raw:: html
Calculate total cost
C+ Product total cost
1 - (nb Product produced insides * inside cost of Product) + (nb Product produced outside * outside cost of Product)

We calculate the usage of each resource in a similar manner, by multiplying the internal production by the required resources. .. raw:: html
Calculate capacity
C+ Resource Product usage of Resource
1 - - nb Product produced inside * nb Resource required for Product

Using this total usage, we can now introduce a new constraint table (`E*`) to explicitly prevent exceeding the capacity of a resource. .. raw:: html
Don't exceed capacity
E* Resource usage of Resource
1 - ≤ capacity of Resource

This already concludes our first model, in three data tables and four simple decision/constraint tables. :-) We can now have the cDMN solver optimize the cost, giving us the following result: .. code:: bash Model 1 ========== nb_Product_produced_inside := {P1 -> 240, P2 -> 0, P3 -> 0}. nb_Product_produced_outside := {P1 -> 10, P2 -> 300, P3 -> 200}. usage_of_Resource := {R1 -> 1200, R2 -> 480, R3 -> 0}. total_cost := 5020. Elapsed time: 0.035s I.e., producing 240 of P1 internally and all the rest externally will give us an optimal cost of 5020. This is not really surprising, as P1 benefits the most cost-wise from inside production. However, it does use up *all* of R1, and uses no R3. With possible "uncertain futures" in mind, fully using up an internal resource seems unwise. Similarly, fully relying on external production for P2 and P3 is likely not preferred either. To fix this, let's extend our model with the following: 1. A way to set the max% of resource usage 2. A minimal internal production percentage (i.e., at least 10% of each product should be produced internally) 3. A maximal external production percentage (i.e., at most 80% of each product may be produced externally) First, we need to update our glossaries with some new symbols. In this case, we luckily only need to update our constants to add these new variables: .. raw:: html
Constant
Name Type
total costInt
capacity percentage marginReal
max percent externalReal
min percent internalReal

Our resource usage constraint now requires updating. Instead of blankly stating the usage may not exceed the capacity, we need to include the capacity percentage margin. .. raw:: html
Don't exceed capacity
E* Resource usage of Resource
1 - ≤ capacity of Resource * (capacity percentage margin /100)

For the last modification, we add a new constraint table to state our min/max production constraints: .. raw:: html
Extra product constraints
E* Product nb Product produced inside nb Product produced outside
1 - > (min percent internal/100) * demand of Product < (max percent external/100) * demand of Product

And that's it! Using a new D-table, our production engineer can now set the values for these configuration variables, and find the best solution. Or, even better, they can use our `interactive online environment `_ to quickly try out different values and see the results. If you want to do so yourself, click on the link, and then click on "Interactive Consultant" at the top. Playing around in this environment gives us the following three solutions for some input values of capacity and min/max in-/external: +---------------------+--------------+--------------+--------------+ | Capacity Percentage | Max External | Max Internal | Optimal Cost | +=====================+==============+==============+==============+ | 100 | 80 | 10 | 5065 | +---------------------+--------------+--------------+--------------+ | 80 | 80 | 10 | 5161 | +---------------------+--------------+--------------+--------------+ | 100 | 90 | 35 | 5098 | +---------------------+--------------+--------------+--------------+ The following screenshots show the full solutions in our online environment. (Note: input in white = user input, grey = derived by system after minimizing total cost) .. image:: ../_static/io_problem1.png :width: 600 :alt: screenshot of the IC tool with the cDMN model preloaded .. image:: ../_static/io_problem2.png :width: 600 :alt: screenshot of the IC tool with the cDMN model preloaded .. image:: ../_static/io_problem3.png :width: 600 :alt: screenshot of the IC tool with the cDMN model preloaded