(Part one of N)

Motivation: Modelling Electricity Generation

A few years ago I worked on model of electricity generation dispatch for the Electricity Authority. Electricity dispatch is the problem of deciding, in any given time period, which stations should be generating power and how much.

As inputs, the dispatch model takes

The model’s output is a list of which stations should generate in the time period, and how much each station should generate.

In the New Zealand electricity market a dispatch model covering the whole country is run by the system operator every half hour and similar models are run in states and countries all over the world.

The EA use dispatch models for understanding how the electricity network will need to grow as electricity use grows, how market conditions are affecting the electricity price and how changes to regulations might change the market. As a result, before I started my work they had already developed several dispatch models, all slightly different. Any of them would have been almost exactly what I needed.

The difference between the new model I was working on and the ones the EA already had was that the new model was to solve the dispatch in each of several time periods. The EA’s existing models were designed to work for a single period. This feels like a pretty small change to make, and that it should be easy to re-use one of the existing models. Unfortunately, it’s far from easy.

There are programming languages that are designed for specifying and solving problems like the dispatch model. The languages have constructs to make it easy to express such models and so they tend to be the best tool for the job, but, as far as I can tell, none of them have good support for re-using models.

In this case, the closest I could get to re-using an existing model was making a copy of the model and then altering every single line of the model’s text. If that can be called re-use at all, it’s the worst kind.

This will become clearer if I illustrate it with an example, so let’s look at a simpler model than electricity dispatch.

The Burglar’s Knapsack

The knapsack model is typified as the problem a burglar has when deciding what to steal.

Our burglar has a sack of a fixed size and is considering stealing a number of items, each of which has a value and a size. Which items should the burglar steal so that they all fit in the sack, and so that what’s in the sack is as valuable as possible?

A knapsack can be written in the style of math modelling languages in three lines:

1   maximize(sum(i in ITEMS) take(i) * value(i))
2   sum(i in ITEMS) take(i) * size(i) <= CAPACITY
3   forall(i in ITEMS) take(i) is_binary

Now, suppose our burglar has a friend, and they have a sack each to fill. It sounds like an opportunity to re-use our single knapsack model, but it doesn’t work. Instead, a multiple knapsack model looks like this:

1   maximize(sum(s in SACKS, i in ITEMS) take(s, i) * value(i))
2   forall(s in SACKS) sum(i in ITEMS) take(s, i) * size(i) >= CAPACITY(s)
3   forall(s in SACKS, i in ITEMS) take(s, i) is_binary
4   forall(i in ITEMS) sum(s in SACKS) take(s, i) >= 1

The four-line model above contains three lines that mean the same as the three-line model.

The first three lines are where things go horribly wrong. Each of them says the same thing as the corresponding line in the first model, but as you can see from the differences I’ve highlighted, every line has been altered.

What’s wrong with this?

As a result of the small change in how we use our knapsack, the two models for the same thing are now completely different.

You can’t keep the two models in sync

If we find a bug in one of the models we’ll have to remember to fix it in both of them. It’s (hopefully) unlikely that we’ll find a bug in a three-line model, but at the scale of a dispatch model bugs are likely.

Even if we don’t find a bug, we might improve one of the models. When we do that, only one of the models will be improved. If we’re diligent, we can transfer the improvements over to the other models. To do that though, we’d need to look at the differences between the two models and separate them into:

This does not work. People aren’t that diligent. There comes a point at which we can’t untangle the differences.

The end result is a mess of slightly different models, some with bug fixes, some with improvements and some that are still used, but way out of date.

You can’t re-use the model without understanding all of it

To change the single knapsack model into the multiple knapsack model, I had to pick through it line-by-line to see where I needed to make changes. I had to make sure I understood what every line was doing, and how that needed to change. I had to be an expert in the single knapsack to make a multiple knapsack.

In the context of a small model, that sounds kind of reasonable, but it’s not.

We can’t all be experts in the inner workings of everything we use:

Usually, you do need to know a bit about the inputs and the outputs of something you use to use it effectively (it helps to know the difference between the left and right pedals). And it pays to be competent in the use of the thing, but demanding detailed knowledge of the internals is a step too far.

A step so far in the wrong direction that I have trouble expressing just how wrong it is. We rely on being able to use the work of others in everything we do. Building complex models of large systems requires being an expert in:

It would be a whole lot easier if all of that didn’t have to fit into one head.

What do re-usable models look like?

In the next few posts on this topic I’ll discuss methods for building re-usable mathematical models, and try to explain why it’s such a hard thing to do2.

  1. as it happens, I do have a PhD in thermodynamics, but it doesn’t make me a better driver.

  2. as much for my benefit as anyone else’s. Writing this down will help me think more clearly about it.