先决条件:冲突可串行化,优先图
冲突可序列化调度:如果调度可以通过交换非冲突操作转换为串行调度,则称为冲突可序列化。冲突序列化调度的串行调度可以通过在冲突序列化调度的优先图上应用拓扑排序来找到。
注意:冲突串行调度的优先级图始终是有向无环图。
方法:按照以下步骤找到优先图的拓扑排序:
- 找到给定优先图的所有节点的入度并将其存储在辅助数组中。
- 现在对于具有入度0的每个节点执行以下步骤:
- 打印当前节点T作为拓扑排序的顺序。
- 设节点T为入度为0的节点。
- 从图中删除T和所有连接到T的边。
- 完成上述步骤后更新所有节点的入度。
- 经过以上步骤,就可以计算出给定优先图的拓扑排序。
下面是上述方法的说明:
假设,冲突串行调度为S: R2(A) W2(A) R3(C) W2(B) W3(A) W3(C) R1(A) R2(B) W1(A) W2(B)
- 这里节点T2 的入度为0 。
- 因此,选择T2并删除T2和所有从它连接的边。
- 现在T3 的入度为0 。因此,选择T3并删除边T3→T1 。
- 最后选择T3 。所以拓扑排序是T2, T3, T1 。
- 因此,给定冲突可串行化调度的等效串行调度为T2→T3→T1 ,即S2: R2(A) W2(A) W2(B) R3(C) W3(A) W3(C) R1(A) R2(B) W1(A) W1(B) 。
冲突可串行化调度的等效串行调度可能不止一个。
下面是使用拓扑排序获取 CSS 串行调度的实现:
C++
// C++ program to print serial schedule
// of CSS using Topological sorting
#include
using namespace std;
class PrecedenceGraph {
// No. of vertices
int V;
// Pointer to an array containing
// adjacency vector
vector* adj;
// Vector to store SerialSchedule
vector serialSchedule;
// Function declarations
void computeIndegree(int* indegree);
int findZeroIndegree(int* indegree,
bool* visited);
public:
// Constructor
PrecedenceGraph(int V);
// Function declarations
void addEdge(int v, int w);
void topologicalSort();
void printSchedule();
};
// Function to create the precedence
// graph
PrecedenceGraph::PrecedenceGraph(int V)
{
this->V = V;
adj = new vector[V];
}
// Function to add the edge to the
// precedence graph
void PrecedenceGraph::addEdge(int v,
int w)
{
adj[v].push_back(w);
}
// Funciton to compute indegree of nodes
void PrecedenceGraph::computeIndegree(
int* indegree)
{
for (int i = 1; i < V; i++) {
// Traverse the adjacency list
// of node i
for (int j = 0;
j < adj[i].size(); j++) {
int node = adj[i][j];
// Update the indegree
// of node
indegree[node]++;
}
}
}
// Function to find node with
// zero indegree
int PrecedenceGraph::findZeroIndegree(
int* indegree, bool* visited)
{
for (int i = 1; i < V; i++) {
// If node is not visited
// and have indegree 0
if (!visited[i]
&& indegree[i] == 0) {
// Mark node visited
visited[i] = true;
// Return node
return i;
}
}
// All nodes are visited
return -1;
}
// Function to find the topological
// Sorting of the given graph
void PrecedenceGraph::topologicalSort()
{
// Create and initialize
// visited array
bool* visited = new bool[V]();
// Create and initialize
// indegree array
int* indegree = new int[V]();
computeIndegree(indegree);
// Check if the node with
// indegree 0 is available
int node = findZeroIndegree(
indegree, visited);
bool nodeAvailable = false;
if (node != -1) {
nodeAvailable = true;
}
while (nodeAvailable) {
// Add node to serial schedule
serialSchedule.push_back(node);
for (int i = 0;
i < adj[node].size(); i++) {
// Delete all edges of current
// node and update indegree
indegree[adj[node][i]]--;
}
// Find next node with indegree 0
node = findZeroIndegree(indegree,
visited);
if (node == -1) {
// Node with zero indegree
// not available
nodeAvailable = false;
}
}
}
// Function to print the serial schedule
void PrecedenceGraph::printSchedule()
{
for (int i : serialSchedule) {
cout << "T" << i << " ";
}
}
// Driver Code
int main()
{
// Create a precedence graph
// given in the above diagram
PrecedenceGraph graph(4);
graph.addEdge(2, 1);
graph.addEdge(2, 3);
graph.addEdge(3, 1);
// Find topological ordereing
graph.topologicalSort();
// Print Schedule
cout << "Equivalent Serial"
<< " Schedule is :";
graph.printSchedule();
}
输出:
Equivalent Serial Schedule is :T2 T3 T1
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。