假设这建立在您之前关于构建您在问题中提到的路径类型的问题的答案之上,您可以使用:
public static int classSize( final Resource klass ) {
return klass.getModel().listSubjectsWithProperty( RDFS.subClassOf, klass ).toList().size();
}
public static double pathSize( final List<Resource> path ) {
int prevSize = classSize( path.get( 0 ));
double pathSum = prevSize;
for ( int i = 1; i < path.size(); i++ ) {
int currSize = classSize( path.get( i ));
double linkWeight = currSize < prevSize ? 0.5 : 1.0;
pathSum += linkWeight + currSize;
prevSize = currSize;
}
return pathSum;
}
然后我们得到以下路径的总和。完整的代码遵循此输出。请注意,owl:Thing
这里的大小为四,而不是您在问题中给出的五。如果这个想法是计算一个类作为对象出现在三元组中的次数,那么您链接到的 OWL 文件rdfs:subClassOf
中只有四个三元组something rdfs:subClassOf owl:Thing
,所以它的大小似乎应该是四个,而不是五。考虑到这一点,请注意“Thing-PurchaseableItem-Lens”路径的权重为 8,正如预期的那样(比 9 少一个,正如您在问题中提到的)。
4.0 [http://www.w3.org/2002/07/owl#Thing]
7.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem]
4.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Window]
4.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Range]
4.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Money]
10.0 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera]
8.0 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Lens]
8.0 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Body]
10.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera, http://www.xfront.com/owl/ontologies/camera/#Digital]
10.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera, http://www.xfront.com/owl/ontologies/camera/#Large-Format]
完整代码:
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDFS;
public class BFSInRDFWithJena {
public static List<List<Resource>> BFS( final Model model, final Queue<List<Resource>> queue, final int depth ) {
final List<List<Resource>> results = new ArrayList<>();
while ( !queue.isEmpty() ) {
final List<Resource> path = queue.poll();
results.add( path );
if ( path.size() < depth ) {
final Resource last = path.get( path.size() - 1 );
final StmtIterator stmt = model.listStatements( null, RDFS.subClassOf, last );
while ( stmt.hasNext() ) {
final List<Resource> extPath = new ArrayList<>( path );
extPath.add( stmt.next().getSubject().asResource() );
queue.offer( extPath );
}
}
}
return results;
}
public static int classSize( final Resource klass ) {
return klass.getModel().listSubjectsWithProperty( RDFS.subClassOf, klass ).toList().size();
}
public static double pathSize( final List<Resource> path ) {
int prevSize = classSize( path.get( 0 ));
double pathSum = prevSize;
for ( int i = 1; i < path.size(); i++ ) {
int currSize = classSize( path.get( i ));
double linkWeight = currSize < prevSize ? 0.5 : 1.0;
pathSum += linkWeight + currSize;
prevSize = currSize;
}
return pathSum;
}
public static void main( final String[] args ) throws IOException {
final Model model = ModelFactory.createDefaultModel();
try ( final InputStream in = BFSInRDFWithJena.class.getClassLoader().getResourceAsStream( "camera.owl" ) ) {
model.read( in, null );
}
// setup the initial queue
final Queue<List<Resource>> queue = new LinkedList<>();
final List<Resource> thingPath = new ArrayList<>();
thingPath.add( OWL.Thing.inModel( model ));
queue.offer( thingPath );
// Get the paths, and display them
final List<List<Resource>> paths = BFS( model, queue, 4 );
for ( List<Resource> path : paths ) {
System.out.println( pathSize( path ) + " " + path );
}
}
}