The Cuthill-Mckee algorithm is used for reordering of a symmetric square matrix. It is based on Breadth First Search algorithm of a graph, whose adjacency matrix is the sparsified version of the input square matrix.
The ordering is frequently used when a matrix is to be generated whose rows and columns are numbered according to the numbering of the nodes. By an appropriate renumbering of the nodes, it is often possible to produce a matrix with a much smaller bandwidth.
Sparsified version of a matrix is a matrix in which most of the elements are zero.
The Reverse Cuthill-Mckee Algorithm is the same as the Cuthill-Mckee algorithm, the only difference is that the final indices obtained using the Cuthill-Mckee algorithm are reversed in the Reverse Cuthill-Mckee Algorithm.
Below are the steps of Reverse Cuthill-Mckee algorithm:
- Instantiate an empty queue Q and empty array for permutation order of the objects R.
- S1: We first find the object with minimum degree whose index has not yet been added to R. Say, object corresponding to pth row has been identified as the object with a minimum degree. Add p to R.
- S2: As an index is added to R, and add all neighbors of the corresponding object at the index,
in increasing order of degree, to Q. The neighbors are nodes with non-zero value amongst the non-diagonal elements in the pth row.- S3: Extract the first node in Q, say C. If C has not been inserted in R, add it to R, add to Q the neighbors of C in increasing order of degree.
- S4: If Q is not empty, repeat S3.
- S5: If Q is empty, but there are objects in the matrix which have not been included in R, start from S1, once again. (This could happen if there are disjoint graphs)
- S6: Terminate this algorithm once all objects are included in R.
- S7: Finally, reverse the indices in R, i.e. (swap(R[i], R[P-i+1])).
Degree: Definition of a degree is not constant, it changes according to the dataset you are working with. For the example given below, the degree of a node is defined as the sum of non-diagonal elements in the corresponding row.
Generalized definition of the degree of a node ‘A’ is the number of nodes connected to ‘A’.
Example:
Given a symmetric matrix:
| 0.0 0.78 0.79 0.8 0.23 |
| 0.9 0.0 0.43 0.771 0.752 |
| 0.82 0.0 0.0 0.79 0.34 |
| 0.8 0.8 0.8 0.0 0.8 |
| 0.54 0.97 0.12 0.78 0.0 |
Degree here is defined as sum of non-diagonal
elements in the corresponding row.
Specification for a matrix is defined as,
if the element of the matrix at i, j has a value
less than 0.75 its made to 0 otherwise its made to 1.
Matrix after Specification:
Degree of node 0 = 2.6
Degree of node 1 = 2.803
Degree of node 2 = 2.55
Degree of node 3 = 3.2
Degree of node 4 = 2.41
Permutation order of objects (R) : 0 2 1 3 4
The new permutation order is just the ordering of the nodes, i.e. convert node ‘R[i]’ to node ‘i’.
Therefore, convert node ‘R[0] = 0’, to 0; node ‘R[1] = 2’, to 1; node ‘R[2] = 1’, to 2; node ‘R[3] = 3’, to 3; and node ‘R[4] = 4’, to 4;
Let’s take a bigger example to understand the result of the reordering:
Give a adjacency matrix :
| 0 1 0 0 0 0 1 0 1 0 |
| 1 0 0 0 1 0 1 0 0 1 |
| 0 0 0 0 1 0 1 0 0 0 |
| 0 0 0 0 1 1 0 0 1 0 |
| 0 1 1 1 0 1 0 0 0 1 |
| 0 0 0 1 1 0 0 0 0 0 |
| 1 1 1 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 0 1 1 |
| 1 0 0 1 0 0 0 1 0 0 |
| 0 1 0 0 1 0 0 1 0 0 |
Degree of node 'A' is defined as number of
nodes connected to 'A'
Output :
Permutation order of objects (R) :
7 8 9 3 5 1 0 4 6 2
Now convert node ‘R[i]’ to node ‘i’
So the graph becomes:
The result of reordering can be seen by the adjacency matrix of the two graph:
From here we can clearly see that how the Cuthill-Mckee algorithm helps in the reordering of a square matrix into a non-distributed matrix.
Below is the implementation of the above algorithm. Taking the general definition of degree.
C++
// C++ program for Implementation of // Reverse Cuthill Mckee Algorithm #include <bits/stdc++.h> using namespace std; vector< double > globalDegree; int findIndex(vector<pair< int , double > > a, int x) { for ( int i = 0; i < a.size(); i++) if (a[i].first == x) return i; return -1; } bool compareDegree( int i, int j) { return ::globalDegree[i] < ::globalDegree[j]; } template < typename T> ostream& operator<<(ostream& out, vector<T> const & v) { for ( int i = 0; i < v.size(); i++) out << v[i] << ' ' ; return out; } class ReorderingSSM { private : vector<vector< double > > _matrix; public : // Constructor and Destructor ReorderingSSM(vector<vector< double > > m) { _matrix = m; } ReorderingSSM() {} ~ReorderingSSM() {} // class methods // Function to generate degree of all the nodes vector< double > degreeGenerator() { vector< double > degrees; for ( int i = 0; i < _matrix.size(); i++) { double count = 0; for ( int j = 0; j < _matrix[0].size(); j++) { count += _matrix[i][j]; } degrees.push_back(count); } return degrees; } // Implementation of Cuthill-Mckee algorithm vector< int > CuthillMckee() { vector< double > degrees = degreeGenerator(); ::globalDegree = degrees; queue< int > Q; vector< int > R; vector<pair< int , double > > notVisited; for ( int i = 0; i < degrees.size(); i++) notVisited.push_back(make_pair(i, degrees[i])); // Vector notVisited helps in running BFS // even when there are dijoind graphs while (notVisited.size()) { int minNodeIndex = 0; for ( int i = 0; i < notVisited.size(); i++) if (notVisited[i].second < notVisited[minNodeIndex].second) minNodeIndex = i; Q.push(notVisited[minNodeIndex].first); notVisited.erase(notVisited.begin() + findIndex(notVisited, notVisited[Q.front()].first)); // Simple BFS while (!Q.empty()) { vector< int > toSort; for ( int i = 0; i < _matrix[0].size(); i++) { if (i != Q.front() && _matrix[Q.front()][i] == 1 && findIndex(notVisited, i) != -1) { toSort.push_back(i); notVisited.erase(notVisited.begin() + findIndex(notVisited, i)); } } sort(toSort.begin(), toSort.end(), compareDegree); for ( int i = 0; i < toSort.size(); i++) Q.push(toSort[i]); R.push_back(Q.front()); Q.pop(); } } return R; } // Implementation of reverse Cuthill-Mckee algorithm vector< int > ReverseCuthillMckee() { vector< int > cuthill = CuthillMckee(); int n = cuthill.size(); if (n % 2 == 0) n -= 1; n = n / 2; for ( int i = 0; i <= n; i++) { int j = cuthill[cuthill.size() - 1 - i]; cuthill[cuthill.size() - 1 - i] = cuthill[i]; cuthill[i] = j; } return cuthill; } }; // Driver Code int main() { int num_rows = 10; vector<vector< double > > matrix; for ( int i = 0; i < num_rows; i++) { vector< double > datai; for ( int j = 0; j < num_rows; j++) datai.push_back(0.0); matrix.push_back(datai); } // This is the test graph, // check out the above graph photo matrix[0] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0 }; matrix[1] = { 1, 0, 0, 0, 1, 0, 1, 0, 0, 1 }; matrix[2] = { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0 }; matrix[3] = { 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 }; matrix[4] = { 0, 1, 1, 1, 0, 1, 0, 0, 0, 1 }; matrix[5] = { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 }; matrix[6] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; matrix[7] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; matrix[8] = { 1, 0, 0, 1, 0, 0, 0, 1, 0, 0 }; matrix[9] = { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 }; ReorderingSSM m(matrix); vector< int > r = m.ReverseCuthillMckee(); cout << "Permutation order of objects: " << r << endl; return 0; } |
Java
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.stream.Collectors; public class ReorderingSSM { private List<List<Double>> matrix; public ReorderingSSM(List<List<Double>> m) { matrix = m; } public ReorderingSSM() { } // Function to generate degree of all the nodes private List<Double> DegreeGenerator() { List<Double> degrees = new ArrayList<>(); for ( int i = 0 ; i < matrix.size(); i++) { double count = 0 ; for ( int j = 0 ; j < matrix.get( 0 ).size(); j++) { count += matrix.get(i).get(j); } degrees.add(count); } return degrees; } // Implementation of Cuthill-Mckee algorithm private List<Integer> CuthillMckee() { List<Double> degrees = DegreeGenerator(); List<Double> globalDegree = new ArrayList<>(degrees); Queue<Integer> Q = new LinkedList<>(); List<Integer> R = new ArrayList<>(); List<Pair<Integer, Double>> notVisited = new ArrayList<>(); for ( int i = 0 ; i < degrees.size(); i++) notVisited.add( new Pair<>(i, degrees.get(i))); // Vector notVisited helps in running BFS // even when there are disjoint graphs while (!notVisited.isEmpty()) { int minNodeIndex = 0 ; for ( int i = 0 ; i < notVisited.size(); i++) { if (notVisited.get(i).getValue() < notVisited.get(minNodeIndex).getValue()) minNodeIndex = i; } Q.add(notVisited.get(minNodeIndex).getKey()); notVisited.remove(FindIndex(notVisited, notVisited.get(Q.peek()).getKey())); // Simple BFS while (!Q.isEmpty()) { List<Integer> toSort = new ArrayList<>(); for ( int i = 0 ; i < matrix.get( 0 ).size(); i++) { if (i != Q.peek() && matrix.get(Q.peek()).get(i) == 1 && FindIndex(notVisited, i) != - 1 ) { toSort.add(i); notVisited.remove(FindIndex(notVisited, i)); } } toSort.sort(Comparator.comparingDouble(globalDegree::get)); Q.addAll(toSort); R.add(Q.peek()); Q.poll(); } } return R; } // Implementation of reverse Cuthill-Mckee algorithm private List<Integer> ReverseCuthillMckee() { List<Integer> cuthill = CuthillMckee(); int n = cuthill.size(); if (n % 2 == 0 ) n -= 1 ; n = n / 2 ; for ( int i = 0 ; i <= n; i++) { int j = cuthill.get(cuthill.size() - 1 - i); cuthill.set(cuthill.size() - 1 - i, cuthill.get(i)); cuthill.set(i, j); } return cuthill; } // Helper function to find index of an element in a list of pairs private int FindIndex(List<Pair<Integer, Double>> a, int x) { for ( int i = 0 ; i < a.size(); i++) { if (a.get(i).getKey() == x) return i; } return - 1 ; } // Helper function to print a list private <T> void PrintList(List<T> list) { System.out.println(list.stream().map(Object::toString).collect(Collectors.joining( " " ))); } // Driver Code public static void main(String[] args) { int num_rows = 10 ; List<List<Double>> matrix = new ArrayList<>(); for ( int i = 0 ; i < num_rows; i++) { List<Double> datai = new ArrayList<>(); for ( int j = 0 ; j < num_rows; j++) datai.add( 0.0 ); matrix.add(datai); } // This is the test graph, // check out the above graph photo matrix.set( 0 , List.of( 0.0 , 1.0 , 0.0 , 0.0 , 0.0 , 0.0 , 1.0 , 0.0 , 1.0 , 0.0 )); matrix.set( 1 , List.of( 1.0 , 0.0 , 0.0 , 0.0 , 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , 1.0 )); matrix.set( 2 , List.of( 0.0 , 0.0 , 0.0 , 0.0 , 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , 0.0 )); matrix.set( 3 , List.of( 0.0 , 0.0 , 0.0 , 0.0 , 1.0 , 1.0 , 0.0 , 0.0 , 1.0 , 0.0 )); matrix.set( 4 , List.of( 0.0 , 1.0 , 1.0 , 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , 0.0 , 1.0 )); matrix.set( 5 , List.of( 0.0 , 0.0 , 0.0 , 1.0 , 1.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 )); matrix.set( 6 , List.of( 1.0 , 1.0 , 1.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 )); matrix.set( 7 , List.of( 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 1.0 , 1.0 )); matrix.set( 8 , List.of( 1.0 , 0.0 , 0.0 , 1.0 , 0.0 , 0.0 , 0.0 , 1.0 , 0.0 , 0.0 )); matrix.set( 9 , List.of( 0.0 , 1.0 , 0.0 , 0.0 , 1.0 , 0.0 , 0.0 , 1.0 , 0.0 , 0.0 )); ReorderingSSM m = new ReorderingSSM(matrix); List<Integer> r = m.ReverseCuthillMckee(); System.out.println( "Permutation order of objects: " ); m.PrintList(r); } } class Pair<K, V> { private final K key; private final V value; public Pair(K key, V value) { this .key = key; this .value = value; } public K getKey() { return key; } public V getValue() { return value; } } |
Python3
# C++ program for Implementation of # Reverse Cuthill Mckee Algorithm from collections import deque as Queue globalDegree = [] def findIndex(a, x): for i in range ( len (a)): if a[i][ 0 ] = = x: return i return - 1 class ReorderingSSM: __matrix = [] # Constructor and Destructor def __init__( self , m): self .__matrix = m # class methods # Function to generate degree of all the nodes def degreeGenerator( self ): degrees = [] for i in range ( len ( self .__matrix)): count = 0 for j in range ( len ( self .__matrix[ 0 ])): count + = self .__matrix[i][j] degrees.append(count) return degrees # Implementation of Cuthill-Mckee algorithm def CuthillMckee( self ): global globalDegree degrees = self .degreeGenerator() globalDegree = degrees Q = Queue() R = [] notVisited = [] for i in range ( len (degrees)): notVisited.append((i, degrees[i])) # Vector notVisited helps in running BFS # even when there are dijoind graphs while len (notVisited): minNodeIndex = 0 for i in range ( len (notVisited)): if notVisited[i][ 1 ] < notVisited[minNodeIndex][ 1 ]: minNodeIndex = i Q.append(notVisited[minNodeIndex][ 0 ]) notVisited.pop(findIndex(notVisited, notVisited[Q[ 0 ]][ 0 ])) # Simple BFS while Q: toSort = [] for i in range ( len ( self .__matrix[ 0 ])): if ( i ! = Q[ 0 ] and self .__matrix[Q[ 0 ]][i] = = 1 and findIndex(notVisited, i) ! = - 1 ): toSort.append(i) notVisited.pop(findIndex(notVisited, i)) toSort.sort(key = lambda x: globalDegree[x]) for i in range ( len (toSort)): Q.append(toSort[i]) R.append(Q[ 0 ]) Q.popleft() return R # Implementation of reverse Cuthill-Mckee algorithm def ReverseCuthillMckee( self ): cuthill = self .CuthillMckee() n = len (cuthill) if n % 2 = = 0 : n - = 1 n = n / / 2 for i in range (n + 1 ): j = cuthill[ len (cuthill) - 1 - i] cuthill[ len (cuthill) - 1 - i] = cuthill[i] cuthill[i] = j return cuthill # Driver Code if __name__ = = "__main__" : num_rows = 10 matrix = [[ 0.0 ] * num_rows for _ in range (num_rows)] # This is the test graph, # check out the above graph photo matrix[ 0 ] = [ 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 ] matrix[ 1 ] = [ 1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 1 ] matrix[ 2 ] = [ 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 ] matrix[ 3 ] = [ 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 0 ] matrix[ 4 ] = [ 0 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 1 ] matrix[ 5 ] = [ 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 ] matrix[ 6 ] = [ 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] matrix[ 7 ] = [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 ] matrix[ 8 ] = [ 1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 ] matrix[ 9 ] = [ 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 ] m = ReorderingSSM(matrix) r = m.ReverseCuthillMckee() print ( "Permutation order of objects:" , r) |
C#
using System; using System.Collections.Generic; using System.Linq; class ReorderingSSM { private List<List< double >> matrix; public ReorderingSSM(List<List< double >> m) { matrix = m; } public ReorderingSSM() { } ~ReorderingSSM() { } // Function to generate degree of all the nodes private List< double > DegreeGenerator() { List< double > degrees = new List< double >(); for ( int i = 0; i < matrix.Count; i++) { double count = 0; for ( int j = 0; j < matrix[0].Count; j++) { count += matrix[i][j]; } degrees.Add(count); } return degrees; } // Implementation of Cuthill-Mckee algorithm private List< int > CuthillMckee() { List< double > degrees = DegreeGenerator(); List< double > globalDegree = degrees; Queue< int > Q = new Queue< int >(); List< int > R = new List< int >(); List<Tuple< int , double >> notVisited = new List<Tuple< int , double >>(); for ( int i = 0; i < degrees.Count; i++) notVisited.Add( new Tuple< int , double >(i, degrees[i])); // Vector notVisited helps in running BFS // even when there are disjoint graphs while (notVisited.Count > 0) { int minNodeIndex = 0; for ( int i = 0; i < notVisited.Count; i++) { if (notVisited[i].Item2 < notVisited[minNodeIndex].Item2) minNodeIndex = i; } Q.Enqueue(notVisited[minNodeIndex].Item1); notVisited.RemoveAt(FindIndex(notVisited, notVisited[Q.Peek()].Item1)); // Simple BFS while (Q.Count > 0) { List< int > toSort = new List< int >(); for ( int i = 0; i < matrix[0].Count; i++) { if (i != Q.Peek() && matrix[Q.Peek()][i] == 1 && FindIndex(notVisited, i) != -1) { toSort.Add(i); notVisited.RemoveAt(FindIndex(notVisited, i)); } } toSort.Sort((x, y) => globalDegree[x].CompareTo(globalDegree[y])); foreach ( int item in toSort) Q.Enqueue(item); R.Add(Q.Peek()); Q.Dequeue(); } } return R; } // Implementation of reverse Cuthill-Mckee algorithm private List< int > ReverseCuthillMckee() { List< int > cuthill = CuthillMckee(); int n = cuthill.Count; if (n % 2 == 0) n -= 1; n = n / 2; for ( int i = 0; i <= n; i++) { int j = cuthill[cuthill.Count - 1 - i]; cuthill[cuthill.Count - 1 - i] = cuthill[i]; cuthill[i] = j; } return cuthill; } // Helper function to find index of an element in a list of tuples private int FindIndex(List<Tuple< int , double >> a, int x) { for ( int i = 0; i < a.Count; i++) { if (a[i].Item1 == x) return i; } return -1; } // Helper function to print a list private void PrintList<T>(List<T> list) { Console.WriteLine( string .Join( " " , list)); } // Driver Code static void Main( string [] args) { int num_rows = 10; List<List< double >> matrix = new List<List< double >>(); for ( int i = 0; i < num_rows; i++) { List< double > datai = new List< double >(); for ( int j = 0; j < num_rows; j++) datai.Add(0.0); matrix.Add(datai); } // This is the test graph, // check out the above graph photo matrix[0] = new List< double > { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0 }; matrix[1] = new List< double > { 1, 0, 0, 0, 1, 0, 1, 0, 0, 1 }; matrix[2] = new List< double > { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0 }; matrix[3] = new List< double > { 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 }; matrix[4] = new List< double > { 0, 1, 1, 1, 0, 1, 0, 0, 0, 1 }; matrix[5] = new List< double > { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 }; matrix[6] = new List< double > { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; matrix[7] = new List< double > { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; matrix[8] = new List< double > { 1, 0, 0, 1, 0, 0, 0, 1, 0, 0 }; matrix[9] = new List< double > { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 }; ReorderingSSM m = new ReorderingSSM(matrix); List< int > r = m.ReverseCuthillMckee(); Console.WriteLine( "Permutation order of objects: " ); m.PrintList(r); } } |
Javascript
// JavaScript program for the above approach class Queue { constructor() { this .items = []; } enqueue(element) { this .items.push(element); } dequeue() { if ( this .isEmpty()) return "Underflow" ; return this .items.shift(); } isEmpty() { return this .items.length == 0; } } function findIndex(a, x) { for (let i = 0; i < a.length; i++) { if (a[i][0] == x) { return i; } } return -1; } let globalDegree = []; class ReorderingSSM { // Constructor and Destructor constructor(m) { this .__matrix = m; } // class methods // Function to generate degree of all the nodes degreeGenerator() { let degrees = []; for (let i = 0; i < this .__matrix.length; i++) { let count = 0; for (let j = 0; j < this .__matrix[0].length; j++) { count += this .__matrix[i][j]; } degrees.push(count); } return degrees; } // Implementation of Cuthill-Mckee algorithm CuthillMckee() { let degrees = this .degreeGenerator(); globalDegree = degrees; let Q = new Queue(); let R = []; let notVisited = []; for (let i = 0; i < degrees.length; i++) { notVisited.push([i, degrees[i]]); } // Vector notVisited helps in running BFS // even when there are dijoind graphs while (notVisited.length > 0) { let minNodeIndex = 0; for (let i = 0; i < notVisited.length; i++) { if (notVisited[i][1] < notVisited[minNodeIndex][1]) { minNodeIndex = i; } } Q.enqueue(notVisited[minNodeIndex][0]); notVisited.splice(findIndex(notVisited, notVisited[Q.items[0]][0]), 1); // Simple BFS while (!Q.isEmpty()) { let toSort = []; for (let i = 0; i < this .__matrix[0].length; i++) { if ( i != Q.items[0] && this .__matrix[Q.items[0]][i] == 1 && findIndex(notVisited, i) != -1 ) { toSort.push(i); notVisited.splice(findIndex(notVisited, i), 1); } } toSort.sort((a, b) => globalDegree[a] - globalDegree[b]); for (let i = 0; i < toSort.length; i++) { Q.enqueue(toSort[i]); } R.push(Q.items[0]); Q.dequeue(); } } return R; } // Implementation of reverse Cuthill-Mckee algorithm ReverseCuthillMckee() { let cuthill = this .CuthillMckee(); let n = cuthill.length; if (n % 2 == 0) { n -= 1; } n = Math.floor(n / 2); for (let i = 0; i < n + 1; i++) { let j = cuthill[cuthill.length - 1 - i]; cuthill[cuthill.length - 1 - i] = cuthill[i]; cuthill[i] = j; } return cuthill; } } // Driver code let num_rows = 10; let matrix = Array(num_rows) .fill() .map(() => Array(num_rows).fill(0)); // This is the test graph, // check out the above matrix[0] = [0, 1, 0, 0, 0, 0, 1, 0, 1, 0] matrix[1] = [1, 0, 0, 0, 1, 0, 1, 0, 0, 1] matrix[2] = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0] matrix[3] = [0, 0, 0, 0, 1, 1, 0, 0, 1, 0] matrix[4] = [0, 1, 1, 1, 0, 1, 0, 0, 0, 1] matrix[5] = [0, 0, 0, 1, 1, 0, 0, 0, 0, 0] matrix[6] = [1, 1, 1, 0, 0, 0, 0, 0, 0, 0] matrix[7] = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1] matrix[8] = [1, 0, 0, 1, 0, 0, 0, 1, 0, 0] matrix[9] = [0, 1, 0, 0, 1, 0, 0, 1, 0, 0] const m = new ReorderingSSM(matrix) const r = m.ReverseCuthillMckee() console.log( "Permutation order of objects:" , r) // This code is contributed by Prince Kumar |
Permutation order of objects: 7 8 9 3 5 1 0 4 6 2
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!