How can I programmatically compute path length using Jena RDF/Ontology API?

别等时光非礼了梦想. 提交于 2019-12-13 15:53:50

问题


I have an RDF Graph with only one relationship(RDFS.subClassOf or is-a) between all the classes.

The 'size' of each class is equal to the total number of its subclasses. The 'size' of each RDFS.subClassOf property is 0.5 if it is connecting from a class with fewer total number of subclasses and 1 if it is connecting from class with large total number of subclasses to class with less total number of subclasses.

I want to perform an arithmetic sum of all the sizes of each semantic component (class / relationship) in the path using the Jena RDF/Ontology API.

For example, given the camera ontology (http://protege.cim3.net/file/pub/ontologies/camera/camera.owl) one of the paths is: Thing - PurchaseableItem - Lens : Its sum would be (5 + 0.5 + 3 + 0.5 + 0) = 9.


回答1:


Assuming that this builds on the answer to your previous question about constructing the type of paths that you mention in the question, can you just use:

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;
}

Then we get the following sums for the paths. The complete code follows this output. Notice the owl:Thing has a size of four here, not five, as you gave in the question. if the idea was to count the number of times that a class appeared as the object in a triple of rdfs:subClassOf, there are only four triples of the form something rdfs:subClassOf owl:Thing in the OWL file that you linked to, so it seems like its size should be four, not five. Given that consideration, note that the “Thing–PurchaseableItem–Lens” path has weight eight, as expected (one less than nine, as you mentioned in the question).

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]

Complete code:

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 );
        }
    }
}


来源:https://stackoverflow.com/questions/17868524/how-can-i-programmatically-compute-path-length-using-jena-rdf-ontology-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!