先决条件:冲突可序列化,优先级图
冲突可序列化时间表:如果可以通过交换非冲突操作将其转换为串行时间表,则该时间表称为冲突可序列化时间表。可以通过在“冲突可序列化时间表”的优先级图上应用拓扑排序来找到“冲突可序列化时间表”的序列表。
注意:冲突序列计划的优先级图始终是有向无环图。
方法:按照以下步骤查找优先级图的拓扑排序:
- 查找给定优先级图的所有节点的度数并将其存储在辅助数组中。
- 现在,对于每个度数为0的节点,请执行以下操作:
- 将当前节点T打印为拓扑排序的顺序。
- 令节点T为度数为0的节点。
- 从图中删除T以及所有与T相连的边。
- 完成上述步骤后,更新所有节点的in度。
- 完成上述步骤后,可以计算给定优先级图的拓扑排序。
下面是上述方法的说明:
设冲突序列表为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)