240 likes | 366 Views
CSE 30331 Lectures 18 – Graphs. Graphs & Characteristics Graph Representations A Representation in C++ (Ford & Topp). What is a graph?. Formally, a graph G(V,E) is A set of vertices V A set of edges E, such that each edge e i,j connects two vertices v i and v j in V V and E may be empty.
E N D
CSE 30331Lectures 18 – Graphs • Graphs & Characteristics • Graph Representations • A Representation in C++ (Ford & Topp)
What is a graph? • Formally, a graph G(V,E) is • A set of vertices V • A set of edges E, such that each edge ei,j connects two vertices vi and vj in V • V and E may be empty
Graph Categories • A graph is connected if each pair of vertices have a path between them • A complete graph is a connected graph in which each pair of vertices are linked by an edge
Example of Digraph • Graphs with ordered edges are called directed graphs or digraphs
B A B A C E C D E D Not Strongly or Weakly Connected Strongly Connected (No path E to D or D to E ) (b) (a) Strength of Connectedness (digraphs only) • Strongly connected if there is a path from each • vertex to every other vertex.
A B A B E D C C D Not Strongly or Weakly Connected Weakly Connected (No path E to D or D to E ) (No path from D to a vertex) (a) ( c) Strength of Connectedness (digraphs only) • Weakly connected if, for each pair of vertices vi and vj, there is either a path P(vi, vj) or a path P(vi, vj).
Representing Graphs • Adjacency Matrix • Edges are represented in a 2-D matrix • Adjacency Set (or Adjacency List) • Each vertex has an associated set or list of edges leaving • Edge List • The entire edge set for the graph is in one list • Mentioned in discrete math (probably)
A B E C D Adjacency Matrix • An m x m matrix, called an adjacency matrix, identifies graph edges. • An entry in row i and column j corresponds to the edge e = (vi, vj). Its value is the weight of the edge, or -1 if the edge does not exist.
Vertices Set of Neighbors A C 1 B 1 (a) A B C 1 B C E B 1 D 1 C D D E B 1 Adjacency Set (or List) • An adjacency set or adjacency list represents the edges in a graph by using … • An m element map or vector of vertices • Where each vertex has a set or list of neighbors • Each neighbor is at the end of an out edge with a given weight
4 B A 2 3 7 C 6 1 2 E 4 D Set of Neighbors Vertices A B 4 C 7 D 6 4 B A 2 A 2 B 3 7 B 3 E 2 C C 6 1 2 D E 4 E 4 D E C 1 Adjacency Matrix and Adjacency Set (side-by-side)
Building a graph class • Neighbor • Identifies adjacent vertex and edge weight • VertexInfo • Contains all characteristics of a given vertex, either directly or through links • VertexMap • Contains names of vertices and links to the associated VertexInfo objects
vertexInfo Object • A vertexInfo object consists of seven data members. • The first two members, called vtxMapLoc and edges, identify the vertex in the map and its adjacency set.
vertexInfo object • vtxMapLoc – iterator to vertex (name) in map • edges – set of vInfo index / edge weight pairs • Each is an OUT edge to an adjacent vertex • vInfo[index] is vertexInfo object for adjacent vertex • inDegree – # of edges coming into this vertex • outDegree is simply edges.size() • occupied – true (this vertex is in the graph), false (this vertex was removed from graph) • color – (white, gray, black) status of vertex during search • dataValue – value computed during search (distance from start, etc) • parent – parent vertex in tree generated by search
A Neighbor class (edges to adjacent vertices) class neighbor { public: int dest; // index of destination vertex in vInfo vector int weight; // weight of this edge // constructor neighbor(int d=0, int c=0) : dest(d), weight(c) {} // operators to compare destination vertices friend bool operator<(const neighbor& lhs, const neighbor& rhs) { return lhs.dest < rhs.dest; } friend bool operator==(const neighbor& lhs, const neighbor& rhs) { return lhs.dest == rhs.dest; } };
vertexInfo object (items in vInfo vector) template <typename T> class vertexInfo { public: enum vertexColor { WHITE, GRAY, BLACK }; map<T,int>::iterator vtxMapLoc; // to pair<T,int> in map set<neighbor> edges; // edges to adjacent vertices int inDegree; // # of edges coming into vertex bool occupied; // currently used by vertex or not vertexColor color; // vertex status during search int dataValue; // relevant data values during search int parent; // parent in tree built by search // default constructor vertexInfo(): inDegree(0), occupied(true) {} // constructor with iterator pointing to vertex in map vertexInfo(map<T,int>::iterator iter) : vtxMapLoc(iter), inDegree(0), occupied(true) {} };
vtxMapLoc edges inDegree occupied color mIter dataValue vertex index (iterator parent location) . . . index vtxMap vInfo A graph using a vertexMap and vertexInfo vector • Graph vertices are stored in a map<T,int>, called vtxMap • Each entry is a <vertex name, vertexInfo index> key, value pair • The initial size of the vertexInfo vector is the number of vertices in the graph • There is a 1-1 correspondence between an entry in the map and a vertexInfo entry in the vector
A graph class (just the private members) private: typedef map<T,int> vertexMap; vertexMap vtxMap; // store vertex in a map with its name as the key // and the index of the corresponding vertexInfo // object in the vInfo vector as the value vector<vertexInfo<T> > vInfo; // list of vertexInfo objects for the vertices int numVertices; int numEdges; // current size (vertices and edges) of the graph stack<int> availStack; // availability stack, stores unused vInfo indices
A B C D VtxMap and Vinfo Example
Find the location for vertexInfo of vertex with name v // uses vtxMap to obtain the index of v in vInfo. // this is a private helper function template <typename T> int graph<T>::getvInfoIndex(const T& v) const { vertexMap::const_iterator iter; int pos; // find the vertex : the map entry with key v iter = vtxMap.find(v); if (iter == vtxMap.end()) pos = -1; // wasn’t in the map else pos = (*iter).second; // the index into vInfo return pos; }
Find in and out degree of v // return the number of edges entering v template <typename T> int graph<T>::inDegree(const T& v) const { int pos=getvInfoIndex(v); if (pos != -1) return vInfo[pos].inDegree; else throw graphError("graph inDegree(): v not in the graph"); } // return the number of edges leaving v template <typename T> int graph<T>::outDegree(const T& v) const { int pos=getvInfoIndex(v); if (pos != -1) return vInfo[pos].edges.size(); else throw graphError("graph outDegree(): v not in the graph"); }
Insert a vertex into graph template <typename T> void graph<T>::insertVertex(const T& v) { int index; // attempt insertion, set vInfo index to 0 for now pair<vertexMap::iterator, bool> result = vtxMap.insert(vertexMap::value_type(v,0)); if (result.second) { // insertion into map succeeded if (!availStack.empty()) { // there is an available index index = availStack.top(); availStack.pop(); vInfo[index] = vertexInfo<T>(result.first); } else { // vInfo is full, increase its size vInfo.push_back(vertexInfo<T>(result.first)); index = numVertices; } (*result.first).second = index; // set map value to index numVertices++; // update size info } else throw graphError("graph insertVertex(): v in graph"); }
Insert an edge into graph // add the edge (v1,v2) with specified weight to the graph template <typename T> void graph<T>::insertEdge(const T& v1, const T& v2, int w) { int pos1=getvInfoIndex(v1), pos2=getvInfoIndex(v2); if (pos1 == -1 || pos2 == -1) throw graphError("graph insertEdge(): v not in the graph"); else if (pos1 == pos2) throw graphError("graph insertEdge(): loops not allowed"); // insert edge (pos2,w) into edge set of vertex pos1 pair<set<neighbor>::iterator, bool> result = vInfo[pos1].edges.insert(neighbor(pos2,w)); if (result.second) // it wasn’t already there { // update counts numEdges++; vInfo[pos2].inDegree++; } }
Erase an edge from graph // erase edge (v1,v2) from the graph template <typename T> void graph<T>::eraseEdge(const T& v1, const T& v2) { int pos1=getvInfoIndex(v1), pos2=getvInfoIndex(v2); if (pos1 == -1 || pos2 == -1) throw graphError("graph eraseEdge(): v not in the graph"); // find the edge to pos2 in the list of pos1 neighbors set<neighbor>::iterator setIter; setIter = vInfo[pos1].edges.find(neighbor(pos2)); if (setIter != edgeSet.end()) { // found edge in set, so remove it & update counts vInfo[pos1].edges.erase(setIter); vInfo[pos2].inDegree--; numEdges--; } else throw graphError("graph eraseEdge(): edge not in graph"); }
Erase a vertex from graph(algorithm) • Find index of vertex v in vInfo vector • Remove vertex v from map • Set vInfo[index].occupied to false • Push index onto availableStack • For every occupied vertex in vInfo • Scan neighbor set for edge pointing back to v • If edge found, erase it • For each neighbor of v, • decrease its inDegree by 1 • Erase the edge set for vInfo[index]