How to determine if a vertex has odd or even number of outE()? - gremlin

I wanna get the vertex that has odd number of edges. Something like these:
g.V().where(out().count() % 2 != 0)
Of course, % can not be used here. Is there a alternative way?

There is no mod operator for sack but there are div, mult and minus.
g.withSack(0).V().as('a').where(outE().count().sack(assign).sack(div).by(constant(2)).sack(mult).by(constant(2)).sack(minus).sack().is(0)) // even
g.withSack(0).V().as('a').where(outE().count().sack(assign).sack(div).by(constant(2)).sack(mult).by(constant(2)).sack(minus).sack().is(neq(0))) // odd

There is no step for a division and to my knowledge also not for modulo, but you can use a lambda for that:
g.V().outE().count().filter{count = it.get(); count % 2 == 1;}
(Note that this query requires a scan of the complete graph in most systems as no index is used.)
This post in the Gremlin-users group contains more information about mathematical operations with Gremlin.

Related

Handy way to index set of tupple in AMPL

I am dealing with a discrete math optimization problem on a complete graph. My variables are the arcs but I want to delete the arcs that "cost too much". I have n nodes which means I have n² arcs.
I define the following set on AMPL
ARCS:={i in 1..n, j in 1..n : i!=j && d[i,j]<= R}
where d[i,j] is the cost on the arc (i,j) and R the limit I am putting.
My problem is that I don't know how to index the variables now. I know I can write
sum{ i in 1..n, j in 1..n : (i,j) in ARCS} blablabla[i,j]
But I think this is quit a tedious way to do. I thought I could write something like this:
sum{e in ARCS} blablabla[e[0],e[1]]
I'm not sure if AMPL supports referencing triple elements by position number the way you've written above. (I suspect not, since I don't recall AMPL ever taking a stance on zero- vs. one-indexing, which it would have to do in order to reference them this way.)
Instead, you can do this:
sum{(i,j) in ARCS} blablabla[i,j]
As well as being more succinct, this may also be more efficient for cases where the membership of ARCS is only a small percentage of possible (i,j) combinations, since it avoids the need to generate and test tuples that aren't in ARCS.

When determining time complexity are variables like n etc always given to an input?

The short version of this long post is when determining time complexity are variables like n etc always given to an input? If not, how else can you define variables?
I'm leaving the long version of my question below in case it helps anyone.
NOTE: I'm aware the question has already been asked here but I'm not satisfied with the answers. The accepted answer ignores the part of the question that the recursion essentially creates a balanced binary tree, while the second answer wrongly presumes that the author used the input as the definition of n rather than the number of levels of calls in the binary tree. (although it may be making the correct point that the difference is the definition of n and its possible the author slipped up or just confused me instead)
I'm comparing these two examples on edition 6 of Cracking the Coding Interview
Pages 44-45 (VI Big O Recursive Runtime section)
int f(int n){
if (n <= 1){
return 1;
}
return f(n-1) + f(n-1);
}
In this case the author defined n as the number of levels created through the recursive calls.
Pages 49-50 (VI Big O Example 9)
Assume the input is a balanced binary search tree
int sum(Node node){
if(node == null){
return 0;
}
return sum(node.left) + node.value + sum(node.right);
}
Here the author defines n as the number of nodes in the tree and states that therefore the depth of the tree is log n. (and since 2^logn equals n its O(n)
So here's the number of calls and depth of the tree based on the input in the first example
Input Calls Depth (author started counting from 0, used the term levels)
1 1 0
2 2 1
3 7 2
4 15 3
etc
I'm actually confused why the author was able to choose the depth of the tree as n because in the past I've always seen an input used as n? (it also seems meaningless b/c the depth is the input minus 1) Was the 2nd answer in the question asked here actually correct instead of the author by using the proper definition of n as the input?
In the 2nd example above it seems sensible that n is the number of nodes in the tree and therefore it has the depth of n?
So I guess I'm asking if an input is always the proper criteria for defining n (or whatever term you want to use as the variable)? If not, how else can you define n? If the input is always used to define n I get why the answers would be different. If not, I'd be confused since the recursion in example 1 essentially does create a balanced binary tree which therefore also has a depth of log n.
Based on googling it does seem that n (etc) is supposed to refer to the input.
Explain Time Complexity?
https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/
https://www.interviewcake.com/article/java/big-o-notation-time-and-space-complexity

Benefits of starting arrays at 0?

What's the purpose of array indices starting at 0 in most programming languages, in contrast to the ordinal way in which we refer to most things IRL (first, second, third, etc.)? What's the logic or utility behind that?
I'm completely used to it by now, but never stopped to think about the reason behind it.
Update: One benefit I read about from Googling is that for loops can have i < n if you want to go up to n.
Dijkstra lays out the reasoning in Why numbering should start at zero.
When dealing with a sequence of length N, the elements of which we wish to distinguish by subscript, the next vexing question is what subscript value to assign to its starting element...
when starting with subscript 1, the subscript range 1 ≤ i < N+1; starting with 0, however, gives the nicer range 0 ≤ i < N. So let us let our ordinals start at zero: an element's ordinal (subscript) equals the number of elements preceding it in the sequence. And the moral of the story is that we had better regard —after all those centuries!— zero as a most natural number.
When we're accessing item by index like a[i] the compiler converts it to [a+i]. So the index of first element is zero because [a+0] will give us 'a' that points to the first item in array. This is quite obviously for, say, C++ but not for more recent languages such as C#.
Dijkstra wrote a really interesting paper about this, in 1982: Why numbering should start at zero.
You may google for it, there's been a lot of discussions about it. I'd say that the fact that the offset of the first element from the beginning (which it is) is zero certainly makes sense.
Because Dijkstra said so.
In my old assembler days it was natural for the offset to start at zero.
dcl foo(9)
ldx0 0 'offset to index register 0
lda foo,x0 'get first element
adx0 1,du 'get 2nd
ldq foo,x0
When looking at it from the perspective of the hardware it makes more sense.

advice needed with prolog cut?

in this task i have a Prolog database filled with e.g.
edge(1,0)
edge(2,0)
edge(1,3)
an edge signifies that two points are joined.
I am asked to write a function called reach(i,j,k) where i is the start point j is the end point and k is the number of steps you may use.
K is needed to stop the recursion looping e.g.
Suppose the only edge I’ve got goes from 1 to3,and I’m trying to get to 6. Then I can’t get from 1to6 in one go. so I’ll look for somewhere I can get to, and see if I can get from there to 6. The first place I can get to in one go is 3, so I’ll try to get from there to 6.
i have done this as so:
%% Can you get there in one step (need two rules because all links are
%% from smaller to greater, but we may need to get from greater to smaller.
reach1(I, J,_K) :-
edge(I, J).
reach1(I, J,_K) :-
edge(J, I).
%% Chhose somewhere you can get to in one step: can you get from there
%% to your target?
reach1(I,J,K) :-
K>1,
edge(I, B),
K1 is K-1,
reach1(B,J,K1).
reach1(I,J,K) :-
K>1,
edge(B, I),
K1 is K-1,
reach1(B,J,K1).
this works, however i am stuck with the second part in which we are asked not to use k but to use a "cut" to do this.
does anyone know how to do this or can give me some pointers?
The cut ensures that once a goal has been resolved in one way, it doesn't look for another way.
example:
reach(I, J,_K) :-
edge(I, J).
no cut - if for some reason Prolog backtracks, it will try to reach from I to J another way.
You might feel there's no point reaching this node another way if the simple edge works, and in that case you can do:
reach(I, J,_K) :-
edge(I, J),
!.
which "cuts" any alternative to this goal, but the one Prolog has found.

Find number range intersection

What is the best way to find out whether two number ranges intersect?
My number range is 3023-7430, now I want to test which of the following number ranges intersect with it: <3000, 3000-6000, 6000-8000, 8000-10000, >10000. The answer should be 3000-6000 and 6000-8000.
What's the nice, efficient mathematical way to do this in any programming language?
Just a pseudo code guess:
Set<Range> determineIntersectedRanges(Range range, Set<Range> setofRangesToTest)
{
Set<Range> results;
foreach (rangeToTest in setofRangesToTest)
do
if (rangeToTest.end <range.start) continue; // skip this one, its below our range
if (rangeToTest.start >range.end) continue; // skip this one, its above our range
results.add(rangeToTest);
done
return results;
}
I would make a Range class and give it a method boolean intersects(Range) . Then you can do a
foreach(Range r : rangeset) { if (range.intersects(r)) res.add(r) }
or, if you use some Java 8 style functional programming for clarity:
rangeset.stream().filter(range::intersects).collect(Collectors.toSet())
The intersection itself is something like
this.start <= other.end && this.end >= other.start
This heavily depends on your ranges. A range can be big or small, and clustered or not clustered. If you have large, clustered ranges (think of "all positive 32-bit integers that can be divided by 2), the simple approach with Range(lower, upper) will not succeed.
I guess I can say the following:
if you have little ranges (clustering or not clustering does not matter here), consider bitvectors. These little critters are blazing fast with respect to union, intersection and membership testing, even though iteration over all elements might take a while, depending on the size. Furthermore, because they just use a single bit for each element, they are pretty small, unless you throw huge ranges at them.
if you have fewer, larger ranges, then a class Range as describe by otherswill suffices. This class has the attributes lower and upper and intersection(a,b) is basically b.upper < a.lower or a.upper > b.lower. Union and intersection can be implemented in constant time for single ranges and for compisite ranges, the time grows with the number of sub-ranges (thus you do not want not too many little ranges)
If you have a huge space where your numbers can be, and the ranges are distributed in a nasty fasion, you should take a look at binary decision diagrams (BDDs). These nifty diagrams have two terminal nodes, True and False and decision nodes for each bit of the input. A decision node has a bit it looks at and two following graph nodes -- one for "bit is one" and one for "bit is zero". Given these conditions, you can encode large ranges in tiny space. All positive integers for arbitrarily large numbers can be encoded in 3 nodes in the graph -- basically a single decision node for the least significant bit which goes to False on 1 and to True on 0.
Intersection and Union are pretty elegant recursive algorithms, for example, the intersection basically takes two corresponding nodes in each BDD, traverse the 1-edge until some result pops up and checks: if one of the results is the False-Terminal, create a 1-branch to the False-terminal in the result BDD. If both are the True-Terminal, create a 1-branch to the True-terminal in the result BDD. If it is something else, create a 1-branch to this something-else in the result BDD. After that, some minimization kicks in (if the 0- and the 1-branch of a node go to the same following BDD / terminal, remove it and pull the incoming transitions to the target) and you are golden. We even went further than that, we worked on simulating addition of sets of integers on BDDs in order to enhance value prediction in order to optimize conditions.
These considerations imply that your operations are bounded by the amount of bits in your number range, that is, by log_2(MAX_NUMBER). Just think of it, you can intersect arbitrary sets of 64-bit-integers in almost constant time.
More information can be for example in the Wikipedia and the referenced papers.
Further, if false positives are bearable and you need an existence check only, you can look at Bloom filters. Bloom filters use a vector of hashes in order to check if an element is contained in the represented set. Intersection and Union is constant time. The major problem here is that you get an increasing false-positive rate if you fill up the bloom-filter too much.
Information, again, in the Wikipedia, for example.
Hach, set representation is a fun field. :)
In python
class nrange(object):
def __init__(self, lower = None, upper = None):
self.lower = lower
self.upper = upper
def intersection(self, aRange):
if self.upper < aRange.lower or aRange.upper < self.lower:
return None
else:
return nrange(max(self.lower,aRange.lower), \
min(self.upper,aRange.upper))
If you're using Java
Commons Lang Range
has a
overlapsRange(Range range) method.

Resources