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() {
}
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;
}
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)));
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()));
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;
}
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;
}
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
;
}
private
<T>
void
PrintList(List<T> list) {
System.out.println(list.stream().map(Object::toString).collect(Collectors.joining(
" "
)));
}
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);
}
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;
}
}