Graphviz 16.1.0~dev.20260823.0643
Loading...
Searching...
No Matches
sgraph.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v2.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11
12#include "config.h"
13#include <limits.h>
14#include <ortho/sgraph.h>
15#include <ortho/fPQ.h>
16#include <stdlib.h>
17#include <util/alloc.h>
18
19void
21{
22 int i;
23 G->save_nnodes = G->nnodes;
24 G->save_nedges = G->nedges;
25 for (i = 0; i < G->nnodes; i++)
26 G->nodes[i].save_n_adj = G->nodes[i].n_adj;
27}
28
29void
31{
32 int i;
33 G->nnodes = G->save_nnodes;
34 G->nedges = G->save_nedges;
35 for (i = 0; i < G->nnodes; i++)
36 G->nodes[i].n_adj = G->nodes[i].save_n_adj;
37 for (; i < G->nnodes+2; i++)
38 G->nodes[i].n_adj = 0;
39}
40
41void initSEdges(sgraph *g, size_t maxdeg) {
42 int i;
43 int* adj = gv_calloc(6 * g->nnodes + 2 * maxdeg, sizeof(int));
44 g->edges = gv_calloc(3 * g->nnodes + maxdeg, sizeof(sedge));
45 for (i = 0; i < g->nnodes; i++) {
46 g->nodes[i].adj_edge_list = adj;
47 adj += 6;
48 }
49 for (; i < g->nnodes+2; i++) {
50 g->nodes[i].adj_edge_list = adj;
51 adj += maxdeg;
52 }
53}
54
55sgraph *createSGraph(size_t nnodes) {
56 sgraph* g = gv_alloc(sizeof(sgraph));
57
58 /* create the nodes vector in the search graph */
59 g->nnodes = 0;
60 g->nodes = gv_calloc(nnodes, sizeof(snode));
61 return g;
62}
63
64snode*
66{
67 snode* np = g->nodes+g->nnodes;
68 np->index = g->nnodes;
69 g->nnodes++;
70 return np;
71}
72
73static void
74addEdgeToNode (snode* np, int idx)
75{
76 np->adj_edge_list[np->n_adj] = idx;
77 np->n_adj++;
78}
79
80sedge*
81createSEdge (sgraph* g, snode* v1, snode* v2, double wt)
82{
83 sedge* e;
84 int idx = g->nedges++;
85
86 e = g->edges + idx;
87 e->v1 = v1->index;
88 e->v2 = v2->index;
89 e->weight = wt;
90 e->cnt = 0;
91
92 addEdgeToNode (v1, idx);
93 addEdgeToNode (v2, idx);
94
95 return e;
96}
97
98void
100{
101 if (g == NULL) {
102 return;
103 }
104 if (g->nodes != NULL) {
105 free(g->nodes[0].adj_edge_list);
106 }
107 free (g->nodes);
108 free (g->edges);
109 free (g);
110}
111
112#include <ortho/fPQ.h>
113
114/* shortest path:
115 * Constructs the path of least weight between from and to.
116 *
117 * Assumes graph, node and edge type, and that nodes
118 * have associated values N_VAL, N_IDX, and N_DAD, the first two
119 * being ints, the last being a node*. Edges have a E_WT function
120 * to specify the edge length or weight.
121 *
122 * Assumes there are functions:
123 * agnnodes: graph -> int number of nodes in the graph
124 * agfstnode, agnxtnode : iterators over the nodes in the graph
125 * agfstedge, agnxtedge : iterators over the edges attached to a node
126 * adjacentNode : given an edge e and an endpoint n of e, returns the
127 * other endpoint.
128 *
129 * The path is given by
130 * to, N_DAD(to), N_DAD(N_DAD(to)), ..., from
131 */
132
133#define UNSEEN INT_MIN
134
135static snode*
137{
138 if (e->v1==n->index)
139 return &g->nodes[e->v2];
140 else
141 return &g->nodes[e->v1];
142}
143
144int shortPath(pq_t *pq, sgraph *g, snode *from, snode *to) {
145 snode* n;
146 sedge* e;
147 snode* adjn;
148 int d;
149 int x, y;
150
151 for (x = 0; x<g->nnodes; x++) {
152 snode* temp = &g->nodes[x];
153 N_VAL(temp) = UNSEEN;
154 }
155
156 PQinit(pq);
157 if (PQ_insert(pq, from)) return 1;
158 N_DAD(from) = NULL;
159 N_VAL(from) = 0;
160
161 while ((n = PQremove(pq))) {
162#ifdef DEBUG
163 fprintf (stderr, "process %d\n", n->index);
164#endif
165 N_VAL(n) *= -1;
166 if (n == to) break;
167 for (y=0; y<n->n_adj; y++) {
168 e = &g->edges[n->adj_edge_list[y]];
169 adjn = adjacentNode(g, e, n);
170 if (N_VAL(adjn) < 0) {
171 d = -(N_VAL(n) + E_WT(e));
172 if (N_VAL(adjn) == UNSEEN) {
173#ifdef DEBUG
174 fprintf (stderr, "new %d (%d)\n", adjn->index, -d);
175#endif
176 N_VAL(adjn) = d;
177 if (PQ_insert(pq, adjn)) return 1;
178 N_DAD(adjn) = n;
179 N_EDGE(adjn) = e;
180 }
181 else {
182 if (N_VAL(adjn) < d) {
183#ifdef DEBUG
184 fprintf (stderr, "adjust %d (%d)\n", adjn->index, -d);
185#endif
186 PQupdate(pq, adjn, d);
187 N_DAD(adjn) = n;
188 N_EDGE(adjn) = e;
189 }
190 }
191 }
192 }
193 }
194
195 return 0;
196}
197
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
static void * gv_alloc(size_t size)
Definition alloc.h:47
void PQinit(pq_t *pq)
Definition fPQ.c:42
snode * PQremove(pq_t *pq)
Definition fPQ.c:102
int PQ_insert(pq_t *pq, snode *np)
Definition fPQ.c:66
void PQupdate(pq_t *pq, snode *n, int d)
Definition fPQ.c:115
#define G
Definition gdefs.h:7
void free(void *)
node NULL
Definition grammar.y:181
#define N_DAD(n)
#define E_WT(e)
#define N_VAL(pq, n)
snode priority queue for shortPath in sgraph
#define N_EDGE(n)
Definition fPQ.h:24
void freeSGraph(sgraph *g)
Definition sgraph.c:99
static void addEdgeToNode(snode *np, int idx)
Definition sgraph.c:74
int shortPath(pq_t *pq, sgraph *g, snode *from, snode *to)
Definition sgraph.c:144
sedge * createSEdge(sgraph *g, snode *v1, snode *v2, double wt)
Definition sgraph.c:81
void gsave(sgraph *G)
Definition sgraph.c:20
snode * createSNode(sgraph *g)
Definition sgraph.c:65
void reset(sgraph *G)
Definition sgraph.c:30
static snode * adjacentNode(sgraph *g, sedge *e, snode *n)
Definition sgraph.c:136
#define UNSEEN
Definition sgraph.c:133
sgraph * createSGraph(size_t nnodes)
Definition sgraph.c:55
void initSEdges(sgraph *g, size_t maxdeg)
Definition sgraph.c:41
Definition heap.c:20
Definition sgraph.h:42
double weight
Definition sgraph.h:43
int cnt
Definition sgraph.h:44
int v2
Definition sgraph.h:48
int v1
Definition sgraph.h:48
int nedges
Definition sgraph.h:52
sedge * edges
Definition sgraph.h:55
int nnodes
Definition sgraph.h:52
snode * nodes
Definition sgraph.h:54
a node of search graph sgraph, is created as a border segment between two adjusted cells of type cell...
Definition sgraph.h:26
short n_adj
Definition sgraph.h:30
int index
Definition sgraph.h:38
int * adj_edge_list
edges incident on this node – stored as indices of the edges array in the graph
Definition sgraph.h:37