⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 greedy.c

📁 生成直角Steiner树的程序包
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************	File:	greedy.c	Rev:	a-1	Date:	01/31/2000	Copyright (c) 2000, 2001 by Martin Zachariasen************************************************************************	Implementation of greedy O(n^2) heuristic for	computing Euclidean Steiner trees	(Algorithmica 25, 418-437, 1999)************************************************************************	Modification Log:	a-1:	01/31/2000	martinz		: Created.  Derived from SLL heuristic************************************************************************/#include "bsd.h"#include "dsuf.h"#include "efuncs.h"#include "steiner.h"#define ANSI_DECLARATORS#define REAL coord_t#include "triangle.h"/* * Global Routines */dist_t		greedy_heuristic (struct pset *, struct bsd *);/* * Local Types */struct greedy_edge {	dist_t		len;	dist_t		bsd;	pnum_t		p1;	pnum_t		p2;	bool		mst;};struct greedy_fst {	dist_t		len;	/* Length of FST */	dist_t		ratio;	/* Ratio of length to length of MST spanning FST-terms */	int		count;	/* Number of terminals */	pnum_t		p [4];	/* List of terminals */	bool		chosen; /* Is this FST chosen by the algorithm? */};/* * Local Routines */static void		add_fst (struct pset *		pts,				 int *			terms,				 int			term_count,				 struct greedy_fst *	greedy_fsts,				 int *			fst_count,				 dist_t			mst_l,				 bool			mst_connected);static int		comp_edges (const void *, const void *);static int		comp_fsts  (const void *, const void *);static dist_t		fst_length (struct pset *, int *, int);static dist_t		mst_length (struct pset *, int *, int);/* * Local Variables */static struct greedy_edge *	greedy_edges;static struct greedy_fst  *	greedy_fsts;/* * Compute the length of a shortest full Steiner tree * for a set of terminals with up to 4 terminals. *  Special fast version which only computes length. * Returns 0.0 if no Steiner tree exists. * Assume terminals are ordered as they appear on Steiner polygon. */	static	dist_tfst_length (struct pset *		pts,		/* IN - terminal list */int *			terms,		/* IN - indices of terminals to consider */int			term_count	/* IN - number of terminals */){int			i;struct point *		a;struct point *		b;struct point *		c;struct point *		d;struct point		e, ctr, e_ad, e_cb;dist_t			l;dist_t			min_length;	if (term_count EQ 2) {		return (EDIST (&(pts -> a [terms [0]]),			       &(pts -> a [terms [1]])));	}	if (term_count EQ 3) {		a = &(pts -> a [terms [0]]);		b = &(pts -> a [terms [1]]);		c = &(pts -> a [terms [2]]);		eq_point (a, b, &e);		eq_circle_center (a, b, &e, &ctr);		if (right_turn (&e, a, c) AND		    left_turn (&e, b, c) AND		    (sqr_dist (&ctr, c) > sqr_dist (&ctr, a))) {			return EDIST (&e, c);		}	}	if (term_count EQ 4) {		min_length = INF_DISTANCE;		for (i = 0; i <= 1; i++) {			/* Using Lemma 5.2 p. 64 in Hwang, Richards, Winter */			a = &(pts -> a [terms [i]]);			d = &(pts -> a [terms [i+1]]);			c = &(pts -> a [terms [i+2]]);			b = &(pts -> a [terms [(i+3) % 4]]);			/* Find intersetion point between ac and bd.			   It is the same in both iterations */			if ((i EQ 0) AND			    NOT segment_intersection (a, c, b, d, &ctr)) break;			eq_point (a, d, &e_ad);			eq_point (c, b, &e_cb);			if (NOT wedge120 (d, a, &e_cb) AND			    NOT wedge120 (&e_cb, d, a) AND			    NOT wedge120 (&e_ad, b, c) AND			    NOT wedge120 (b, c, &e_ad) AND			    NOT wedge120 (a, &ctr, d)) {				l = EDIST (&e_ad, &e_cb);				if (l < min_length) {					min_length = l;				}			}		}		if (min_length < INF_DISTANCE) return (min_length);	}	return (0.0);}/* * Compute the length of a MST for a set of terminals. * Simply call general procedure (which might not be * the most effective to thing to do) */	static	dist_tmst_length (struct pset *		pts,		/* IN - terminal list */int *			terms,		/* IN - indices of terminals to consider */int			term_count	/* IN - number of terminals */){int			t;struct pset *		tpts;dist_t			mst_l;	tpts = NEW_PSET (term_count);	tpts -> n = term_count;	for (t = 0; t < term_count; t++) {		tpts -> a[t] = pts -> a[terms[t]];	}	mst_l  = euclidean_mst_length(tpts);	free (tpts);	return mst_l;}/* * For sorting edges by length (should be changed!!) */	static	intcomp_edges (const void *		p1,const void *		p2){dist_t			l1;dist_t			l2;	l1 = greedy_edges [ *(int*) p1].len;	l2 = greedy_edges [ *(int*) p2].len;	if (l1 < l2) return (-1);	if (l1 > l2) return (1);	return (0);}/* * For sorting FSTs by ratio (should be changed!!) */	static	intcomp_fsts (const void *		p1,const void *		p2){dist_t			l1;dist_t			l2;	l1 = greedy_fsts [ *(int*) p1].ratio;	l2 = greedy_fsts [ *(int*) p2].ratio;	if (l1 < l2) return (-1);	if (l1 > l2) return (1);	return (0);}/* * Add generated FST to list of FSTs */	static	voidadd_fst (struct pset *	pts,		/* IN - terminal list */int *		terms,		/* IN - indices of terminals in FST */int		term_count,	/* IN - number of terminals */struct greedy_fst * greedy_fsts,/* IN/OUT - list of FSTs */int *		fst_count,	/* IN/OUT - current FST count */dist_t		mst_l,		/* Length of MST spanning FST-terms */bool		mst_connected	/* Is induced subgraph of MST connected? */){int		j;dist_t		smt_l;dist_t		ratio;	smt_l = fst_length (pts, terms, term_count);	if (smt_l > 0) {		ratio = smt_l / mst_l;		if (ratio < 1.0) {			for (j = 0; j < 4; j++) {				greedy_fsts [*fst_count].p [j] = terms [j];			}			greedy_fsts [*fst_count].len	= smt_l;			greedy_fsts [*fst_count].ratio	= ratio;			greedy_fsts [*fst_count].count	= term_count;			greedy_fsts [*fst_count].chosen = mst_connected;			++(*fst_count);		}	}}/* * Greedy heuristic by Zachariasen and Winter */	dist_tgreedy_heuristic (struct pset *	ptss,	/* IN - terminals list for which				heuristic tree should be constructed */struct bsd *	bsdp	/* IN - BSD data structure */){int			i, j, k, jj, ei, fi, fk;int			ni, nj, nt, np1, np2, p1, p2, p4;int			fst_count, mst_count1, mst_count2;int			neighbour_edge, neighbour_edge_idx;int			term_count;int			root [4];int			terms [4];int *			triangleedges;int *			sortededges;int *			sortedfsts;bool *			new_chosen;bool			convex_region;bool			in_same_block;dist_t			mst_l, mst_l1, total_mst_l;dist_t			total_smt_l, best_smt_l, l[5], mx, my;struct point		minp, maxp;struct dsuf		mstsets, fstsets;struct triangulateio	in, out, vorout;struct pset *		pts;	/* Special cases */	if (ptss -> n <= 1) return (0.0);	if (ptss -> n EQ 2) return (EDIST (&(ptss -> a [0]),					   &(ptss -> a [1])));	/* Compute mean of all terminals and translate in order */	/* to improve the precision of computed eq-points.	*/	mx = 0.0;	my = 0.0;	for (i = 0; i < ptss -> n; i++) {		mx += ptss -> a[i].x;		my += ptss -> a[i].y;	}	mx = floor(mx / ((dist_t) ptss -> n));	my = floor(my / ((dist_t) ptss -> n));	/* Transfer to triangulate data structure and call triangle */	in.numberofpoints = ptss -> n;	in.pointlist = NEWA (2*in.numberofpoints, REAL);	pts = NEW_PSET(ptss -> n);	pts -> n = ptss -> n;	for (i = 0; i < pts -> n; i++) {		pts -> a[i].x	 = ptss -> a[i].x - mx;		pts -> a[i].y	 = ptss -> a[i].y - my;		pts -> a[i].pnum = ptss -> a[i].pnum;		in.pointlist [2*i  ] = pts -> a [i].x;		in.pointlist [2*i+1] = pts -> a [i].y;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -