kruse/ryba ch121 object oriented data structures graphs sets mathematical background computer...
TRANSCRIPT
Kruse/Ryba ch12 1
Object Oriented Data Structures
GraphsSets
Mathematical BackgroundComputer Representation
Graph TraversalTopological SortingGreedy Algorithms
Minimal Spanning Trees
Kruse/Ryba ch12 2
Set Definitions
Are values themselves maintained in the sets, or simply an indication of values?Are multiple instances of the same value allowed? If yes, data structure is sometimes called a bag.Can elements be ordered in relation to each other? If so, then often more efficient algorithms can be used.
A set is an unordered collection of values.
Various issues in the design of sets:
Kruse/Ryba ch12 4
Reuse Using Composition
The bit vector will simply hold a vector as one of its components.As with inheritance, much of the effort involved in the development of the class can be performed by the underlying class.
We will use the bit vector class to illustrate reuse by composition.
Kruse/Ryba ch12 5
Bit Vector Class (STL)
Used to represent sets of small integers.A sequence of 0/1 valuesPacked into a larger structure.
Kruse/Ryba ch12 6
template <int N> class bitset {public: bitset(): data((N+31)/32,0) {} bitset (bitset<N> & b) : data(b.data) {}
// bit level opeations void flip (); void flip (int index); void reset (); void reset (int index); void set (); void set (int index); bool test (int index);
// bit testing operations bool any (); bool none (); bool count ();
Kruse/Ryba ch12 7
// set operations void operator |= (biset<N> & rhs); void operator &= (biset<N> & rhs); void operator ^= (biset<N> & rhs); void operator == (biset<N> & rhs);
// other operations void operator << (int); void operator >> (int); string to_string ();
protected: vector<int> data; int indexValue (int index) {return index/32} int mask (int index) {return 1 << (index % 32);}
Kruse/Ryba ch12 8
Utility Function - byteNumber
Convert an index into the bit vector into and index in the character vector.
unsigned int bitVector::byteNumber(unsigned int index)const{ // return index of byte containing specified // value. byte number is index value divided by 8
return index >> 3; //shifting right is dividing
}
Kruse/Ryba ch12 9
bits 31-24 bits 23-16 bits 15-8 bits 7-0
byte # 3 2 1 0
Think of 13, which is 00001101
Shift right by 3 places, obtaining 00000001,
which is 1.
This tells us to look in cell 1
Kruse/Ryba ch12 10
The mask function
unsigned int bitVector::mask(unsigned int index)const{ // compute the amount to shift contained in the low // order 3 bits of the index const unsigned int shiftAmount = index & 07;
// make a mask by shifting the value one left by the // given amount. return 1 << shiftAmount;}
Kruse/Ryba ch12 11
bits 31-24 bits 23-16 bits 15-8 bits 7-0
byte # 3 2 1 0
Again, think of 13, which is 00001101
Low order three bits are 00000101, which is 5
Shift 1 left by 5 places, which yields 00100000
Kruse/Ryba ch12 12
bits 31-24 bits 23-16 bits 15-8 bits 7-0
byte # 3 2 1 0
Again, think of 13, which is 00001101
Low order three bits are 00000101, which is 5
Shift 1 left by 5 places, which yields 00100000
00100000
Kruse/Ryba ch12 13
Setting a Bit
To set a bit, the logical or operation is used. By or'ing with a single one bit, only one location will be set.
data 10011001mask 00100000result 10111001
void bitvector::set(unsigned int indx){ // set the indicated bit data[indexValue(indx)] |= mask(indx);}
Kruse/Ryba ch12 14
Setting all bits to 1
template<int N> void bitset<N>::set() // meta set all values to 1{ int n = data.size(); for (int i = 0; i < n; i++) data[i] = ~0;}
Kruse/Ryba ch12 15
To Clear a Bit
To turn off a bit, the logical and operation is used with the inverse of the mask
data 10111001mask 00100000inverse 11011111result 10011001
void bitset::reset(unsigned int indx){ // clear the indicated bit data[indexValue(indx)] &= ~mask(indx);}
Kruse/Ryba ch12 16
Clear all bits
template <int N> void bitset<N>::reset() // reset all values to zero{ int n = data.size(); for(int i = 0; i < n; i++) data[i] = 0;}
Kruse/Ryba ch12 17
Testing a Bit
To test a bit, we and the data values with the given mask and see if the result is nonzero.
data 10011001mask 00100000result 00000000
int bitset<N>::test(unsigned int indx){ // test the indicated bit return 0 != (data[indexValue(indx)]& mask(indx));}
Kruse/Ryba ch12 18
Inverting a Bit
To invert a bit, we exclusive or the data values with the given mask.
data 10011001mask 00100000result 10111001
void bitset<N>::flip(int indx){ // test the indicated bit (data[indexValue(indx)] ^= mask(indx);}
Kruse/Ryba ch12 19
Inverting all bits
template <int N>void bitset<N>::flip() // flip all values{ int n = data.size(); for (int i = 0; i < n; i++) data[i] = ~data[i];}
Kruse/Ryba ch12 20
Union
100110010011100010111001
dataargument
result
void bitset<N>::operator |=(bitset<N> rhs){ // form the union of set with argument set // only works if both sets the same size const int n = data.size(); for(int i = 0; i < n; i++) data[i] |= rhs.data[i]; // bitwise or}
Kruse/Ryba ch12 21
Intersection100110010011100000011000
dataargument
result
void bitset::operator &=(bitset<N> & rhs){ // form the intersection of set with argument // set only works if both sets the same size int n = data.size(); for(int i = 0; i < n; i++) data[i] &= rhs.data[i]; // bitwise and}
Kruse/Ryba ch12 22
Difference 10011001001110001100011110000001
dataargument
inverse argumentresult
void bitset::operator -(bitset<T> & rhs){ // form the difference of set with argument // set only works if both sets the same size int ne = data.size(); for(int i = 0; i < n; i++) data[i] &= ~rhs.data[i]; // bitwise and}
Difference requires inverting the second argument.
Kruse/Ryba ch12 23
Set Equality
int bitset::operator == (bitset<N> & rhs){ // test to see if two sets are the same // only works if sets the same size // test to see if every position is equal to the argument int n = data.size(); for(int i = 0; i < n; i++) if(data[i] != rhs.data[i]) return 0; // all equal, sets the same return 1;}
Kruse/Ryba ch12 24
The Set Data Type (STL)
Stores actual values.Combination of container class and generic operations.
Kruse/Ryba ch12 25
Summary of Set & Multiset Operations
set<T> s;default constructor O(1)
multiset<T> m;default constructor O(1)
set<T> s(aSet);copy constructor O(n)
multiset<T> m(aMultiset)copy constructor O(n)
s = aSet O(n) s.swap(aSet) O(1)
Kruse/Ryba ch12 26
Insertion and Removal s.insert(value_type)
insert new element O(log n)
s.erase(value_type)remove all matching element O(log
n) s.erase(iterator)
remove element specified by iterator O(log n)
s.erase(iterator, iterator)remove range of values O(log
n)
Kruse/Ryba ch12 27
Testing for Inclusion
s.empty()true if collection is empty O(1)
s.size()number of elements in collection O( n)
s.count(value_type)count number of occurrences O(log n)
s.find(value_type)locate value O(log n)
Kruse/Ryba ch12 28
Testing for Inclusion
s.lower_bound(value_type)first occurrence of value O(log n)
s.upper_bound(value_type)next element after value O(log n)
s.equal_range(value_type)lower and upper bound pair O(log n)
Kruse/Ryba ch12 29
Iterators
set<T>::iterator itrdeclare new iterator O(1)
set.begin()starting iterator O(1)
set.end()stopping iterator O(1)
set.rbegin() O(1) set.rend() O(1)
Kruse/Ryba ch12 30
Special Iterators for Sets
set<int, less<int> > setA, setB, setC;
set_union(setA.begin(),setA.end(), setB.begin(),setB.end(), inserter(setC,setC.begin()));
Kruse/Ryba ch12 31
Simple Graphs
A simple graph G=(V,E) consists of V, a nonempty set of vertices, and E, a set of unordered pairs of distinct elements {v,w} of V called edges.
Kruse/Ryba ch12 32
Simple Graph Example
V={a,b,c,d,e,f,g}
ab
c
d
e
f
g
{a,c},
{c,b},
{b,d},
{d,e},
{e,g},{d,f},{f,g}
,{d,g} }
{{a,b},
Kruse/Ryba ch12 33
Directed Graph
A directed graph (V,E) consists of a set of vertices V and a set of edges E that are ordered pairs (v,w) of elements of V.
Kruse/Ryba ch12 34
Directed Graph Example
V={a,b,c,d,e,f,g}
ab
c
d
e
f
g
{(b,a),(b,c),(c,a),(c,b),(d,b),(d,e),(d,g),(d,f),(f,g), (g,d),(g,e), (g,f)}
Kruse/Ryba ch12 44
Adjacency Matrices
The adjacency matrix A [aij] for a graph G is
a ij
v Gj
0 o th erw ise
1 if v is an ed g e o f i
,
Kruse/Ryba ch12 45
ab
c
d
e
f
g
0 1 1 0 0 0 0
1 0 1 1 0 0 0
1 1 0 0 0 0 0
0 1 0 0 1 1 1
0 0 0 1 0 0 1
0 0 0 1 0 0 1
0 0 0 1 1 1 0
é
ë
êêêêêêêêê
ù
û
úúúúúúúúú
Kruse/Ryba ch12 48
template <int max_size>void Digraph<max_size>::depth_first(void (*visit)(Vertex &)) const/*Post: The function *visit has been performed at each vertex of the Digraph in depth- first order.Uses: Method traverse to produce the recursive depth-first order.*/{ bool visited[max_size]; Vertex v; for (all v in G) visited[v] = false; for (all v in G) if (!visited[v]) traverse(v, visited, visit);}
Kruse/Ryba ch12 49
template <int max_size>void Digraph<max_size>::traverse(Vertex &v, bool visited[], void (*visit)(Vertex &)) const
{ Vertex w; visited[v] = true; (*visit)(v); for (all w adjacent to v) if (!visited[w]) traverse(w, visited, visit);
}
Kruse/Ryba ch12 50
template <int max_size>void Digraph<max_size>::breadth_first(void (*visit)(Vertex &)) const{ Queue q; bool visited[max_size]; Vertex v, w, x; for (all v in G) visited[v] = false; for (all v in G) if (!visited[v]) { q.append(v); while (!q.empty()){ q.retrieve(w); if (!visited[w]) { visited[w] = true; (*visit)(w); for (all x adjacent to w) q.append(x); } q.serve(); } }}
Kruse/Ryba ch12 51
Topological Sorting
In a topological order, each vertex must appear before all the vertices that are its successors in the directed graph.
Kruse/Ryba ch12 52
0 1 2 3 4
5 6 7 8 9
If there is an edge from v to w, then v precedes w in the sequential listing.
Problem!!
9 6 3 4 8 2 0 5 1 7
Kruse/Ryba ch12 53
0 1 2 3 4
5 6 7 8 9
If there is an edge from v to w, then v precedes w in the sequential listing.
9 6 3 4 8 2 0 5 1 7
Kruse/Ryba ch12 54
template <int graph_size>void Digraph<graph_size>::depth_sort(List<Vertex> &topological_order)
{ bool visited[graph_size]; Vertex v; for (v = 0; v < count; v++) visited[v] = false;
topological_order.clear();
for (v = 0; v < count; v++) if (!visited[v]) recursive_depth_sort(v, visited, topological_order);
}
Kruse/Ryba ch12 55
template <int graph_size>void Digraph<graph_size>::recursive_depth_sort(Vertex v, bool *visited, List<Vertex> &topological_order){ visited[v] = true; int degree = neighbors[v].size(); for (int i = 0; i < degree; i++) { Vertex w; //A (neighboring) successor of v neighbors[v].retrieve(i, w); if (!visited[w]) //Order successors of w. recursive_depth_sort(w, visited, topological_order); } topological_order.insert(0, v);}
Kruse/Ryba ch12
Dijkstra's Algorithm
Discovers the shortest distance from a specific starting vertex to all other reachable nodes in a graph.
The input to the procedure is the starting node. The output is returned in a dictionary keyed by vertices and holding distance values.
Kruse/Ryba ch12 58
Minimal Spanning Trees
A spanning tree represents a set of paths that allows visiting any vertex in the graph.
A minimal spanning tree of a connected network is a spanning tree such that the sum of the weights of its edges is as small as possible.
Kruse/Ryba ch12 61
Prim's Algorithm
procedure Prim(G: weighted connected undirected graph with n vertices)
T:= a minimum-weight edgefor i:=1 to n-2begin e := an edge of minimum weight incident to a vertex in T and not forming a simple circuit in T if added to T T := T with e addedend { T is a minimum spanning tree of G }
Kruse/Ryba ch12 62
San Fran
Chicago
New York
Atlanta
Denver
$2000
$1200
$2200$900
$1000
$1400
$1600$1300
$700
$800
{Chicago,Atlanta} $700{Atlanta, New York} $800
{Chicago, San Fran} $1200
{San Fran, Denver} $900
Total $3600
Kruse/Ryba ch12 63
template <class Weight, int graph_size>class Network: public Digraph<Weight, graph_size>
{public: Network(); void read(); // method to enter a Network void make_empty(int size = 0); void add_edge(Vertex v, Vertex w, Weight x); void minimal_spanning(Vertex source, Network<Weight, graph_size> &tree) const;};
Prim's Algorithm Implementation
Kruse/Ryba ch12 64
template <class Weight, int graph_size>void Network<Weight, graph_size>::minimal_spanning(Vertex source, Network<Weight, graph_size> &tree) const{ tree.make_empty(count); bool component[graph_size]; // Vertices in set X Weight distance[graph_size]; // Distances of vertices adjacent to X Vertex neighbor[graph_size]; // Nearest neighbor in set X Vertex w;
for (w = 0; w < count; w++) { component[w] = false; distance[w] = adjacency[source][w]; neighbor[w] = source;
}
Kruse/Ryba ch12 65
component[source] = true; // source alone is in the set X. for (int i = 1; i < count; i++) { Vertex v; // Add one vertex v to X on each pass. Weight min = infinity; for (w = 0; w < count; w++) if (!component[w]) if (distance[w] < min) { v = w; min = distance[w]; } if (min < infinity) { component[v] = true; tree.add_edge(v, neighbor[v], distance[v]); for (w = 0; w < count; w++) if (!component[w]) if (adjacency[v][w] < distance[w]) { distance[w] = adjacency[v][w]; neighbor[w] = v; } } // finished component else break; // in disconnected graph }}