У меня есть эта функция для вычисления класса эквивалентности
let eq_class m i =
let column = m.(i)
and set = ref [] in
Array.iteri begin fun j l ->
if j = i || column.(j) && m.(j).(i) then
set := j :: !set else ignore l
end column;
!set;;
и эта функция для сбора всех классов эквивалентна
let eq_classes m =
let classes = ref [] in
Array.iteri begin fun e _ ->
if not (List.exists (List.mem e) !classes) then
classes := eq_class m e :: !classes
end m;
!classes;;
У меня есть эта функция для сравнения двух классов эквивалентности:
let cmp_classes m c c' = if c = c' then 0 else
match c, c' with
| i :: _, j :: _ -> if m.(i).(j) then 1 else -1
| _ -> assert false
После того, как я использовал эту функцию, чтобы отсортировать ее с помощью List.sort
let sort_eq_classes m = List.sort (cmp_classes m);;
Моя матрица является булевой матрицей, и я рассчитал ее с помощью транзитивного замыкания.
let transClosure m =
let n = Array.length m in
for k = 0 to n - 1 do
let mk = m.(k) in
for i = 0 to n - 1 do
let mi = m.(i) in
for j = 0 to n - 1 do
mi.(j) <- max mi.(j) (min mi.(k) mk.(j))
done;
done;
done;
m;;
let tc = transClosure matrix
let eq = eq_classes tc
let sort_eq = sort_eq_classes tc eq
Я протестировал множество примеров счетчиков, чтобы протестировать все эти функции, например, с графиком (матрицей)
EDIT
матрица:
a <-> b c <-> d
|
v
e
matrix_2:
a <-> b -> e -> f
| |
v v
h <------- g
| |
v v
u k
Я ввожу логическую матрицу:
let matrix =
[|
[|false; true; false; false; false|];
[|true; false; false; false; false|];
[|false; false; false; true; false|];
[|false; false; true; false; false|];
[|false; false; false; false; false|];
|];;
let matrix_2 =
[|
[| false; false; false; false; false; false; false; false |];
[| false; false; false; false; false; false; false; false |];
[| false; false; false; true; false; false; true; false |];
[| false; false; true; false; true; false; false; false |];
[| true; false; false; false; false; true; false; false |];
[| false; true; false; false; false; false; true; false |];
[| false; false; false; false; false; false; false; true |];
[| false; false; false; false; false; false; false; false |];
|]
вывод матрицы 1:
классы эквивалентности: e d c b a
классы эквивалентности сортировки: e d c b a
вывод матрицы 2:
классы эквивалентности: u h g e b a k f
Классы эквивалентности сортировки: u h k g f e b a
И результат в правильном порядке, как я ожидал. Но когда я проверяю это с моими данными, которые являются данными xsds, возникают более сложные зависимые отношения. Это выводит для меня неправильный порядок. У меня был тест с функцией преобразования в булеву матрицу из xsds, и я тестировал транзитивное замыкание, это правильно. Так что я думаю, что их ошибки в моих функциях (eq_class
) или (cmp_classes
).
Не могли бы вы помочь мне увидеть, что не так в этом коде?