Ocaml 比较两个等价类
我有一个简单的图表:Ocaml 比较两个等价类,ocaml,Ocaml,我有一个简单的图表: name -> string ^ | v label let matrix = [| [|false; false; false |]; [|true; false; true |]; [|false; true; false|] |] (* compute transitive closure of matrix*) let transClosure m = let n = Array.length m in for k = 0 to n -
name -> string
^
|
v
label
let matrix = [|
[|false; false; false |];
[|true; false; true |];
[|false; true; false|] |]
(* compute transitive closure of matrix*)
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 cmp_classes m i j =
match m.(i).(j), m.(j).(i) with
(* same class: there is a path between i and j, and between j and i *)
| true, true -> 0
(* there is a path between i and j *)
| true, false -> -1
(* there is a path between j and i *)
| false, true -> 1
(* i and j are not compareable *)
| false, false -> raise Not_found
let sort_eq_classes m = List.sort (cmp_classes m);;
let eq_class m i =
let column = m.(i)
and set = ref [] in
Array.iteri begin fun j _ ->
if j = i || column.(j) && m.(j).(i) then
set := j :: !set
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;;
(* compute transitive closure of given matrix *)
let tc_xsds = transClosure matrix
(* finding equivalence classes in transitive closure matrix *)
let eq_xsds = eq_classes tc_xsds
(* sorting all equivalence classes with transitive closure matrix *)
let sort_eq_xsds = sort_eq_classes tc_xsds (List.flatten eq_xsds)
它给出了顺序:标签、名称、字符串
,表示正确的顺序
问题是,当我使用另一个图形进行测试时,例如:
name -> string
^
|
v
label -> int
或
或
输出为raise未找到
你能帮我解释一下为什么不能下正确的订单吗?谢谢。正如我在中所说,它不能给你正确的订单,因为在某些情况下,有很多正确的订单
在这三个反例中,您对string
和int
的顺序有何期望?一个接一个,还是随机排列?因为它们之间没有优势,所以它们是不可比较的,您的代码会引发not\u found
异常
处理此问题的一种方法是捕获Not\u found
异常,并指出没有唯一的顺序。或者更温和的方法是返回0
,而不是引发异常,这意味着您不关心不可比较类之间的顺序
正如@ygrek在评论中所说,使用内置异常是个坏主意。您应该定义一个专用于您的目的的自定义异常。并且请不要提出“未找到-定义自定义异常”。请您为我解释更多关于“它不能为您提供正确的订单,因为在某些情况下有很多正确的订单”的信息?我想要一个接一个的顺序。由于字典顺序,你认为
int
应该在string
之前。但就等价类而言,它们之间没有顺序。如果有多个订单,不要试图找到唯一的订单。如果您坚持,请尝试比较字符串以对其排序。但对我来说,这毫无意义。
name -> int
^ \
| \
v v
label string
name -> string
|
v
label -> int