OWLAPI 缓慢计算不相交的公理
OWLAPI slow calculating disjoint axioms
我的目标:在包含大约 5000 个公理的 ontology 中找到不相交的公理(断言和推断)。
我的代码:
for (OWLClass clazz1 : ontology.getClassesInSignature()) {
for (OWLClass clazz2 : ontology.getClassesInSignature()) {
OWLAxiom axiom = MyModel.factory.getOWLDisjointClassesAxiom(clazz2, clazz1);
if( !(ontology.containsAxiom(axiom)) && reasoner.isEntailed(axiom))
{
System.out.println(clazz2.toString() + " disjoint with " + clazz1.toString());
}
问题:执行时间非常慢,我想说是永恒的。即使我减少了一些if语句的比较次数,情况还是一样。
Protege 似乎可以非常快速地计算这些推断的公理,它基于我正在使用的相同 API (OWLAPI)。那么,我的方法有误吗?
分析代码很可能会发现慢的部分是
reasoner.isEntailed(axiom)
此形式要求推理器重新计算每个 class 对的蕴含,包括 clazz1
和 clazz2
相等的对(您可能想跳过它)。
或者,您可以遍历签名中的 classes 一次,然后使用推理器获取所有不相交的 classes:
Set<OWLClass> visited=new HashSet<>();
for (OWLClass c: ontology.getClassesInSignature()) {
if (visited.add(c)) {
NodeSet set = reasoner.getDisjointClasses(c);
for (Node node: set.getNodes()) {
System.out.println("Disjoint with "+c+": "+node);
visited.addAll(node.getEntities());
}
}
}
最坏的情况,这将对每个 class 进行一次推理调用(因为没有 class 是不相交的)。最好的情况,所有 classes 都不相交或等同于另一个 class,因此只需要一个推理机调用。
我的目标:在包含大约 5000 个公理的 ontology 中找到不相交的公理(断言和推断)。
我的代码:
for (OWLClass clazz1 : ontology.getClassesInSignature()) {
for (OWLClass clazz2 : ontology.getClassesInSignature()) {
OWLAxiom axiom = MyModel.factory.getOWLDisjointClassesAxiom(clazz2, clazz1);
if( !(ontology.containsAxiom(axiom)) && reasoner.isEntailed(axiom))
{
System.out.println(clazz2.toString() + " disjoint with " + clazz1.toString());
}
问题:执行时间非常慢,我想说是永恒的。即使我减少了一些if语句的比较次数,情况还是一样。
Protege 似乎可以非常快速地计算这些推断的公理,它基于我正在使用的相同 API (OWLAPI)。那么,我的方法有误吗?
分析代码很可能会发现慢的部分是
reasoner.isEntailed(axiom)
此形式要求推理器重新计算每个 class 对的蕴含,包括 clazz1
和 clazz2
相等的对(您可能想跳过它)。
或者,您可以遍历签名中的 classes 一次,然后使用推理器获取所有不相交的 classes:
Set<OWLClass> visited=new HashSet<>();
for (OWLClass c: ontology.getClassesInSignature()) {
if (visited.add(c)) {
NodeSet set = reasoner.getDisjointClasses(c);
for (Node node: set.getNodes()) {
System.out.println("Disjoint with "+c+": "+node);
visited.addAll(node.getEntities());
}
}
}
最坏的情况,这将对每个 class 进行一次推理调用(因为没有 class 是不相交的)。最好的情况,所有 classes 都不相交或等同于另一个 class,因此只需要一个推理机调用。