- It is
*simple*, i.e., doesn't cross itself. - Any line intersecting the polygon crosses the boundary at most twice.

A *chord* is a line segment connecting any two vertices. A *chord*
splits the polygon into two smaller polygons. Note that a chord always
divides a convex polygon into two convex polygons.

A *triangulation* of a polygon can be thought of as a set of chords
that divide the polygon into triangles such that no two chords intersect
(except possibly at a vertex). This is a triangulation of the
same polygon:

cost (<(where |v_{i},v_{j},v_{k}>) = |v_{i},v_{j}| + |v_{j},v_{k}| + |v_{i},v_{k}|

We would like to find, given a convex polygon and cost function over its vertices, the cost of an optimal triangulation of it. We would also like to get the structure of the triangulation itself as a list of triples of vertices.

This problem has a nice recursive substructure, a prerequisite for a dynamic programming algorithm. The idea is to divide the polygon into three parts: a single triangle, the sub-polygon to the left, and the sub-polygon to the right. We try all possible divisions like this until we find the one that minimizes the cost of the triangle plus the cost of the triangulation of the two sub-polygons. Where do we get the cost of triangulation of the two sub-polygons? Recursively, of course! The base case of the recursion is a line segment (i.e., a polygon with zero area), which has cost 0.

Let's define a function based on this intuitive notion. Let
*t*(*i*, *j*) be the cost of an optimal triangulation
of the polygon
<*v*_{i-1},
*v*_{i},
*v*_{i+1},
... , *v*_{j}>. So

*t*(*i*, *j*) =

0, ifWhat's that say in English? If we just have a line segment, that is, we're just looking at the "polygon" <i=j

min_{i<=k<=j-1}{ t(i,k) + t(k+1,j) + cost (<v_{i-1},v_{k},v_{j}>)} if i < j

More English, please? We just look at all possible triangles and leftover smaller polygons and pick the configuration that minimizes the cost.

We could write a recursive function in pseudocode right now, but it would be
pretty inefficient. How inefficient? Well, remember the inefficient
Fibonacci recursive function that took exponential time? It did only
two recursive calls per invokation. This one does up to *n* recursive
calls per invokation. This is a lot worse. There's no simple analysis,
but since all possible triangulations will be explored by this method,
a lower bound is same as the one given for an isomorphic problem in
your book, about
(4^{n} / *n*^{3/2}). Yikes.

This situation is perfectly suited for dynamic programming. There are
many redundant computations done. Each time we find a value for
*t*(*i*, *j*), we can just stick that value into
a two-dimensional array and never have to compute it again.

Here is the
algorithm to compute the value of an optimal triangulation of a
polygon given as an array *V*[0..*n*] of vertices. The array
*memo_t* is an *n* by *n* array of real numbers
initialized to -1. We must be careful to do arithmetic on vertex indices
modulo *n*+1, to avoid going outside the array:

Triangulate (V) weight = t (1, n) print "the weight is" weight t (i, j) if i == j then return 0 if memo_t[i][j] != -1 then return memo_t[i][j] min = infinity for k in i..j-1 do x = t (i, k) + t (k+1 (mod n+1), j) + cost (<v[i-1 (mod n+1)], v[k], v[j]>) if x < min then min = x end for memo_t[i][j] = min return min

This takes (*n*^{2})
storage because of the big array, and
(*n*^{3})
time since we have a function that does *n* things on *n*^{2}
array elements.

But this only tells us the *value* of an optimal solution? How do
we find the structure, i.e., a list of triangles we can draw to actually
triangulate the polygon? We can modify the *memo_t* array to be
an array of pairs (*c*, *k*) where *c* is the
minimum cost and *k* is the index of the vertex where the
minimum cost was found. Then change the `if` statement above to:

if x < min then min = x mink = k end ifand the

memo_t[i][j].c = min memo_t[i][j].k = minkOnce we find the optimal cost, we have a history recorded in the array of a best vertex to do the recursive triangulations at each step. ("A" best, not "the" best, since there could have been two equally optimal vertices at any step.) We can print the list of triangles as triples of vertex indices using another recursive algorithm:

Print-Triangulation (i, j) if i != j then print i-1 (mod n+1), memo_t[i][j].k, j Print-Triangulation (i, memo_t[i][j].k) Print-Triangulation (memo_t[i][j].k+1 (mod n+1), j) end ifThen listing the triangles is just a call to