예제 #1
0
int
main ()
{
    int i, data;
    int v_id[V_COUNT];
    DfsVertex *dfs_vs[V_COUNT];

    Graph graph;
    DfsVertex *dfs_vertex;
    List ordered;
    ListElmt *element;

    graph_init (&graph, &match, NULL);

    for (i = 0; i < V_COUNT; i++)
    {
        v_id[i] = i;
        if ((dfs_vertex = (DfsVertex *) malloc (sizeof(DfsVertex))) == NULL)
            return -1;
        dfs_vertex->data = &v_id[i];
        dfs_vertex->color = white;
        dfs_vs[i] = dfs_vertex;
        graph_ins_vertex (&graph, (void *) dfs_vertex);
        /* printf ("vertex[%d] addr=%d\n", i, (void *) &vertex[i]);  */
    }

    printf ("graph vcount=%d\n", graph_vcount (&graph));

    /* Graph as in figure 11.8 Network hops.  */
    /* graph_ins_edge (&graph, (void *) dfs_vs[0], (void *) dfs_vs[1]);  */
    graph_ins_edge (&graph, (void *) dfs_vs[0], (void *) dfs_vs[2]);
    graph_ins_edge (&graph, (void *) dfs_vs[2], (void *) dfs_vs[1]);
    graph_ins_edge (&graph, (void *) dfs_vs[1], (void *) dfs_vs[3]);
    /* graph_ins_edge (&graph, (void *) dfs_vs[2], (void *) dfs_vs[4]);  */
    graph_ins_edge (&graph, (void *) dfs_vs[3], (void *) dfs_vs[4]);
    graph_ins_edge (&graph, (void *) dfs_vs[4], (void *) dfs_vs[5]);
    graph_ins_edge (&graph, (void *) dfs_vs[1], (void *) dfs_vs[6]);

    printf ("graph ecount=%d\n", graph_ecount (&graph));

    dfs (&graph, &ordered);
    printf ("size of ordered list=%d\n", list_size (&ordered));

    for (element = list_head (&ordered); element != NULL;
         element = list_next (element))
    {
        dfs_vertex = (list_data (element));
        printf ("vertex id=%d,\tcolour=%d\n",
                *(int *) dfs_vertex->data,
                (int) dfs_vertex->color);
    }

    list_destroy (&ordered);
    graph_destroy (&graph);
    return 0;
}
예제 #2
0
int main(){
    Graph *graph;
    if((graph = (Graph *)malloc(sizeof(Graph))) == NULL) return -1;
    graph_init(graph, &match_string, &free);

    DfsVertex *cs100, *cs200, *ma100, *cs300, *ma300, *cs150;
    create_DfsVertex(cs100, "cs100", 5);
    create_DfsVertex(cs200, "cs200", 5);
    create_DfsVertex(ma100, "ma100", 5);
    create_DfsVertex(cs300, "cs300", 5);
    create_DfsVertex(ma300, "ma300", 5);
    create_DfsVertex(cs150, "cs150", 5);

    graph_ins_vertex(graph, cs100);
    //graph_ins_vertex(graph, cs200);
    //graph_ins_vertex(graph, ma100);
    //graph_ins_vertex(graph, cs300);
    //graph_ins_vertex(graph, ma300);
    //graph_ins_vertex(graph, cs150);

    printf("dfs.h\n");
}
/**
 * 测试最小生成树
 */
void test_mini_span_tree_from_graph() {
    Student s[] = {
            *studn_get_init(1, "a", 0, 22, 11),
            *studn_get_init(2, "b", 0, 22, 11),
            *studn_get_init(3, "c", 0, 22, 11),
            *studn_get_init(4, "d", 0, 22, 11),
            *studn_get_init(5, "e", 0, 22, 11),
            *studn_get_init(6, "f", 0, 22, 11),
    };

    MstVertex m[] = {
            /*0*/*mst_vertex_get_init((void *)(&s[0]), 0, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[1]), 0, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[2]), 0, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[3]), 0, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[4]), 0, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[5]), 0, (int (*)(const void *, const void *))studn_match, NULL),
            
            /*a点延伸出去的边的连接节点*/
            /*6*/*mst_vertex_get_init((void *)(&s[1]), 7, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[2]), 4, (int (*)(const void *, const void *))studn_match, NULL),
            
            /*b点延伸出去的边的连接节点*/
            /*8*/*mst_vertex_get_init((void *)(&s[0]), 7, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[2]), 6, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[3]), 2, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[5]), 4, (int (*)(const void *, const void *))studn_match, NULL),
            
            /*c点延伸出去的边的连接节点*/
            /*12*/*mst_vertex_get_init((void *)(&s[0]), 4, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[1]), 6, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[4]), 9, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[5]), 8, (int (*)(const void *, const void *))studn_match, NULL),
            
            /*d点延伸出去的边的连接节点*/
            /*16*/*mst_vertex_get_init((void *)(&s[1]), 2, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[5]), 7, (int (*)(const void *, const void *))studn_match, NULL),
            
            
            /*e点延伸出去的边的连接节点*/
            /*18*/*mst_vertex_get_init((void *)(&s[2]), 9, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[5]), 1, (int (*)(const void *, const void *))studn_match, NULL),
            
            /*f点延伸出去的边的连接节点*/
            /*20*/*mst_vertex_get_init((void *)(&s[1]), 4, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[2]), 8, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[3]), 7, (int (*)(const void *, const void *))studn_match, NULL),
            *mst_vertex_get_init((void *)(&s[4]), 1, (int (*)(const void *, const void *))studn_match, NULL),
    };

    Graph graph;
    graph_init(&graph, (int (*)(const void *, const void *))mst_vertex_match, NULL);
    int i;
    //插入所有的节点
    for (i = 0; i < 6; ++i) {
        graph_ins_vertex(&graph, &m[i]);
    }
    printf("%s\n", "insert vertex success");

    //插入所有的边
    graph_ins_edge(&graph, &m[0], &m[6]);
    graph_ins_edge(&graph, &m[0], &m[7]);

    graph_ins_edge(&graph, &m[1], &m[8]);
    graph_ins_edge(&graph, &m[1], &m[9]);
    graph_ins_edge(&graph, &m[1], &m[10]);
    graph_ins_edge(&graph, &m[1], &m[11]);

    graph_ins_edge(&graph, &m[2], &m[12]);
    graph_ins_edge(&graph, &m[2], &m[13]);
    graph_ins_edge(&graph, &m[2], &m[14]);
    graph_ins_edge(&graph, &m[2], &m[15]);

    graph_ins_edge(&graph, &m[3], &m[16]);
    graph_ins_edge(&graph, &m[3], &m[17]);

    graph_ins_edge(&graph, &m[4], &m[18]);
    graph_ins_edge(&graph, &m[4], &m[19]);

    graph_ins_edge(&graph, &m[5], &m[20]);
    graph_ins_edge(&graph, &m[5], &m[21]);
    graph_ins_edge(&graph, &m[5], &m[22]);
    graph_ins_edge(&graph, &m[5], &m[23]);

    List span;
    mst(&graph, m, &span, (int (*)(const void *, const void *))mst_vertex_match);
    list_resetIterator(&span);
    while (list_hasNext(&span)) {
        list_moveToNext(&span);
        MstVertex *vertex = NULL;
        list_iterator(&span, (void **)(&vertex));
        Student *s = (Student *)vertex->data;
        printf("key : %.0f", vertex->key);
        if (vertex->parent != NULL) {
            Student *sP = (Student *)(vertex->parent->data);
            printf(", parentid:%d, ",  sP->_id);
        }
        studn_print(s);
    }

    return;
}
예제 #4
0
int main(int argc, char **argv) {

	Graph graph;

	MstVertex *mst_start, *mst_vertex, mst_vertex1, *mst_vertex2;

	PathVertex *pth_start, *pth_vertex, pth_vertex1, *pth_vertex2;

	TspVertex *tsp_start, *tsp_vertex;

	List span, paths, vertices, tour;

	ListElmt *element;

	double distance, total, x, y;

	int i;

	/*****************************************************************************
	 *                                                                            *
	 *  Compute a minimum spanning tree.                                          *
	 *                                                                            *
	 *****************************************************************************/

	graph_init(&graph, match_mst, free);

	fprintf(stdout, "Computing a minimum spanning tree\n");

	for (i = 0; i < MSTVCT; i++) {

		if ((mst_vertex = (MstVertex *) malloc(sizeof(MstVertex))) == NULL)
			return 1;

		if (i == 0)
			mst_start = mst_vertex;

		mst_vertex->data = MstTestV[i];

		if (graph_ins_vertex(&graph, mst_vertex) != 0)
			return 1;

	}

	for (i = 0; i < MSTECT; i++) {

		if ((mst_vertex2 = (MstVertex *) malloc(sizeof(MstVertex))) == NULL)
			return 1;

		mst_vertex1.data = MstTestE[i].vertex1;
		mst_vertex2->data = MstTestE[i].vertex2;
		mst_vertex2->weight = MstTestE[i].weight;

		if (graph_ins_edge(&graph, &mst_vertex1, mst_vertex2) != 0)
			return 1;

	}

	print_graph_mst(&graph);

	if (mst(&graph, mst_start, &span, match_mst) != 0)
		return 1;

	for (element = list_head(&span); element != NULL;
			element = list_next(element)) {

		mst_vertex = list_data(element);

		fprintf(stdout, "vertex=%s, parent=%s\n", (char *) mst_vertex->data,
				mst_vertex->parent != NULL ?
						(char *) mst_vertex->parent->data : "*");

	}

	list_destroy(&span);
	graph_destroy(&graph);

	/*****************************************************************************
	 *                                                                            *
	 *  Compute shortest paths.                                                   *
	 *                                                                            *
	 *****************************************************************************/

	graph_init(&graph, match_pth, free);

	fprintf(stdout, "Computing shortest paths\n");

	for (i = 0; i < PTHVCT; i++) {

		if ((pth_vertex = (PathVertex *) malloc(sizeof(PathVertex))) == NULL)
			return 1;

		if (i == 0)
			pth_start = pth_vertex;

		pth_vertex->data = PthTestV[i];

		if (graph_ins_vertex(&graph, pth_vertex) != 0)
			return 1;

	}

	for (i = 0; i < PTHECT; i++) {

		if ((pth_vertex2 = (PathVertex *) malloc(sizeof(PathVertex))) == NULL)
			return 1;

		pth_vertex1.data = PthTestE[i].vertex1;
		pth_vertex2->data = PthTestE[i].vertex2;
		pth_vertex2->weight = PthTestE[i].weight;

		if (graph_ins_edge(&graph, &pth_vertex1, pth_vertex2) != 0)
			return 1;

	}

	print_graph_pth(&graph);

	if (shortest(&graph, pth_start, &paths, match_pth) != 0)
		return 1;

	for (element = list_head(&paths); element != NULL;
			element = list_next(element)) {

		pth_vertex = list_data(element);

		fprintf(stdout, "vertex=%s, parent=%s, d=%.1lf\n",
				(char *) pth_vertex->data,
				pth_vertex->parent != NULL ?
						(char *) pth_vertex->parent->data : "*", pth_vertex->d);

	}

	list_destroy(&paths);
	graph_destroy(&graph);

	/*****************************************************************************
	 *                                                                            *
	 *  Solve the traveling-salesman problem.                                     *
	 *                                                                            *
	 *****************************************************************************/

	/*list_init(&vertices, free);

	 fprintf(stdout, "Solving a traveling-salesman problem\n");

	 for (i = 0; i < TSPVCT; i++) {

	 if ((tsp_vertex = (TspVertex *)malloc(sizeof(TspVertex))) == NULL)
	 return 1;

	 if (i == 0)
	 tsp_start = tsp_vertex;

	 tsp_vertex->data = TspTestV[i].vertex;
	 tsp_vertex->x = TspTestV[i].x;
	 tsp_vertex->y = TspTestV[i].y;

	 if (list_ins_next(&vertices, list_tail(&vertices), tsp_vertex) != 0)
	 return 1;

	 }

	 print_list_tsp(&vertices);

	 if (tsp(&vertices, tsp_start, &tour, match_tsp) != 0)
	 return 1;

	 total = 0;

	 for (element = list_head(&tour); element != NULL; element =
	 list_next(element)) {

	 tsp_vertex = list_data(element);

	 if (!list_is_head(&tour, element)) {

	 distance = sqrt(pow(tsp_vertex->x-x, 2.0) + pow(tsp_vertex->y-y, 2.0));
	 total = total + distance;

	 }

	 x = tsp_vertex->x;
	 y = tsp_vertex->y;

	 if (!list_is_head(&tour, element)) {

	 fprintf(stdout, "vertex=%s, distance=%.2lf\n", (char *)tsp_vertex->
	 data, distance);

	 }

	 else
	 fprintf(stdout, "vertex=%s\n", (char *)tsp_vertex->data);

	 }

	 fprintf(stdout, "total=%.2lf\n", total);

	 list_destroy(&vertices);
	 list_destroy(&tour);*/

	return 0;

}
int main(int argc, char **argv)
{

	Graph graph;

	DfsVertex *task, task1, *task2;

	List list;

	ListElmt *element;

	char data1[STRSIZ];

	int i;

/*****************************************************************************
*  Initialize the graph.                                                     *
*****************************************************************************/

	graph_init(&graph, match_task, destroy_task);

/*****************************************************************************
*  Insert some tasks.                                                        *
*****************************************************************************/

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "a");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "b");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "c");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "d");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "e");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "f");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "g");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "h");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	if ((task = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task->data, "i");
	fprintf(stdout, "Inserting vertex %s\n", (char *)task->data);

	if (graph_ins_vertex(&graph, task) != 0)
		return 1;

	print_graph(&graph);

/*****************************************************************************
*  Insert some dependencies.                                                 *
*****************************************************************************/

	task1.data = data1;

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "a");
	strcpy((char *)task2->data, "b");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "a");
	strcpy((char *)task2->data, "c");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "b");
	strcpy((char *)task2->data, "i");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "c");
	strcpy((char *)task2->data, "i");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "e");
	strcpy((char *)task2->data, "f");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "e");
	strcpy((char *)task2->data, "h");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "f");
	strcpy((char *)task2->data, "c");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "f");
	strcpy((char *)task2->data, "h");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

	if ((task2 = (DfsVertex *) malloc(sizeof(DfsVertex))) == NULL)
		return 1;

	if ((task2->data = malloc(STRSIZ)) == NULL)
		return 1;

	strcpy((char *)task1.data, "g");
	strcpy((char *)task2->data, "h");
	fprintf(stdout, "Inserting edge %s to %s\n", (char *)task1.data,
		(char *)
		task2->data);

	if (graph_ins_edge(&graph, &task1, task2) != 0)
		return 1;

	print_graph(&graph);

/*****************************************************************************
*  Perform depth-first search.                                               *
*****************************************************************************/

	fprintf(stdout, "Generating the depth-first search listing\n");

	if (dfs(&graph, &list) != 0)
		return 1;

	i = 0;

	for (element = list_head(&list); element != NULL; element =
	     list_next(element)) {

		task = list_data(element);
		fprintf(stdout, "list[%03d]=%s (color=%d)\n", i,
			(char *)task->data, task->color);
		i++;

	}

/*****************************************************************************
*  Destroy the linked list.                                                  *
*****************************************************************************/

	fprintf(stdout, "Destroying the list\n");
	list_destroy(&list);

/*****************************************************************************
*  Destroy the graph.                                                        *
*****************************************************************************/

	fprintf(stdout, "Destroying the graph\n");
	graph_destroy(&graph);

	return 0;

}
예제 #6
0
int gridSteinerFH(Graph *grid_graph, AdjList**** Edge2Adj, int width, int height, CoordData *term, int no_terminals, double *L,int
	net_num, int *edge_count_OUT, int **SteinerTree_OUT, int l, int K) {
    int i,j;
	/* globals */
	
	int				GRID_WIDTH, GRID_HEIGHT, NO_TERMINALS;
	
	
	Graph			ND;					/* distance network of terminals */
	
	/*used to generate grid graph */
	PathVertex      *path_vertex;
	
	sPathData		*sPath_vertex;
	
	CoordData       *coord;
	
	/* used in shortest paths computations */
	PathVertex      **terminals;        /* a (1D) array of terminal (pointers) */
	List            *tempPaths,			/* tempporary */
					**sPaths;			/* 2d array of shortest path lists */
	ListElmt        *element;           /* temp, used to traverse a list */	
	
	/* used in computing MST of ND */
	MstVertex		*mst_start,
					*mst_vertex,
					*mst_vertex1,
					*mst_vertex2;
	List			TD;					/* spanning tree of ND */
										/* used in final steps of algorithm */
	
	Graph			NTD;				/* complete distance network */
	
	List			T;					/* spanning tree of NTD (eventually the steiner tree)*/
	int				isSteiner;			/* boolean flag */
	double			tree_cost;			/* total cost of the steiner tree (unused, this is computed after*/
	

			
	GRID_WIDTH = width;
	GRID_HEIGHT = height;
	NO_TERMINALS = no_terminals;
	
	mst_start = NULL;
	
	/*-----------------------------------------------*/
	/* If the number of terminals is two, then we    */
	/* only need to perform one call of Dijkstra to  */
	/* get the Steiner Tree                          */
	/*-----------------------------------------------*/
	if (NO_TERMINALS == 2) {
		PathVertex	*v1,*v2;	/* the two terminals*/
		CoordData	*c1,*c2;	/* coordinates of the two terminals*/
		List		P;			/* P-Array in Dijkstra's*/
		ListElmt	*e;			/* list counter*/
		List		T;			/* steiner tree*/
		double		tree_cost;
		int			j;
		int			first_edge,last_edge;
		
		PathVertex	*u;
			
		u = NULL;
	
		/* allocate vertices */
		v1 = (PathVertex*) malloc(sizeof(PathVertex));
		v2 = (PathVertex*) malloc(sizeof(PathVertex));
		c1 = (CoordData*) malloc(sizeof(CoordData));
		c2 = (CoordData*) malloc(sizeof(CoordData));		
		
		/* set terminal data */
		c1->x = term[0].x; 		c1->y = term[0].y;		c1->z = term[0].z;
		c2->x = term[1].x; 		c2->y = term[1].y;		c2->z = term[1].z;		
		v1->data = c1;
		v2->data = c2;
		
		/* compute shortest path from v1 */
		if (shortest(grid_graph, v1 , &P, match_coord,GRID_WIDTH,GRID_HEIGHT) != 0)
			return 1;

		/* initialize the tree */
		list_init(&T,NULL);
		
		/* find the end vertex (v2)*/
		for (e = list_head(&P); e != NULL; e = list_next(e)) 
			if ( match_coord(v2,list_data(e)))
				u = (PathVertex*)list_data(e);
		
		
		first_edge = 1;
		last_edge = 0;
		/* follow the end vertex back to the start vertex*/
		while (u->parent != NULL) {
			int			ux,uy,uz,upx,upy,upz;
			AdjList		*a;
			ListElmt	*ee;
			
			/*current vertex*/
			ux = ((CoordData*)((PathVertex*)u)->data)->x;
			uy = ((CoordData*)((PathVertex*)u)->data)->y;
			uz = ((CoordData*)((PathVertex*)u)->data)->z;
			
			/*connecting vertex (parent)*/
			upx = ((CoordData*)((PathVertex*)u->parent)->data)->x;
			upy = ((CoordData*)((PathVertex*)u->parent)->data)->y;
			upz = ((CoordData*)((PathVertex*)u->parent)->data)->z;
			
			
			/* get the index of the edge that connects (ux,uy,uz) and its parent*/
			a = Edge2Adj[ux][uy][uz];
			for (ee = list_head(&a->adjacent); ee != NULL; ee = list_next(ee)) {
				PathVertex	*v;
				int			*i;
				int			vx,vy,vz;
				
				v = (PathVertex*)list_data(ee);
				vx = ((CoordData*)v->data)->x;
				vy = ((CoordData*)v->data)->y;
				vz = ((CoordData*)v->data)->z;
				
				/* found it*/
				if (( vx == upx ) && ( vy == upy ) && ( vz == upz )) {
					
					/*don't insert if its a via*/
					if (first_edge) {
						first_edge = 0;
						if (v->index > ((grid_graph->ecount / 2) - (grid_graph->vcount/2)))
							continue;
					}
						
					/*check if its the last edge*/
					if (u->parent != NULL)
						if (u->parent->parent == NULL)
							last_edge = 1;
							
					/* don't insert if its a via*/
					if (last_edge)
						if (v->index > ((grid_graph->ecount / 2) - (grid_graph->vcount/2)))
							continue;
					
					i = (int*) malloc(sizeof(int));
					tree_cost += v->weight;
					*i = v->index;
					list_ins_next(&T, list_tail(&T),i);
				}
			}
			
			/* next */
			u = u->parent;
		}
		
		/* count total edges*/
		*edge_count_OUT = list_size(&T);

		/* write the solution (including vias)*/
		if ((*(SteinerTree_OUT) = (int*) malloc(sizeof(int)*(list_size(&T))))==NULL) {
			printf("gsFH.h : SteinerTree_OUT mem allocation error\n");
			fflush(stdout);
			exit(1);
		}
		
		e = list_head(&T);
		for (j = 0; ((j < list_size(&T))&&(e!=NULL)); j++,e=list_next(e)) 
			(*SteinerTree_OUT)[j] = *((int*)list_data(e));
		
		
		/* free up some temps*/
		free(v1->data); free(v1);
		free(v2->data); free(v2);
		list_destroy(&P);
		list_destroy(&T);
		
		return 0;
	}
	
	/*--------------------------------------------------------*/
	/* General case of 3 or more terminals begins here.  The  */
	/* above code for 2 terminals or less can be removed      */
	/* without affecting the block solution.   However, it is */
	/* faster with the special case                           */
	/*--------------------------------------------------------*/	
	
	/* Create Path Vertices out of the original terminal set */
	if ((terminals = (PathVertex**) malloc(sizeof(PathVertex*)*NO_TERMINALS))==NULL) {
		printf("gsFH.h : terminals mem allocation error\n");
		fflush(stdout);
		exit(1);
	}	
	for (i = 0; i < NO_TERMINALS; i++) {
		int x,y,z;
		
		x = term[i].x;
		y = term[i].y;
		z = term[i].z;
		
		path_vertex = (PathVertex*) malloc(sizeof(PathVertex));
		coord = (CoordData*) malloc(sizeof(CoordData));
		
		if ((path_vertex == NULL)||(coord == NULL)) {
			printf("gsFH.h : terminal[i] mem allocation error\n");
			fflush(stdout);
			exit(1);
		}

		
		coord->x = x;
		coord->y = y;
		coord->z = z;
		path_vertex->data = coord;
		
		terminals[i] = path_vertex;
	}

    

	/* inialize an array of list pointers used in extracting shortest paths from Dijkstra */
	sPaths = (List**) malloc(sizeof(List*)*NO_TERMINALS);
	if (sPaths == NULL) {
		printf("gsFH.h : sPaths mem allocation error\n");
		fflush(stdout);
		exit(1);
	}
	if ((tempPaths = (List*) malloc(sizeof(List)*NO_TERMINALS))==NULL) {
		printf("gsFH.h : tempPaths mem allocation error\n");
		fflush(stdout);
		exit(1);
	}	
	for (i = 0; i < NO_TERMINALS; i++)
		if ((sPaths[i] = (List*) malloc(sizeof(List)*NO_TERMINALS))==NULL) {
			printf("gsFH.h : sPaths[i] mem allocation error\n");
			fflush(stdout);
			exit(1);
		}



    
    /*--------------------------------------------------------------------------------------*/
    /*                          COMPUTE THE SHORTEST PATHS                                  */
    /*  Shortest paths are computed using O(EV^2) version of Dijkstras Algorithm            */
    /*--------------------------------------------------------------------------------------*/
    
	
    
    /* for each terminal (stored as a path vertex), find the shortest path   */
    /* The shortest path for terminal[i] is stored in the List pointed to by */
    /* paths[i].                                                             */

	for (i = 0; i < NO_TERMINALS; i++) {
		
		if (shortest(grid_graph, terminals[i], &tempPaths[i], match_coord,GRID_WIDTH,GRID_HEIGHT) != 0)
			return 1;
		
		/* copy out the shortest path data, if we don't do this, it will get overwritten*/
		for (j = 0; j < NO_TERMINALS; j++) 
			if (i != j)
				copy_sPath(&tempPaths[i], &(sPaths[i][j]), (CoordData*)((PathVertex*)terminals[j])->data);
	}
			
	
			


	/*--------------------------------------------------------------------------------------------------*/
	/*                Generate complete distance network ND												*/
	/*--------------------------------------------------------------------------------------------------*/

	/* initialize the graph */
	graph_init(&ND, match_coord, (void*)mst_vertex_free);
	
	/* insert the verticies.  Verticies consist of all the terminals */
	for (i = 0; i < NO_TERMINALS; i++) {
		
		/* allocate space for a MST vertex */
		if ((mst_vertex = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) {
			printf("Error allocating space for mst_vertex\n");
			printf("Terminating..\n");
			return 1;
		}
		
		/* if it's the first, make it the start.  It doesn't matter which one is the start */
		if (i == 1)
			mst_start = mst_vertex;
		
		/* set the data */
		if ((coord = (CoordData*) malloc(sizeof(CoordData)))==NULL) {
			printf("gsFH.h : coord mem allocation error\n");
			fflush(stdout);
			exit(1);
		}

		coord->x = ((CoordData*)(((PathVertex*)terminals[i])->data))->x;
		coord->y = ((CoordData*)(((PathVertex*)terminals[i])->data))->y;
		coord->z = ((CoordData*)(((PathVertex*)terminals[i])->data))->z;
		mst_vertex->data = coord;
		
		/* insert */
		if (graph_ins_vertex(&ND, mst_vertex) != 0) {
			printf("Error inserting vertex into mst_graph\n");
			printf("Terminating...\n");
			return 1;
		}
	}

	/*	now we must insert the edges into the distance network graph ND.  We do this by accessing the
		shortest path lists (sPath) computed in the previous step */
	for (i = 0; i < NO_TERMINALS; i++) {
		int ux,uy,uz;
		
		ux = ((CoordData*)((PathVertex*)terminals[i])->data)->x;
		uy = ((CoordData*)((PathVertex*)terminals[i])->data)->y;		
		uz = ((CoordData*)((PathVertex*)terminals[i])->data)->z;
				
		for (j = 0; j < NO_TERMINALS; j++) {
			int vx,vy,vz;
			
			/* shouldn't be an edge from a terminal to itself */
			if (i != j) {
				double weight;
				CoordData *v1,*v2;
				int eCode;
			
				vx = ((CoordData*)((PathVertex*)terminals[j])->data)->x;
				vy = ((CoordData*)((PathVertex*)terminals[j])->data)->y;
				vz = ((CoordData*)((PathVertex*)terminals[j])->data)->z;
				
			
				/* now we must find how far away vx is from vy.   we do this by looking
					for at the head element in sPath[i][j] */
				
				element = list_head(&(sPaths[i][j]));
				sPath_vertex = list_data(element);
				weight = ((sPathData*)sPath_vertex)->d;
				
				/* allocate an edge */				
				if ((v1 = (CoordData*) malloc(sizeof(CoordData))) == NULL) {
					printf("gsFH.h : v1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				if ((v2 = (CoordData*) malloc(sizeof(CoordData))) == NULL) {
					printf("gsFH.h : v2 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				
				v1->x = ux;
				v1->y = uy;
				v1->z = uz;
				
				v2->x = vx;
				v2->y = vy;
				v2->z = vz;
				
				if ((mst_vertex1 = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) {
					printf("gsFH.h : mst_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
								
				if ((mst_vertex2 = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) {
					printf("gsFH.h : mst_vertex2 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				mst_vertex1->data =v1;
				mst_vertex2->data = v2;
				mst_vertex2->weight = weight;
				
				if ((eCode = graph_ins_edge(&ND, mst_vertex1, mst_vertex2)) != 0) {
					printf("Error inserting edge into ND\n");
					printf("graph_ins_edge returned the value %d\n",eCode);
					return 1;
				}
				
				free(mst_vertex1->data);
				free(mst_vertex1);
				
			}/* endif i!=j */
		}/* endfor j */
	}/* endfor i */

/*--------------------------------------------------------------------------------------------------*/
/*		Copmute TD (Min Span Tree of ND)						    */
/*--------------------------------------------------------------------------------------------------*/

	if (mst(&ND, mst_start,&TD, match_coord) != 0) {
		printf("Error computing minimum spanning tree\n");
		return 1;
	}	
	
	/* set leaves */
	
	/* initialize */
	for ( element = list_head(&TD); element != NULL; element = list_next(element))
	{
	   mst_vertex = list_data(element);
	   mst_vertex->is_leaf = 1;
    }
    
    /* for each node, set the parent is_leaf to 0.   Then, all leaves will remain */
    for (element = list_head(&TD); element != NULL; element = list_next(element))
    {
        mst_vertex = list_data(element);
        
        if (mst_vertex->parent != NULL)
            mst_vertex->parent->is_leaf = 0;
    }
	

/*--------------------------------------------------------------------------------------------------*/
/*	         Find N[TD]									    */
/*--------------------------------------------------------------------------------------------------*/
	
	graph_init(&NTD,match_coord,(void*)mst_vertex_free);


    /* for each edge in TD */
	for (element = list_head(&TD); element != NULL; element = list_next(element)) {
		MstVertex	*nextVertex;
		int			v,p;

		p = -1;
		v = -1;

		nextVertex = list_data(element);
		
		/* if it is not the root */
		if (nextVertex->parent != NULL) {
			int vx,vy,vz,px,py,pz;
			ListElmt	*currentV, *nextV;
			int			done;
			
			
			vx = ((CoordData*)((MstVertex*)nextVertex)->data)->x;
			vy = ((CoordData*)((MstVertex*)nextVertex)->data)->y;
			vz = ((CoordData*)((MstVertex*)nextVertex)->data)->z;
			
			px = ((CoordData*)(MstVertex*)(nextVertex->parent)->data)->x;
			py = ((CoordData*)(MstVertex*)(nextVertex->parent)->data)->y;			
			pz = ((CoordData*)(MstVertex*)(nextVertex->parent)->data)->z;
			
			/* find terminal index of nextVertex and nextVertex->parent */
			for (i = 0; i < NO_TERMINALS; i++) {
				int tx,ty,tz;
				
				tx = ((CoordData*)((PathVertex*)terminals[i])->data)->x;
				ty = ((CoordData*)((PathVertex*)terminals[i])->data)->y;
				tz = ((CoordData*)((PathVertex*)terminals[i])->data)->z;
				
				if ((tx == vx)&&(ty == vy)&&(tz == vz))
					v = i;
				
				if ((tx == px)&&(ty == py)&&(tz == pz))
					p = i;
			}
			
			/* now, we must step through the list of sPathData elements found in sPaths[p][v].
			   For each element in the list, we must insert vertices for the vertex and parent, 
				then make an edge with the appropriate weight and insert it */
			
			currentV = list_head(&(sPaths[p][v]));
			nextV = list_next(currentV);
			done = 0;
			while ( !done ) {
				MstVertex	*u,*v, *mst_vertex1, *mst_vertex2;
				CoordData	*uc,*vc;
				sPathData	*currentVData, *nextVData;
				int			cvx,cvy,cvz,nvx,nvy,nvz;
				double		weight;

				/*---------------------------------------*/
				/* insert vertices u and v into NTD      */
				/*---------------------------------------*/
				
				/* make a vertex for currentV and nextV */
				u = (MstVertex*) malloc(sizeof(MstVertex));
				v = (MstVertex*) malloc(sizeof(MstVertex));
				uc = (CoordData*) malloc(sizeof(CoordData));
				vc = (CoordData*) malloc(sizeof(CoordData));
				
				if ((u == NULL)||(uc==NULL)||(v==NULL)||(vc==NULL)) {
					printf("gsFH.h : error allocating vertex for NTD\n");
					fflush(stdout);
					exit(1);
				}
				
				/* get vertices from the sPaths list */
				currentVData = list_data(currentV);
				nextVData = list_data(nextV);
				
				/* get vertex data */
				cvx = ((CoordData*)((sPathData*)currentVData)->vertex)->x;
				cvy = ((CoordData*)((sPathData*)currentVData)->vertex)->y;
				cvz = ((CoordData*)((sPathData*)currentVData)->vertex)->z;
				
				nvx = ((CoordData*)((sPathData*)nextVData)->vertex)->x;
				nvy = ((CoordData*)((sPathData*)nextVData)->vertex)->y;
				nvz = ((CoordData*)((sPathData*)nextVData)->vertex)->z;

								
				/* set vertex data */
				uc->x = cvx;
				uc->y = cvy;
				uc->z = cvz;
				
				vc->x = nvx;
				vc->y = nvy;
				vc->z = nvz;
				
				u->data = uc;
				v->data = vc;
				
				/* calculate weight between u and v */
				weight = currentVData->d - nextVData->d;

				
				/* try and insert u, if it exists, then delete the memory we allocated for it */
				if ( graph_ins_vertex(&NTD, u) == 1 ) {
					free(uc);
					free(u);
				}
				else {
					/* doesnt' matter which one is the start */
					mst_start = u;
				}

				/* try and insert v, if it exists, then delete the memorr we allocated for it */
				if ( graph_ins_vertex(&NTD, v) == 1) {
					free(vc);
					free(v);
				}
				
				/* now the vertices u and v are in the graph.   we now have to make an edge for uv */
				
				/* make edge going forward */				
				if ((uc = (CoordData*)malloc(sizeof(CoordData))) == NULL) {
					printf("gsFH.h : uc mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				if ((vc = (CoordData*)malloc(sizeof(CoordData))) == NULL) {
					printf("gsFH.h : vc mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				uc->x = cvx;
				uc->y = cvy;
				uc->z = cvz;

				vc->x = nvx;
				vc->y = nvy;
				vc->z = nvz;
				
				if ((mst_vertex1 = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) {
					printf("gsFH.h : mst_Vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				if ((mst_vertex2 = (MstVertex*)malloc(sizeof(MstVertex))) == NULL) {
					printf("gsFH.h : mst_vertex2 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				mst_vertex1->data = uc;
				mst_vertex2->data = vc;
				mst_vertex2->weight = weight;
				
				/* try and insert, if it exists, free previously allocated mem */
				if ( graph_ins_edge(&NTD, mst_vertex1, mst_vertex2) == 1) {
					free(vc);
					free(mst_vertex2);
				}
				
				/* free the label */
				free(mst_vertex1->data);
				free(mst_vertex1);
				
				
				/* make edge going backward */				
				if ((uc = (CoordData*)malloc(sizeof(CoordData))) == NULL) {
					printf("gsFH.h : uc mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				if ((vc = (CoordData*)malloc(sizeof(CoordData))) == NULL) {
					printf("gsFH.h : vc mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				uc->x = cvx;
				uc->y = cvy;
				uc->z = cvz;
				
				vc->x = nvx;
				vc->y = nvy;
				vc->z = nvz;
				
				if ((mst_vertex1 = (MstVertex*) malloc(sizeof(MstVertex))) == NULL) {
					printf("gsFH.h : mst_Vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}

				if ((mst_vertex2 = (MstVertex*)malloc(sizeof(MstVertex))) == NULL) {
					printf("gsFH.h : mst_Vertex2 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
				mst_vertex1->data = vc;
				mst_vertex2->data = uc;
				mst_vertex2->weight = weight;
				
				/* try and insert, if it exists, free previously allocated mem */
				if ( graph_ins_edge(&NTD, mst_vertex1, mst_vertex2) == 1) {
					free(uc);
					free(mst_vertex2);
				}

				/* free the label */
				free(mst_vertex1->data);
				free(mst_vertex1);
								
				
				/* follow pointers */
				currentV = list_next(currentV);
				nextV = list_next(nextV);
				
				/* check to see if we're finished */
				if (nextV == NULL)
					done = 1;
			
			}
				
		 }
	}


/*----------------------------------------------------------------------------------------------------------*/
/*	Compute T (minimum spanning tree of NTD)							    */
/*----------------------------------------------------------------------------------------------------------*/

	/* call minimum spanning tree subroutine */
	if (mst(&NTD, mst_start,&T, match_coord) != 0) {
		printf("Error computing minimum spanning tree\n");
		return 1;
	}

	/* set leaves */	
	for ( element = list_head(&T); element != NULL; element = list_next(element))
	{
		mst_vertex = list_data(element);
		mst_vertex->is_leaf = 1;
    }
    
    /* for each node, set the parent is_leaf to 0.   Then, all leaves will remain */
    for (element = list_head(&T); element != NULL; element = list_next(element))
    {
        mst_vertex = list_data(element);
        
        if (mst_vertex->parent != NULL)
            mst_vertex->parent->is_leaf = 0;
    }
    
	
	
/*--------------------------------------------------------------------------------------*/
/*		Compute Steiner Tree Sk						 	*/
/*--------------------------------------------------------------------------------------*/

	isSteiner = 0;
	/* we remove all leaves that arent' terminals, when all leaves are terminals then we have a Steiner Tree */
	while (!isSteiner) {
		ListElmt	*prev;
		
		/* assume we have it */
		isSteiner = 1;
		
		/* check if each leaf is a terminal */
		prev = list_head(&T);
		element = list_next(prev);
		while (element != NULL) {
			int mx,my,mz;
			
			mst_vertex = list_data(element);
			mx = ((CoordData*)((MstVertex*)mst_vertex)->data)->x;
			my = ((CoordData*)((MstVertex*)mst_vertex)->data)->y;		
			mz = ((CoordData*)((MstVertex*)mst_vertex)->data)->z;					
			
			if (mst_vertex->is_leaf) {
				int found;
				
				found = 0;
				for (i = 0; i < NO_TERMINALS; i++) {
					int	tx,ty,tz;
					
					tx = ((CoordData*)((PathVertex*)terminals[i])->data)->x;
					ty = ((CoordData*)((PathVertex*)terminals[i])->data)->y;
					tz = ((CoordData*)((PathVertex*)terminals[i])->data)->z;
					
					if ( (tx==mx)&&(ty==my)&&(tz==mz))
						found = 1;
				}
				
				/* remove it if we can't find it */
				if (!found) {
					MstVertex	*junk;
					ListElmt *e;
					
					isSteiner = 0;		/* not done yet */
					
					list_rem_next(&T, prev, (void**)(&junk));
					
					/*reset leaves */
					/* initialize */
					for ( e = list_head(&T); e != NULL; e = list_next(e))
					{
						mst_vertex = list_data(e);
						mst_vertex->is_leaf = 1;
					}
					
					/* for each node, set the parent is_leaf to 0.   Then, all leaves will remain */
					for (e = list_head(&T); e != NULL; e = list_next(e))
					{
						mst_vertex = list_data(e);
						
						if (mst_vertex->parent != NULL)
							mst_vertex->parent->is_leaf = 0;
					}
					
					/* start over at beginning of list */
					prev = list_head(&T);
					element = list_next(prev);
					
					
				}
				else {
					prev = list_next(prev);
					element = list_next(element);
				}
			}
			else {
				prev = list_next(prev);
				element = list_next(element);
			}
		}
	}



	/* we can further eliminate vias that connect to a terminal leaf.   These are not neccessary*/
	isSteiner = 0;
	while (!isSteiner) {
		ListElmt	*prev;
		
		/* assume we have it */
		isSteiner = 1;
		
		/* check if each leaf is a terminal */
		prev = list_head(&T);
		element = list_next(prev);
		while (element != NULL) {
			int mx,my,mz;
			
			mst_vertex = list_data(element);
			mx = ((CoordData*)((MstVertex*)mst_vertex)->data)->x;
			my = ((CoordData*)((MstVertex*)mst_vertex)->data)->y;		
			mz = ((CoordData*)((MstVertex*)mst_vertex)->data)->z;					
			
			if (mst_vertex->is_leaf) {
				int remove;
				int	px,py;
				
				remove = 0;
				px = ((CoordData*)((MstVertex*)mst_vertex->parent)->data)->x;
				py = ((CoordData*)((MstVertex*)mst_vertex->parent)->data)->y;				
				
				if ((px == mx)&&(py == my))
					remove = 1;
				
				
				/* remove it if neccessary */
				if (remove) {
					MstVertex	*junk;
					ListElmt *e;
					
					isSteiner = 0;		/* not done yet */
					
					list_rem_next(&T, prev, (void**)(&junk));
					
					/*reset leaves */
					/* initialize */
					for ( e = list_head(&T); e != NULL; e = list_next(e))
					{
						mst_vertex = list_data(e);
						mst_vertex->is_leaf = 1;
					}
					
					/* for each node, set the parent is_leaf to 0.   Then, all leaves will remain */
					for (e = list_head(&T); e != NULL; e = list_next(e))
					{
						mst_vertex = list_data(e);
						
						if (mst_vertex->parent != NULL)
							mst_vertex->parent->is_leaf = 0;
					}
					
					/* start over at beginning of list */
					prev = list_head(&T);
					element = list_next(prev);
					
					
				}
				else {
					prev = list_next(prev);
					element = list_next(element);
				}
			}
			else {
				prev = list_next(prev);
				element = list_next(element);
			}
		}
	}



	/* get the total cost of the tree */
	tree_cost = 0;
	for (element = list_head(&T); element != NULL; element = list_next(element)) {
		
		CoordData *u, *v;
		
		mst_vertex = list_data(element);
		
		if (( mst_vertex->parent == NULL))
			continue;
		else {
			double temp;
			
			u = (CoordData*)mst_vertex->data;
			v = (CoordData*)mst_vertex->parent->data;
			
			/* look up cost of edge uv */
			temp = find_edge_weight(grid_graph,u,v);
			tree_cost += temp;
				
		}
	}
	
	

	*edge_count_OUT = list_size(&T)-1;
	if ((*(SteinerTree_OUT) = (int*) malloc(sizeof(int)*(list_size(&T)-1)))==NULL) {
		printf("gsFH.h : SteinerTree_OUT mem allocation error\n");
		fflush(stdout);
		exit(1);
	}


	i = 0;
	for ( element = list_head(&T); element != NULL; element = list_next(element))
	{
		int vx,vy,vz,px,py,pz;
		int tx,ty,tz;
		AdjList *a;
		ListElmt *e;
		int		edge_index;
		double	edge_weight;
		
		mst_vertex = list_data(element);
		
		vx = ((CoordData*)mst_vertex->data)->x;
		vy = ((CoordData*)mst_vertex->data)->y;
		vz = ((CoordData*)mst_vertex->data)->z;
		if (mst_vertex->parent != NULL) {
			px = ((CoordData*)mst_vertex->parent->data)->x;
			py = ((CoordData*)mst_vertex->parent->data)->y;		
			pz = ((CoordData*)mst_vertex->parent->data)->z;		
			edge_weight = mst_vertex->weight;
		}
		else {
			px = -1;
			py = -1;
			pz = -1;
		}
		

			
		a = (AdjList*)Edge2Adj[vx][vy][vz];
		
		tx = ((CoordData*)((PathVertex*)(a->vertex))->data)->x;
		ty = ((CoordData*)((PathVertex*)(a->vertex))->data)->y;
		tz = ((CoordData*)((PathVertex*)(a->vertex))->data)->z;
		
		for ( e = list_head(&(a->adjacent)); e != NULL; e = list_next(e) ) {
			PathVertex *p;
		
			p = (PathVertex*)list_data(e);
			
			tx = ((CoordData*)p->data)->x;
			ty = ((CoordData*)p->data)->y;
			tz = ((CoordData*)p->data)->z;
			
			if ((tx == px)&&(ty == py)&&(tz == pz)) {	/*found*/
				edge_index = p->index;
				(*SteinerTree_OUT)[i] = edge_index;
				i++;
			}
		}
	}


	

	/*-------------------------------------------------------------------------------------*/
	/*			Clean Up						       */
	/*-------------------------------------------------------------------------------------*/
	
	

	/* free our list of temporary paths*/
	for (i = 0; i < NO_TERMINALS; i++) 
		list_destroy(&tempPaths[i]);
	free(tempPaths);

	/* destroy distance network*/
	graph_destroy(&ND);
	
	/* deystroy all the shortest path lists*/
	for (i = 0; i < NO_TERMINALS; i++) 
	   for (j = 0; j < NO_TERMINALS; j++)
		   if ( i != j ) 
			   list_destroy(&sPaths[i][j]);
	
	/* destroy the pointers to the shortest path lists*/
	for (i = 0; i < NO_TERMINALS; i++) 
		free(sPaths[i]);
	free(sPaths);

	/* destroy the minimum spanning tree*/
	list_destroy(&TD);

	/* destroy grid spanning tree*/
	graph_destroy(&NTD);

	/* destroy the terminal list*/
	for (i = 0; i < NO_TERMINALS; i++) {
		path_vertex_free(terminals[i]);
	}
	free(terminals);
	
	/*destroy the steiner tree*/
	list_destroy(&T);

	return 0;
}
예제 #7
0
파일: ex-1.c 프로젝트: ArineYao/algorithms
int main(int argc, char **argv) {

Graph              graph;

AdjList            *adjlist;

ListElmt           *element;

char               *data,
                   data1[STRSIZ],
                   *data2;

int                retval,
                   size,
                   i;

/*****************************************************************************
*                                                                            *
*  Initialize the graph.                                                     *
*                                                                            *
*****************************************************************************/

graph_init(&graph, match_str, free);

/*****************************************************************************
*                                                                            *
*  Perform some graph operations.                                            *
*                                                                            *
*****************************************************************************/

if ((data = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data, "a");
fprintf(stdout, "Inserting vertex %s\n", data);

if (graph_ins_vertex(&graph, data) != 0)
   return 1;

if ((data = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data, "b");
fprintf(stdout, "Inserting vertex %s\n", data);

if (graph_ins_vertex(&graph, data) != 0)
   return 1;

if ((data = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data, "c");
fprintf(stdout, "Inserting vertex %s\n", data);

if (graph_ins_vertex(&graph, data) != 0)
   return 1;

if ((data = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data, "d");
fprintf(stdout, "Inserting vertex %s\n", data);

if (graph_ins_vertex(&graph, data) != 0)
   return 1;

if ((data = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data, "e");
fprintf(stdout, "Inserting vertex %s\n", data);

if (graph_ins_vertex(&graph, data) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "a");
strcpy(data2, "b");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "a");
strcpy(data2, "c");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "b");
strcpy(data2, "c");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "b");
strcpy(data2, "d");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "c");
strcpy(data2, "b");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "c");
strcpy(data2, "c");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "c");
strcpy(data2, "d");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "d");
strcpy(data2, "a");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "e");
strcpy(data2, "c");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "e");
strcpy(data2, "d");
fprintf(stdout, "Inserting edge %s to %s\n", data1, data2);

if (graph_ins_edge(&graph, data1, data2) != 0)
   return 1;

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "a");
strcpy(data2, "c");
data = data2;

fprintf(stdout, "Removing edge %s to %s\n", data1, data2);

if (graph_rem_edge(&graph, data1, (void **)&data) != 0)
   return 1;

free(data);
print_graph(&graph);

strcpy(data1, "c");
strcpy(data2, "c");
data = data2;

fprintf(stdout, "Removing edge %s to %s\n", data1, data2);

if (graph_rem_edge(&graph, data1, (void **)&data) != 0)
   return 1;

free(data);
print_graph(&graph);

strcpy(data1, "e");
strcpy(data2, "c");
data = data2;

fprintf(stdout, "Removing edge %s to %s\n", data1, data2);

if (graph_rem_edge(&graph, data1, (void **)&data) != 0)
   return 1;

free(data);
print_graph(&graph);

strcpy(data1, "a");
strcpy(data2, "b");
data = data2;

fprintf(stdout, "Removing edge %s to %s\n", data1, data2);

if (graph_rem_edge(&graph, data1, (void **)&data) != 0)
   return 1;

free(data);
print_graph(&graph);

strcpy(data1, "d");
strcpy(data2, "a");
data = data2;

fprintf(stdout, "Removing edge %s to %s\n", data1, data2);

if (graph_rem_edge(&graph, data1, (void **)&data) != 0)
   return 1;

free(data);
print_graph(&graph);

free(data2);

strcpy(data1, "a");
data = data1;

fprintf(stdout, "Removing vertex %s\n", data1);

if (graph_rem_vertex(&graph, (void **)&data) != 0)
   return 1;

free(data);
print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "f");
strcpy(data2, "a");

retval = graph_ins_edge(&graph, data1, data2);
fprintf(stdout,"Inserting an invalid edge from %s to %s...Value=%d (-1=OK)\n",
   data1, data2, retval);

if (retval != 0)
   free(data2);

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "c");
strcpy(data2, "b");

retval = graph_ins_edge(&graph, data1, data2);
fprintf(stdout,"Inserting an existing edge from %s to %s...Value=%d (1=OK)\n",
   data1, data2, retval);

if (retval != 0)
   free(data2);

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "f");
strcpy(data2, "a");
data = data2;

retval = graph_rem_edge(&graph, data1, (void **)&data);
fprintf(stdout, "Removing an invalid edge from %s to %s...Value=%d (-1=OK)\n",
   data1, data2, retval);

if (retval == 0)
   free(data);

free(data2);
print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "c");
strcpy(data2, "e");
data = data2;

retval = graph_rem_edge(&graph, data1, (void **)&data);
fprintf(stdout, "Removing an invalid edge from %s to %s...Value=%d (-1=OK)\n",
   data1, data2, retval);

if (retval == 0)
   free(data);

free(data2);
print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data2, "c");

retval = graph_ins_vertex(&graph, data2);
fprintf(stdout, "Inserting an existing vertex %s...Value=%d (1=OK)\n", data1,
   retval);

if (retval != 0)
   free(data2);

print_graph(&graph);

if ((data2 = (char *)malloc(STRSIZ)) == NULL)
   return 1;

strcpy(data1, "b");
strcpy(data2, "d");

retval = graph_is_adjacent(&graph, data1, data2);
fprintf(stdout, "Testing graph_is_adjacent (%s, %s)...Value=%d (1=OK)\n",
   data1, data2, retval);

strcpy(data1, "a");
strcpy(data2, "e");

retval = graph_is_adjacent(&graph, data1, data2);
fprintf(stdout, "Testing graph_is_adjacent (%s, %s)...Value=%d (0=OK)\n",
   data1, data2, retval);

strcpy(data1, "e");
strcpy(data2, "d");

retval = graph_is_adjacent(&graph, data1, data2);
fprintf(stdout, "Testing graph_is_adjacent (%s, %s)...Value=%d (1=OK)\n",
   data1, data2, retval);

strcpy(data1, "c");
strcpy(data2, "a");

retval = graph_is_adjacent(&graph, data1, data2);
fprintf(stdout, "Testing graph_is_adjacent (%s, %s)...Value=%d (0=OK)\n",
   data1, data2, retval);

free(data2);

strcpy(data1, "c");

if (graph_adjlist(&graph, data1, &adjlist) != 0)
   return 1;

fprintf(stdout, "Vertices adjacent to %s: ", data1);

i = 0;
size = set_size(&adjlist->adjacent);
element = list_head(&adjlist->adjacent);

while (i < size) {

   i++;
   if (i > 1) fprintf(stdout, ", ");
   fprintf(stdout, "%s", (char *)list_data(element));
   element = list_next(element);

}

fprintf(stdout, "\n");

/*****************************************************************************
*                                                                            *
*  Destroy the graph.                                                        *
*                                                                            *
*****************************************************************************/

fprintf(stdout, "Destroying the graph\n");
graph_destroy(&graph);

return 0;

}
예제 #8
0
/*-------------------------------------------------------------*/
int gen_gridgraph(Graph *grid_graph, int GRID_WIDTH, int GRID_HEIGHT) {
	
	PathVertex		*path_vertex, *path_start, *path_vertex1, *path_vertex2;
	CoordData		*coord;
	int				i,j;
	int				index;
	
	printf("Creating Grid Graph\n");
	
	/* initialize a grid graph */
	graph_init(grid_graph, match_coord, (void*)path_vertex_free);
	printf("\tInitialized grid graph..\n");
	
    /* insert vertices into grid graph */
	printf("\tInserting verticies");
    for (i = 0; i < GRID_WIDTH; i++) {
		
		printf(".");
		fflush(stdout);
		
        for (j = 0; j < GRID_HEIGHT; j++) {
			
            /* allocate a vertex */
            if ((path_vertex = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
                printf("\t\tError allocating (%d,%d) PathVertex\nTerminating...\n",i,j);
                fflush(stdout);
                exit(1);
            }
			
            /* allocate a coordinate */
            if ((coord = (CoordData*) malloc(sizeof(CoordData))) == NULL) {
                printf("\t\tError allocating (%d,%d) CoordData\nTerminating...\n",i,j);
				fflush(stdout);
				exit(1);
            }
			
            /* set values to coord */
            coord->x = i;
            coord->y = j;
			coord->z = 0;
            
            /* insert coord as data to path vertex */
            path_vertex->data = coord;
			
			if ((i == 1)&&(j==2))
				path_start = path_vertex;
            
            /*insert it into the graph */
            if (graph_ins_vertex(grid_graph, path_vertex) != 0) {
                printf("\t\tError inserting vertex (%d,%d)\nTerminating...\n",i,j);
                return 1;
            }
        }
    } /*done inserting vertices*/     
	printf("Finished\n");
    
    
    /* for each vertex we check if there is a vertex to the left, right, above and below.
		In this way, it only consumes O(n) time where n is the number of vertices */
    /* insert edges into grid graph */
	printf("\tInserting edges");
	
	index = 1;
	
    for (i = 0; i < GRID_WIDTH; i++) {
		
		printf(".");
		fflush(stdout);
		
        for (j = 0; j < GRID_HEIGHT; j++) {
            
            /* check to the left */
            if (i - 1 >= 0) {
                CoordData *u,*v;
				
                /* allocate the vertices (for in the edges)*/
                u = (CoordData*)malloc(sizeof(CoordData));
                v = (CoordData*)malloc(sizeof(CoordData));
                
                if (u == NULL) {
                	printf("gsFH.h : u mem allocation error\n");
                	fflush(stdout);
                	exit(1);
                }
				
                if (v == NULL) {
                	printf("gsFH.h : v mem allocation error\n");
                	fflush(stdout);
                	exit(1);
                }
				
				
                /* set vertex data */
                u->x = i;
                u->y = j;
				u->z = 0;
				
                v->x = i-1;
                v->y = j;
				v->z = 0;
				
				
				if ((path_vertex1 = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
					printf("gsFH.h : path_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
                
                if ((path_vertex2 = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
  					printf("gsFH.h : path_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
                path_vertex1->data = u;
                path_vertex2->data = v;
                path_vertex2->weight = 1;
                
                if (graph_ins_edge(grid_graph, path_vertex1, path_vertex2) != 0)
                    return 1;
				
				free(path_vertex1->data);
				free(path_vertex1);
				
            }
            
            /* check to the right */
            if (i + 1 < GRID_WIDTH) {
                CoordData *u,*v;
				
                /* allocate the vertices (for in the edges)*/
                u = (CoordData*)malloc(sizeof(CoordData));
                v = (CoordData*)malloc(sizeof(CoordData));
                
                if (u == NULL) {
                	printf("gsFH.h : u mem allocation error\n");
                	fflush(stdout);
                	exit(1);
                }
				
                if (v == NULL) {
                	printf("gsFH.h : v mem allocation error\n");
                	fflush(stdout);
                	exit(1);
                }
				
				
                /* set vertex data */
                u->x = i;
                u->y = j;
				u->z = 0;
				
                v->x = i+1;
                v->y = j;
				v->z = 0;
				
				
				if ((path_vertex1 = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
					printf("gsFH.h : path_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
                
                if ((path_vertex2 = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
  					printf("gsFH.h : path_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
                path_vertex1->data = u;
                path_vertex2->data = v;
                path_vertex2->weight = 1;
                
                if (graph_ins_edge(grid_graph, path_vertex1, path_vertex2) != 0)
                    return 1;
				
				free(path_vertex1->data);
				free(path_vertex1);
            }
			
            /* check up */
            if (j - 1 >= 0) {
                CoordData *u,*v;
				
                /* allocate the vertices (for in the edges)*/
                u = (CoordData*)malloc(sizeof(CoordData));
                v = (CoordData*)malloc(sizeof(CoordData));
                
                if (u == NULL) {
                	printf("gsFH.h : u mem allocation error\n");
                	fflush(stdout);
                	exit(1);
                }
				
                if (v == NULL) {
                	printf("gsFH.h : v mem allocation error\n");
                	fflush(stdout);
                	exit(1);
                }
				
				
                /* set vertex data */
                u->x = i;
                u->y = j;
				u->z = 0;
				
                v->x = i;
                v->y = j-1;
				v->z = 0;
				
				
				if ((path_vertex1 = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
					printf("gsFH.h : path_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
                
                if ((path_vertex2 = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
  					printf("gsFH.h : path_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
                path_vertex1->data = u;
                path_vertex2->data = v;
                path_vertex2->weight = 1;
                
                if (graph_ins_edge(grid_graph, path_vertex1, path_vertex2) != 0)
                    return 1;
				
				free(path_vertex1->data);
				free(path_vertex1);
				
            }
            
            /* check down */
            if (j + 1 < GRID_HEIGHT) {
                CoordData *u,*v;
				
                /* allocate the vertices (for in the edges)*/
                u = (CoordData*)malloc(sizeof(CoordData));
                v = (CoordData*)malloc(sizeof(CoordData));
				
                if (u == NULL) {
                	printf("gsFH.h : u mem allocation error\n");
                	fflush(stdout);
                	exit(1);
                }
				
                if (v == NULL) {
                	printf("gsFH.h : v mem allocation error\n");
                	fflush(stdout);
                	exit(1);
                }
				
				
                /* set vertex data */
                u->x = i;
                u->y = j;
				u->z = 0;
				
                v->x = i;
                v->y = j+1;
				v->z = 0;
				
				if ((path_vertex1 = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
					printf("gsFH.h : path_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
				
                
                if ((path_vertex2 = (PathVertex*) malloc(sizeof(PathVertex))) == NULL) {
  					printf("gsFH.h : path_vertex1 mem allocation error\n");
					fflush(stdout);
					exit(1);
				}
                
                path_vertex1->data = u;
                path_vertex2->data = v;
                path_vertex2->weight = 1;
                
                if (graph_ins_edge(grid_graph, path_vertex1, path_vertex2) != 0)
                    return 1;
				
				free(path_vertex1->data);
				free(path_vertex1);
				
            }
			
			
        }
    }/* finished inserting edges */
	printf("Finished\n");
	return 0;
}
예제 #9
0
/*-------------------------------------------------------------*/
void grid2VL(Graph *G, Graph *H, int width, int height) { 
	ListElmt	*elmt;
	int			index,via;
	
	
	printf("Creating Virtual Layer Graph\n");
	
	graph_init(H, match_coord, (void*)path_vertex_free);
	
	// original edges enumrated from 1, vias enumerated after original edges.
	// also, since our graph is undirected, we have to half edges for each edge in undirected graph, 
	// thus we start vias from ecount/2
	index = 1;
	via = (G->ecount / 2) + 1;
	
	
	// for each vertex in G, there will be two vertices in H.  (One per layer)
	printf("\tInserting vertices and vias into multi-layer graph....");
	fflush(stdout);
	for (elmt = list_head(&G->adjlists); elmt != NULL; elmt = list_next(elmt)) {
		PathVertex	*v0,*v1,*v;		// v = vertex from g, v1,v2 = new vertices to insert in H
		CoordData	*v0c,*v1c;
		
		v = ((AdjList*)list_data(elmt))->vertex;
		
		// insert both verticies
		v0 = (PathVertex*) malloc(sizeof(PathVertex));
		v0c = (CoordData*) malloc(sizeof(CoordData));
		v1 = (PathVertex*) malloc(sizeof(PathVertex));
		v1c = (CoordData*) malloc(sizeof(CoordData));
		
		if ( (v0 == NULL)||(v0c == NULL)||(v1 == NULL)||v1c == NULL) {
			printf("gsFH.h : vertex mem allocation error (grid2VL)\n");
			fflush(stdout);
			exit(1);
		}
		
		v0->data = v0c;
		v1->data = v1c;
		
		// horizontal vertex
		v0c->x = ((CoordData*)((PathVertex*)v)->data)->x;
		v0c->y = ((CoordData*)((PathVertex*)v)->data)->y;
		v0c->z = 0;
		
		// vertical vertex
		v1c->x = ((CoordData*)((PathVertex*)v)->data)->x;
		v1c->y = ((CoordData*)((PathVertex*)v)->data)->y;
		v1c->z = 1;
		
		graph_ins_vertex(H,v0);
		graph_ins_vertex(H,v1);
		
		// now we insert the via between v0 and v1
		v0 = (PathVertex*) malloc(sizeof(PathVertex));
		v0c = (CoordData*) malloc(sizeof(CoordData));
		v1 = (PathVertex*) malloc(sizeof(PathVertex));
		v1c = (CoordData*) malloc(sizeof(CoordData));
		
		if ( (v0 == NULL)||(v0c == NULL)||(v1 == NULL)||v1c == NULL) {
			printf("gsFH.h : vertex mem allocation error (grid2VL)\n");
			fflush(stdout);
			exit(1);
		}
		
		
		v0->data = v0c;
		v1->data = v1c;
		
		// set the weights to 1, temporarily
		v1->weight	 = 1;
		
		// set via index
		v1->index = via;
		
		// horizontal vertex
		v0c->x = ((CoordData*)((PathVertex*)v)->data)->x;
		v0c->y = ((CoordData*)((PathVertex*)v)->data)->y;
		v0c->z = 0;
		
		// vertical vertex
		v1c->x = ((CoordData*)((PathVertex*)v)->data)->x;
		v1c->y = ((CoordData*)((PathVertex*)v)->data)->y;
		v1c->z = 1;
		
		
		// forward edge
		graph_ins_edge(H,v0,v1);
		free(v0c);
		free(v0);
		
		
		v0 = (PathVertex*) malloc(sizeof(PathVertex));
		v0c = (CoordData*) malloc(sizeof(CoordData));
		v1 = (PathVertex*) malloc(sizeof(PathVertex));
		v1c = (CoordData*) malloc(sizeof(CoordData));
		
		if ( (v0 == NULL)||(v0c == NULL)||(v1 == NULL)||v1c == NULL) {
			printf("gsFH.h : vertex mem allocation error (grid2VL)\n");
			fflush(stdout);
			exit(1);
		}
		
		
		
		v0->data = v0c;
		v1->data = v1c;
		
		// set the weights to 1, temporarily
		v0->weight	 = 1;
		
		// via index
		v0->index = via;
		
		// horizontal vertex
		v0c->x = ((CoordData*)((PathVertex*)v)->data)->x;
		v0c->y = ((CoordData*)((PathVertex*)v)->data)->y;
		v0c->z = 0;
		
		// vertical vertex
		v1c->x = ((CoordData*)((PathVertex*)v)->data)->x;
		v1c->y = ((CoordData*)((PathVertex*)v)->data)->y;
		v1c->z = 1;
		
		// forward edge
		graph_ins_edge(H,v1,v0);
		free(v1c);
		free(v1);
		
		// next via
		via++;
		
	}
	printf("Finished\n");
	fflush(stdout);
	
	
	printf("\tInserting edges into multi-layer graph..");
	fflush(stdout);
	// now we insert edges into the multi layer graph
	for (elmt = list_head(&G->adjlists); elmt != NULL; elmt = list_next(elmt)) {
		PathVertex	*v0,*v1,*v,*next;		// v = vertex from g, v1,v2 = new vertices to insert in H
		CoordData	*v0c,*v1c;
		ListElmt	*e;
		int			vx,vy,vz;
		
		//printf(".");
		//fflush(stdout);
		
		v = ((AdjList*)list_data(elmt))->vertex;
		
		vx = ((CoordData*)((PathVertex*)v)->data)->x;
		vy = ((CoordData*)((PathVertex*)v)->data)->y;
		vz = ((CoordData*)((PathVertex*)v)->data)->z;
		
		// go through each vertex adjacent to v
		for (e = list_head(&((AdjList*)list_data(elmt))->adjacent); e != NULL; e = list_next(e)) {
			int			nx, ny, nz;
			double		weight;
			int			layer;
			int			exists;
			
			next = list_data(e);
			
			nx = ((CoordData*)((PathVertex*)next)->data)->x;
			ny = ((CoordData*)((PathVertex*)next)->data)->y;
			nz = ((CoordData*)((PathVertex*)next)->data)->z;
			weight = (double)((PathVertex*)next)->weight;
			
			// find out if it's a horizontal or vertical edge
			if (vx == nx) layer = 1;
			else if (vy == ny) layer = 0;
			else assert(0);
			
			// insert forward edge from v0 to v1
			v0 = (PathVertex*) malloc(sizeof(PathVertex));
			v1 = (PathVertex*) malloc(sizeof(PathVertex));
			v0c = (CoordData*) malloc(sizeof(CoordData));
			v1c = (CoordData*) malloc(sizeof(CoordData));
			
			if ( (v0 == NULL)||(v0c == NULL)||(v1 == NULL)||v1c == NULL) {
				printf("gsFH.h : vertex mem allocation error (grid2VL)\n");
				fflush(stdout);
				exit(1);
			}
			
			
			v0c->x = vx;
			v0c->y = vy;
			v0c->z = layer;
			
			v1c->x = nx;
			v1c->y = ny;
			v1c->z = layer;
			
			v0->data = v0c;
			v1->data = v1c;
			
			v1->weight = weight; 
			v1->index = index;
			
			graph_ins_edge(H,v0,v1);
			
			// free the lookup variable
			free(v0c);
			free(v0);
			
			
			// insert the backedge v1 to v0
			v0 = (PathVertex*) malloc(sizeof(PathVertex));
			v1 = (PathVertex*) malloc(sizeof(PathVertex));
			v0c = (CoordData*) malloc(sizeof(CoordData));
			v1c = (CoordData*) malloc(sizeof(CoordData));
			
			if ( (v0 == NULL)||(v0c == NULL)||(v1 == NULL)||v1c == NULL) {
				printf("gsFH.h : vertex mem allocation error (grid2VL)\n");
				fflush(stdout);
				exit(1);
			}
			
			
			v0c->x = vx;
			v0c->y = vy;
			v0c->z = layer;
			
			v1c->x = nx;
			v1c->y = ny;
			v1c->z = layer;
			
			v0->data = v0c;
			v1->data = v1c;
			
			v0->weight = weight;
			v0->index = index; 
			
			exists = graph_ins_edge(H,v1,v0);
			
			if (!exists) {
				((PathVertex*)next)->index = index;		// set index in orginal graph G
				index++;
			}
			
			// free the lookup variable
			free(v1c);
			free(v1);
			
		}
	}
	printf("finished\n");
	fflush(stdout);
	
	
}