www.pudn.com > geosteiner-3.1.zip > bmst.c
/***********************************************************************
File: bmst.c
Rev: b-1
Date: 02/28/2001
Copyright (c) 1997, 2001 by David M. Warme & Martin Zachariasen
************************************************************************
Routines to compute Minimum Spanning Trees using the
Bottleneck Steiner Distance.
************************************************************************
Modification Log:
a-1: 09/04/97 warme
: Created.
b-1: 02/28/2001 martinz
: Added new procedures "bmst" and "bmst_terms" that
: return the edges of the MST (instead of only the
: length)
************************************************************************/
#include "bsd.h"
#include "steiner.h"
/*
* Global Routines
*/
dist_t bmst_length (struct pset *, struct bsd *);
int bmst (struct pset *, struct bsd *, struct edge *);
dist_t bmst_terms_length (int *, int, struct bsd *);
int bmst_terms (int *, int, struct bsd *, struct edge *);
/*
* External References
*/
/* none */
/*
* This routine computes the length of a Minimum Spanning Tree for
* the given point set as measured using the Bottleneck Steiner Distance.
*/
dist_t
bmst_length (
struct pset * pts, /* IN - point set */
struct bsd * bsdp /* IN - BSD data structure */
)
{
int i;
int nedges;
struct edge * ep;
struct edge * edges;
dist_t total;
edges = NEWA (pts -> n - 1, struct edge);
nedges = bmst (pts, bsdp, &edges [0]);
if (nedges NE pts -> n - 1) {
fatal ("bmst_length: bug 1.");
}
total = 0;
ep = edges;
for (i = 0; i < nedges; i++, ep++) {
total += ep -> len;
}
free ((char *) edges);
return (total);
}
/*
* This routine computes a Minimum Spanning Tree for
* the given point set as measured using the Bottleneck Steiner Distance.
*/
int
bmst (
struct pset * pts, /* IN - point set */
struct bsd * bsdp, /* IN - BSD data structure */
struct edge * edges /* OUT - edge list */
)
{
int i;
int j;
int n;
int nedges;
int mst_edge_count;
struct point * p1;
struct point * p2;
struct edge * ep;
struct edge * edge_array;
n = pts -> n;
nedges = (n * (n - 1)) >> 1;
edge_array = NEWA (nedges, struct edge);
ep = edge_array;
p1 = &(pts -> a [0]);
for (i = 0; i < n; i++, p1++) {
p2 = p1 + 1;
for (j = i + 1; j < n; j++, p2++) {
ep -> len = bsd (bsdp, p1 -> pnum, p2 -> pnum);
ep -> p1 = ((pnum_t) i);
ep -> p2 = ((pnum_t) j);
++ep;
}
}
mst_edge_count = mst_edge_list (n, nedges, &edge_array [0], edges);
free ((char *) edge_array);
return (mst_edge_count);
}
/*
* This routine computes the length of a Minimum Spanning Tree for
* the given list of terminals as measured using the
* Bottleneck Steiner Distance.
*/
dist_t
bmst_terms_length (
int * terms, /* IN - array of terminal numbers */
int n, /* IN - number of terminals */
struct bsd * bsdp /* IN - BSD data structure */
)
{
int i;
int nedges;
struct edge * ep;
struct edge * edges;
dist_t total;
edges = NEWA (n - 1, struct edge);
nedges = bmst_terms (terms, n, bsdp, edges);
if (nedges NE n - 1) {
fatal ("bmst_terms_length: bug 1.");
}
total = 0;
ep = edges;
for (i = 0; i < nedges; i++, ep++) {
total += ep -> len;
}
free ((char *) edges);
return (total);
}
/*
* This routine computes a Minimum Spanning Tree for
* the given list of terminals as measured using the
* Bottleneck Steiner Distance.
*/
int
bmst_terms (
int * terms, /* IN - array of terminal numbers */
int n, /* IN - number of terminals */
struct bsd * bsdp, /* IN - BSD data structure */
struct edge * edges /* OUT - edge list */
)
{
int i;
int j;
int t;
int nedges;
int mst_edge_count;
int * ip;
int * jp;
struct edge * ep;
struct edge * edge_array;
nedges = (n * (n - 1)) >> 1;
edge_array = NEWA (nedges, struct edge);
ep = edge_array;
ip = &terms [0];
for (i = 0; i < n; i++, ip++) {
t = *ip;
jp = ip + 1;
for (j = i + 1; j < n; j++, jp++) {
ep -> len = bsd (bsdp, t, *jp);
ep -> p1 = ((pnum_t) i);
ep -> p2 = ((pnum_t) j);
++ep;
}
}
mst_edge_count = mst_edge_list (n, nedges, &edge_array [0], edges);
free ((char *) edge_array);
return (mst_edge_count);
}