Change Making

This page details the cDMN implementation of the Change Making challenge, as listed on https://dmcommunity.org/challenge/challenge-feb-2015/. The challenge is as follows:

Change Making

Let S be a given sum that we want to achieve with a minimal amount of coins in denominations of x1, x2, …, xn. Here is a simple example: S is 123 cents, n is 4, x1 is 1 cent, x2 is 10 cents, x3 is 25 cents and xn is 100 cents.

This is a pretty cool example, as it shows the mathematical power of the cDMN solver. It is also a great example to show how cDMN is able to optimize values.

We start by making the glossaries. For this example, we do not need to introduce any types: all variables represent integer numbers, so we can rely on the built-in Int instead.

To represent the number of coins, we will use a constant for each denomination. We will also use a constant to keep track of the total amount of coins, and the total amount of money.

Constant
Name Type
TotalMoney Int
TotalCoins Int
OneCent Int
TwoCent Int
FiveCent Int
TenCent Int
TwentyCent Int
FiftyCent Int
OneEuro Int
TwoEuro Int

Now that our glossary is finished, we can move on to the decision tables. We will be creating three tables which consist exclusively of output columns.

The first one is the total amount of money which we want to find the optimal assignment for. This is easily represented as:

Total
U TotalMoney
1 123

Next up, we want a way to represent the following formula: TotalMoney = OneCent * 1 + TwoCent * 2 + .... Using a decision table with the C+ hit policy, we can model this as:

Change
C+ TotalMoney
1 OneCent * 1
2 TwoCent * 2
3 FiveCent * 5
4 TenCent * 10
5 TwentyCent * 20
6 FiftyCent * 50
7 OneEuro * 100
8 TwoEuro * 200

Similarly, to count the amount of total coins:

Coins
C+ TotalCoins
1 OneCent
2 TwoCent
3 FiveCent
4 TenCent
5 TwentyCent
6 FiftyCent
7 OneEuro
8 TwoEuro

If we were to run the current implementation, we would encounter something very curious: the solver would be able to find a solution in which exactly one coin is used. Indeed, we have not yet specified that our number of coins must always be positive, so the solver can e.g. find solutions with -3 TwoCent coins. To overcome this, we add a constraint table as follows:

Coins
C+ TotalCoins OneCent TwoCent FiveCent TenCent TwentyCent FiftyCent OneEuro TwoEuro
1 ≥ 0 ≥ 0 ≥ 0 ≥ 0 ≥ 0 ≥ 0 ≥ 0 ≥ 0 ≥ 0

Now all that is left to do, is specify what we want to do with this model. There are multiple solutions possible, but we want the solution with the optimal amount of coins By creating a Goal table, we can tell the system to optimize the TotalCoins constant.

Goal
Minimize TotalCoins

And that’s it! With just 2 glossary tables, 3 decision tables and a Goal table, we were able to model an optimal change making algorithm. If we run this in the cDMN solver, we get the following output:

Model 1
==========
TotalMoney := 123.
TotalCoins := 4.
OneCent := 1.
TwoCent := 1.
FiveCent := 0.
TenCent := 0.
TwentyCent := 1.
FiftyCent := 0.
OneEuro := 1.
TwoEuro := 0.

Elapsed Time:
1.106

If we want to look for the optimal way to form 567 cents, the cDMN solver outputs the following:

Model 1
==========
TotalMoney := 567.
TotalCoins := 7.
OneCent := 0.
TwoCent := 1.
FiveCent := 1.
TenCent := 1.
TwentyCent := 0.
FiftyCent := 1.
OneEuro := 1.
TwoEuro := 2.

Elapsed Time:
1.121