graph.addEdge() implicitly add non-existing vertices? - jgrapht

While it's good that JGraphT separates the act of adding vertices and adding edges, surely there's a case when you'd want to combine the two? In other words, if you try to add an edge where either (or both) of the vertices aren't in the graph, then add them?
Does JGraphT have such a shortcut to writing 3 method calls?

You could simply override JGraphT's method to make it add vertices that are not yet present in the graph:
#Override
public E addEdge(V sourceVertex, V targetVertex) {
if (!containsVertex(sourceVertex)) {
addVertex(sourceVertex);
}
if (!containsVertex(targetVertex)) {
addVertex(targetVertex);
}
return super.addEdge(sourceVertex, targetVertex);
}

Related

Sorting a 2 dimensional array of objects in Kotlin

I have a static 2 dimensional array of objects in a Kotlin project:
class Tables {
companion object{
lateinit var finalTable: Array<Array<Any?>?>
}
}
It is a little clearer in Java:
public class Tables {
public static Object[][] finalTable;
}
The third element in one row of objects in the table, is a string boxed as an object. In other words: finalTable[*][2] is a string describing the item. When I add an item to the array in Kotlin, I want to sort the entire array in alphabetical order of the description.
In Java this is easy:
Arrays.sort(Tables.finalTable, Comparator.comparing(o -> (String) o[2]));
When I try to use Android Studio to translate the Java code into Kotlin, it produces the following:
Arrays.sort( Tables.finalTable, Comparator.comparing( Function { o: Array<Any?>? -> o[2] as String }) )
This does not work, you have change the String cast as follows:
Arrays.sort( Tables.finalTable, Comparator.comparing( Function { o: Array<Any?>? -> o[2].toString() }) )
This version will compile and run, but it totally messes up the sorting of the table, so it does not work. I have tried variations on this theme, without any success. To get my project to work, I had to create a Java class in the Kotlin project with the functional Java code listed above:
public class ArraySort {
public void sortArray(){
Arrays.sort(Tables.finalTable, Comparator.comparing(o -> (String) o[2]));
}
}
This sorts the table like a charm, but I would prefer to keep my project "pure Kotlin". Can anyone suggest a pure Kotlin method to sort such an array? Thanks!
Unless I'm missing something, you can just do this:
Tables.finalTable.sortBy { it[2] as String }
which sorts your array in place. sortedBy will produce a new copy of the original if that's what you want instead, and might be why the comment suggestions weren't working for you.
But this whole unstructured array situation isn't ideal, the solution is brittle because it would be easy to put the wrong type in that position for a row, or have a row without enough elements, etc. Creating a data structure (e.g. a data class) would allow you to have named parameters you can refer to (making the whole thing safer and more readable) and give you type checking too

OWLAPI slow calculating disjoint axioms

My goal: find the disjoint axioms (asserted and inferred) in an ontology which contains around 5000 axioms.
My code:
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());
}
The problem: the execution time is extremely slow, I'd say eternal. Even if I reduce the number of comparison with some if statement, the situation is still the same.
Protege seems to be very quick to compute those inferred axioms and it's based on the same API I am using (OWLAPI). So, am I in the wrong approach?
Profiling the code will very likely reveal that the slow part is
reasoner.isEntailed(axiom)
This form requires the reasoner to recompute entailments for each class pair, including the pairs where clazz1 and clazz2 are equal (you might want to skip that).
Alternatively, you can iterate through the classes in signature once and use the reasoner to get all disjoint 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());
}
}
}
Worst case scenario, this will make one reasoner call per class (because no class is disjoint). Best case scenario, all classes are disjoint or equivalent to another class, so only one reasoner call is required.

How to get data from an upstream node in maya?

I have a maya node myNode, which creates a shadeNode, which inMesh attribute is connected to shapeNode.outMesh and has an attribute distance.
myNode.outMesh -> shapeNode.inMesh
myNode.distance = 10
Then i have a command, which works on the shape node, but requires the distance argument, which it does by iterating over the inMesh connections:
MPlugArray meshConnections;
MPlug inMeshPlug = depNodeFn.findPlug("inMesh");
inMeshPlug.connectedTo(meshConnections, true, false); // in connections
bool node_found = false;
for(uint i = 0; i < numConnections; i++) {
MPlug remotePlug = meshConnections[i];
myNode = remotePlug.node();
if(MFnDependencyNode(myNode ).typeName() == "myNode") {
node_found = true;
break;
}
}
MFnDependencyNode myDepNode(myNode);
MPlug distancePlug = myDepNode.findPlug("distance");
Now i get a problem, when applying another node (of another type) to myShape, because the dependency graph now looks like this:
myNode.outMesh -> myOtherNode.inMesh
myOtherNode.outMesh -> shapeNode.inMesh
myNode.distance = 10
I tried to remove the check for typeName() == "myNode", because i understood the documentation like there should be recursion to the parent node, when the next node return Mstatus::kInvalidParameter for the unknown MPlug, but i cannot reach the distance plug without implementing further graph traversion.
What is the correct way to reliably find an attribute of a parent node, even when some other nodes were added in between?
The command itself should use the distance Plug to either connect to myNode or to some plug which gets the value recursively. If possible i do not want to change myOtherNode to have a distance plug and correspondig connections for forwarding the data.
The usual Maya workflow would be to make the node operate in isolation -- it should not require any knowledge of the graph structure which surrounds it, it just reacts to changes in inputs and emits new data from its outputs. The node needs to work properly if a user manually unhooks the inputs and then manually reconnects them to other objects -- you can't know, for example, that some tool won't insert a deformer upstream of your node changing the graph layout that was there when the node was first created.
You also don't want to pass data around outside the dag graph -- if the data needs to be updated you'll want to pass it as a connection. Otherwise you won't be able to reproduce the scene from the graph alone. You want to make sure that the graph can only ever produce an unambiguous result.
When you do have to do DAG manipulations -- like setting up a network of connectiosn -- put them into an MPXCommand or a mel/python script.
I found the answer in an answer (python code) to the question how to get all nodes in the graph. My code to find the node in the MPxCommand now looks like this:
MPlugArray meshConnections;
MPlug inMeshPlug = depNodeFn.findPlug("inMesh");
MItDependencyGraph depGraphIt(inMeshPlug, MFn::kInvalid, MItDependencyGraph::Direction::kUpstream);
bool offset_mesh_node_found = false;
while(!depGraphIt.isDone()) {
myNode = depGraphIt.currentItem();
if(MFnDependencyNode(myNode).typeName() == "myNode") {
offset_mesh_node_found = true;
break;
}
depGraphIt.next();
}
The MItDependencyGraph can traverse the graph in upstream or downstream direction either starting from an object or a plug. Here i just search for the first instance of myNode, as I assume there will only be one in my use case. It then connects the distance MPlug in the graph, which still works when more mesh transforms are inserted.
The MItDependencyGraph object allows to filter for node ids, but only the numeric node ids not node names. I probably add a filter later, when I have unique maya ids assigned in all plugins.

How to use Collections.binarySearch() in a CodenameOne project

I am used to being able to perform a binary search of a sorted list of, say, Strings or Integers, with code along the lines of:
Vector<String> vstr = new Vector<String>();
// etc...
int index = Collections.binarySearch (vstr, "abcd");
I'm not clear on how codenameone handles standard java methods and classes, but it looks like this could be fixed easily if classes like Integer and String (or the codenameone versions of these) implemented the Comparable interface.
Edit: I now see that code along the lines of the following will do the job.
int index = Collections.binarySearch(vstr, "abcd", new Comparator<String>() {
#Override
public int compare(String object1, String object2) {
return object1.compareTo(object2);
}
});
Adding the Comparable interface (to the various primitive "wrappers") would also would also make it easier to use Collections.sort (another very useful method :-))
You can also sort with a comparator but I agree, this is one of the important enhancements we need to provide in the native VM's on the various platforms personally this is my biggest peeve in our current VM.
Can you file an RFE on that and mention it as a comment in the Number issue?
If we are doing that change might as well do both.

Check if an apex list contains an object

Is there any way to check if a list contains a certain element? I looked at the List functions and did not see any contain() function like Java or C# , so I was wondering how other people are handling this.
I really need to use a List I cant use a Map like in this example here
What I have now is really bad..
for (String s : allContacts)
{
for(String ic:insertedContacts)
{
if (s != ic )
{
errorContacts.add(s);
break;
}
break;
}
}
A Set might be what you're looking for.
Define a new Set. Set<String> mySet = new Set<String>();
Use the Set.addAll() method to add all of the List elements to the set. mySet.addAll(myList);.
Use the Set.contains() method to check the Set for the element you're looking for.

Resources