Efficient algorithm for looping over all neighbor pairs (2 point cliques) in 2-D array - c

I need to loop over all (unordered) pairs of pixels in an image that are neighbors of each other without repetition. I am using an 8 point neighborhood. For example:
x,y| 0 1 2 3 4
---+---+---+---+---+---+
0 | | | | | |
+---+---+---+---+---+
1 | a | b | c | d | |
+---+---+---+---+---+
2 | e | f | g | h | |
+---+---+---+---+---+
3 | i | j | k | l | |
+---+---+---+---+---+
4 | | | | | |
+---+---+---+---+---+
The neighbors of pixel f are in the 3x3 square around it. Thus, g, for example, forms a 2 point clique with f. If I were to loop over all the rows and columns of the image, this clique would be counted twice, once when f is the center pixel and once when g is the center pixel. Similar inefficiencies would occur with the rest of the cliques.
So what I would like to do, is loop over all the cliques, rather than each pixel. If I were familiar with graph theory, I think some of the answers already given to similar questions would suffice, but as I am not, I would really appreciate any help that you can give with an efficient algorithm in layman's terms. Thanks in advance!

Loop the first point over all points. Inner loop the second point over the right, lower-left, lower, and lower-right neighbors (if they exist).

Related

How to traverse nodes efficiently in postgresql?

I'm trying to traverse nodes from the specific one with the recursive clause in PostgreSQL.(Btw I'm new to Postgresql) Here's a simple version of my db tables:
table: nodes
|--------------|------------------|
| id | node_name |
|--------------|------------------|
| 1 | A |
|--------------|------------------|
| 2 | B |
|--------------|------------------|
| 3 | C |
|--------------|------------------|
| 4 | D |
|--------------|------------------|
| 5 | E |
table: links
|--------------|---------------------|-----------------|
| id | id_from | id_to |
|--------------|---------------------|-----------------|
| 1 | 1 | 2 |
|--------------|---------------------|-----------------|
| 2 | 1 | 3 |
|--------------|---------------------|-----------------|
| 3 | 2 | 4 |
|--------------|---------------------|-----------------|
| 4 | 3 | 4 |
|--------------|---------------------|-----------------|
| 5 | 4 | 5 |
So, it's just this simple direct graph. (all edges go left to right)
B
/ \
A D - E
\ /
C
In this situation, what is the efficient way to get all vertices that can be visited starting from A?
What I tried:
dfs solution found at Simple Graph Search Algorithm in SQL (PostgreSQL)
with recursive graph(node1, node2, path) as
(
select id_from, id_to, ARRAY[id_from] from links
where id_from = 1
union all
select nxt.id_from, nxt.id_to,array_append(prv.path, nxt.id_from)
from links nxt, graph prv
where nxt.id_from = prv.node2
and nxt.id_from != ALL(prv.path)
)
select * from graph
It gave me almost all paths. But it visited D vertex twice. (Perform D -> E logic twice) I want to ignore the visited vertex for efficiency.
So, how can I achieve this? Thanks in advance!
It is not that simple. Within a single query, all recursive paths are completely independent. So, each path does not know about what's going on on the sibling path. It does not know that a certain node was already visited by a sibling.
Because SQL queries don't support some kind of global variables, it is impossible to share such information between the recursion paths that way.
I'd recommend to write a function where you can use plsql syntax which solves the problem in a more "common programmatical" way.

array formula with dates

I have four columns of dates(A,B,C,D),I want to excel verify if each period of "period 2" intersects ALL "period 1" from 1,2,3.....
For example 20-28/01/2016 intersects 01-24/01/2016 AND 25/01-03/02/2016. The answer in this case in column E must be "wrong".
I think this have to be an array because in a cell must be verified an entire column. If it could be done without array I would be very happy, because array slow time calculation very much down on my computer .
_________________________________________________________________
| A | B | C | D | E |
| period 1 | period 2 | |
1 |01/01/2016|24/01/2016|20/01/2016|28/01/2016| "wrong" |
2 |25/01/2016|03/02/2016|04/02/2016|10/02/2016| "ok" |
3 |

Creating hierarchical data (tree) structures in Neo4j using "tree keys"

I have imported data from a CSV file and created a lot of Nodes, all of which are related to other Nodes within the same data set based on a "Tree Number" hierarchy system:
For example, the Node with Tree Number A01.111 is a direct child of Node A01, and the Node with Tree Number A01.111.230 is a direct child of Node A01.111.
What I am trying to do is create unique relationships between Nodes that are direct children of other Nodes. For example Node A01.111.230 should only have one "IS_CHILD_OF" relationship, with Node A01.111.
I have tried several things, for example:
MATCH (n:Node), (n2:Node)
WHERE (n2.treeNumber STARTS WITH n.treeNumber)
AND (n <> n2)
AND NOT ((n2)-[:IS_CHILD_OF]->())
CREATE UNIQUE (n2)-[:IS_CHILD_OF]->(n);
This example results in creating unique "IS_CHILD_OF" relationships but not with the direct parent of a Node. Rather, Node A01.111.230 would be related to Node A01.
I'd like to suggest another general solution, also avoiding a cartesian product as #InverseFalcon points out.
Let's indeed start by creating an index for faster lookup, and inserting some test data:
CREATE CONSTRAINT ON (n:Node) ASSERT n.treeNumber IS UNIQUE;
CREATE (n:Node {treeNumber: 'A01.111.230'})
CREATE (n:Node {treeNumber: 'A01.111'})
CREATE (n:Node {treeNumber: 'A01'})
Then we need to scan all nodes as potential parents, and look for children which start with the treeNumber of the parent (STARTS WITH can use the index) and have no dots in the "remainder" of the treeNumber (i.e. a direct child), instead of splitting, joining, etc.:
MATCH (p:Node), (c:Node)
WHERE c.treeNumber STARTS WITH p.treeNumber
AND p <> c
AND NOT substring(c.treeNumber, length(p.treeNumber) + 1) CONTAINS '.'
RETURN p, c
I replaced the creation of the relationship by a simple RETURN for profiling purposes, but you can simply replace it by CREATE UNIQUE or MERGE.
Actually, we can get rid of the p <> c predicate and the + 1 on the length by pre-computing the actual prefix which should match:
MATCH (p:Node)
WITH p, p.treeNumber + '.' AS parentNumber
MATCH (c:Node)
WHERE c.treeNumber STARTS WITH parentNumber
AND NOT substring(c.treeNumber, length(parentNumber)) CONTAINS '.'
RETURN p, c
However, profiling that query shows that the index is not used, and there is a cartesian product (so we have a O(n^2) algorithm):
Compiler CYPHER 3.0
Planner COST
Runtime INTERPRETED
+--------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+--------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +ProduceResults | 2 | 2 | 0 | c, p | p, c |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +Filter | 2 | 2 | 26 | c, p, parentNumber | NOT(Contains(SubstringFunction(c.treeNumber,length(parentNumber),None),{ AUTOSTRING1})) AND StartsWith(c.treeNumber,parentNumber) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +Apply | 2 | 9 | 0 | p, parentNumber -- c | |
| |\ +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| | +NodeByLabelScan | 9 | 9 | 12 | c | :Node |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +Projection | 3 | 3 | 3 | parentNumber -- p | p; Add(p.treeNumber,{ AUTOSTRING0}) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +NodeByLabelScan | 3 | 3 | 4 | p | :Node |
+--------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
Total database accesses: 45
But, if we simple add a hint like so
MATCH (p:Node)
WITH p, p.treeNumber + '.' AS parentNumber
MATCH (c:Node)
USING INDEX c:Node(treeNumber)
WHERE c.treeNumber STARTS WITH parentNumber
AND NOT substring(c.treeNumber, length(parentNumber)) CONTAINS '.'
RETURN p, c
it does use the index and we have something like a O(n*log(n)) algorithm (log(n) for the index lookup):
Compiler CYPHER 3.0
Planner COST
Runtime INTERPRETED
+-------------------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+-------------------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +ProduceResults | 2 | 2 | 0 | c, p | p, c |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +Filter | 2 | 2 | 6 | c, p, parentNumber | NOT(Contains(SubstringFunction(c.treeNumber,length(parentNumber),None),{ AUTOSTRING1})) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +Apply | 2 | 3 | 0 | p, parentNumber -- c | |
| |\ +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| | +NodeUniqueIndexSeekByRange | 9 | 3 | 6 | c | :Node(treeNumber STARTS WITH parentNumber) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +Projection | 3 | 3 | 3 | parentNumber -- p | p; Add(p.treeNumber,{ AUTOSTRING0}) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +NodeByLabelScan | 3 | 3 | 4 | p | :Node |
+-------------------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
Total database accesses: 19
Note that I did cheat a bit when introducing the WITH step creating the prefix earlier, as I noticed it improved the execution plan and DB accesses over
MATCH (p:Node), (c:Node)
USING INDEX c:Node(treeNumber)
WHERE c.treeNumber STARTS WITH p.treeNumber
AND p <> c
AND NOT substring(c.treeNumber, length(p.treeNumber) + 1) CONTAINS '.'
RETURN p, c
which has the following execution plan:
Compiler CYPHER 3.0
Planner RULE
Runtime INTERPRETED
+--------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
| Operator | Rows | DB Hits | Variables | Other |
+--------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
| +Filter | 2 | 9 | c, p | NOT(p == c) AND NOT(Contains(SubstringFunction(c.treeNumber,Add(length(p.treeNumber),{ AUTOINT0}),None),{ AUTOSTRING1})) |
| | +------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
| +SchemaIndex | 6 | 12 | c -- p | PrefixSeekRangeExpression(p.treeNumber); :Node(treeNumber) |
| | +------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
| +NodeByLabel | 3 | 4 | p | :Node |
+--------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
Total database accesses: 25
Finally, for the record, the execution plan of the original query I wrote (i.e. without the hint) was:
Compiler CYPHER 3.0
Planner COST
Runtime INTERPRETED
+--------------------+----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+--------------------+----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| +ProduceResults | 2 | 2 | 0 | c, p | p, c |
| | +----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| +Filter | 2 | 2 | 21 | c, p | NOT(p == c) AND StartsWith(c.treeNumber,p.treeNumber) AND NOT(Contains(SubstringFunction(c.treeNumber,Add(length(p.treeNumber),{ AUTOINT0}),None),{ AUTOSTRING1})) |
| | +----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| +CartesianProduct | 9 | 9 | 0 | p -- c | |
| |\ +----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| | +NodeByLabelScan | 3 | 9 | 12 | c | :Node |
| | +----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| +NodeByLabelScan | 3 | 3 | 4 | p | :Node |
+--------------------+----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Total database accesses: 37
It's not the worse one: the one without the hint but with the pre-computed prefix is! This is why you should always measure.
I think we can improve on the query a bit. First, ensure you have either a unique constraint or an index on :Node.treeNumber, as you'll need that to improve your parent node lookups in this query.
Next, let's match on child nodes, excluding root nodes (assuming no .'s in the root's treeNumber) and nodes that have already been processed and have a relationship already.
Then we'll find each node's parent by the treeNumber using our index, and create the relationship. This assumes that a child treeNumber always has 4 more characters, including the dot.
MATCH (child:Node)
WHERE child.treeNumber CONTAINS '.'
AND NOT EXISTS( (child)-[:IS_CHILD_OF]->() )
WITH child, SUBSTRING(child.treeNumber, 0, SIZE(child.treeNumber)-4) as parentNumber
MATCH (parent:Node)
WHERE parent.treeNumber = parentNumber
CREATE UNIQUE (child)-[:IS_CHILD_OF]->(parent)
I think this query avoids a cartesian product as you may get from other answers, and should be around O(n) (someone correct me if I'm wrong).
EDIT
In the event that each subset of numbers in treeNumbers is NOT constrained to 3 (as in your description, actually, with 'A01.111.23'), then you need a different means of deriving the parentNumber. Neo4j is a little weak here, as it lacks both an indexOf() function as well as a join() function to reverse a split(). You may need the APOC Procedures library installed to allow access to a join() function.
The query to handle cases with variable counts of digits in the numeric subsets of treeNumber becomes this:
MATCH (child:Node)
WHERE child.treeNumber CONTAINS '.'
AND NOT EXISTS( (child)-[:IS_CHILD_OF]->() )
WITH child, SPLIT(child.treeNumber, '.') as splitNumber
CALL apoc.text.join(splitNumber[0..-1], '.') YIELD value AS parentNumber
WITH child, parentNumber
MATCH (parent:Node)
WHERE parent.treeNumber = parentNumber
CREATE UNIQUE (child)-[:IS_CHILD_OF]->(parent)
I think I just figured out a solution! (If someone has a more elegant one please do post)
I just realized that the "Tree Number" coding system always uses 3-digit numbers between the dots, i.e. A01.111.230 or C02.100, therefore if a Node is the direct child of another Node, it's "Tree Number" should not only start with the Tree Number of the parent Node, it should also be 4 characters longer (one character for the dot '.' and 3 characters for the numeric value).
Therefore my solution that seems to do the job is:
MATCH (n:Node), (n2:Node)
WHERE (n2.treeNumber STARTS WITH n.treeNumber)
AND (length(n2.treeNumber) = (length(n.treeNumber) + 4))
CREATE UNIQUE (n2)-[:IS_CHILD_OF]->(n);
For your requirement STARTS WITH won't work, since A01.111.23 does indeed start with A01 in addition to starting with A01.111.
The treeNumber is made up of several parts with '.' as the separator. Let's not make any assumptions about the maximum/minimum possible character lengths of the individual parts. What we need is to compare all but the last part of each node's treeNumber with that of the potential child node being tested. You can achieve this using Cypher's split() function as follows:
MATCH (n1:Node), (n2:Node)
WHERE split(n2.treeNumber,'.')[0..-1] = split(n1.treeNumber,'.')
CREATE UNIQUE (n2)-[:IS_CHILD_OF]->(n1);
The split() function splits a string, at each occurrence of a given separator, into a list of strings (parts). In this context the separator is '.' to split any treeNumber. We can select a subset of a list in cypher using the syntax list[{startIndex}..{endIndex}]. Negative indices for reverse lookup are permitted, such ass the one used in the above query.
This solution should generalize to all possible treeNumber values, in the format at hand, irrespective of number of parts and individual part lengths.

All the possible combinations from the decomposition of the elements from an array

For example, if i have this array: {2,3,1} the first element can be decompose in {0,1,2}, the second one in {0,1,2,3} and the third one in {0,1}. So i have to make the sum of every single combination what is possible to be make.
example:
0,1,0
0,0,0
0,3,1
2,3,1
.....
My idea to above this problem is make a kind of tree like this.
0 1 2
| | | | | | | | | | | |
0 1 2 3 0 1 2 3 0 1 2 3
| | | | | | | | | | | | | | | | | | | | | | | |
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
so my idea is make a Recursive function to make the sum:
1) move from top to bottom and when i find the limit change the move.
2) move from left to right, and when i find the limit in the right i return.
3) go back and move to the right, and back to the first step.
This is my code:
void tree(int*A, int i,int n,int j,int mov){
if(mov){ ///move from up to bottom.
if(i==n){ ///n is the large of the array.
return; ///
tree(A,i-1,n,j+1,0);
}
tree(A,i+1,n,j,1);
}
else{ ///move from left to right.
if(j>A[i]){ ///j is decomposition of the element.
return;
}
tree(A,i,n,j+1,0);
}
}
I don't make any sum, I'm just trying to go over all the possible combination. But it's not working. I think is a problem whit what is being returning when the function find a limit.
I really want to solve it by myself but I'm in a dead point right now, maybe a need to know something else about recursive functions, so please don't put a complete solution, i want to learn by my way. I just want tips about what can i do. Is this the best way to solve this problem?
Also, please tell if the problem it's clear, my English is basic so i have problems to express what i want.

C program to find the number of onto functions and to display all the functions

I have to write a C program (for my Discrete Mathematics assignment) that finds the number of onto functions from set A (|A| = m) to set B (|B|=n) and to display all those functions. Number of onto functions I calculated using the code:
for(k=0; k<n; k++)
x = x + pow( -1, k) * combination( n, n - k ) * pow( ( n - k ), m);
Where combination is a function that finds the Number of possible combinations.
For example if A = {1,2,3}, B={a,b,c} then the number of onto functions evaluated from the formula is
3^3 - 3(2^3) + 3 = 6.
One possible solution is f = {(1,a),(2,b),(3,c)} [I know this is a solution].
But my problem is: How to display each and every solution!?
This is just a trivial example. But if m and n values are increased (provided m>=n) then the number of possible onto functions increases exponentially!!
For example if m=7 and n=4 there are 8400 functions!
I can't think of any method to display each and every function that exists between A and B.
I answered a similar problem sometime ago but m and n were equal m = n.(You must think recursively to solve this), by your comment I think the possible answers are: {(1,a)(2,b)(3,c)}, {(2,a)(3,b)(1,c)}, {(3,a)(1,b)(2,c)}, {(3,a)(2,b)(1,c)}, {(2,a)(1,b)(3,c)} and {(1,a)(3,b)(2,c)} then this is my recipe:
Set 2 arrays with their initial value let's call them letters and numbers.
*---*---*---* *---*---*---*
| a | b | c | <---letters. | 1 | 2 | 3 | <---numbers.
*---*---*---* *---*---*---*
Choose one of the arrays to be your pivot, I chose the letters, it will be statical.
*---*---*---* *---*---*---*
| a | b | c | <---STATIC. | 1 | 2 | 3 | <---DYNAMIC.
*---*---*---* *---*---*---*
Rotate the dynamic array counter-clockwise or clockwise as you wish, you must print the i element of numbers with the i element of letters.
*---*---*---* *---*---*---* *---*---*---*
| 1 | 2 | 3 | -(Print)-> | 2 | 3 | 1 | -(Print)-> | 3 | 1 | 2 |
*---*---*---* *---*---*---* *---*---*---*
So you get at this point: {(1,a)(2,b)(3,c)}, {(2,a)(3,b)(1,c)}, {(3,a)(1,b)(2,c)}, 3 are missing.
Swap the i element with the n element of the dynamic array.
*---*---*---* *---*---*---*
| 1 | 2 | 3 | ---------( Swap (0<->2) )-------> | 3 | 2 | 1 |
*---*---*---* *---*---*---*
Repeat the step 3.
*---*---*---* *---*---*---* *---*---*---*
| 3 | 2 | 1 | -(Print)-> | 2 | 1 | 3 | -(Print)-> | 1 | 3 | 2 |
*---*---*---* *---*---*---* *---*---*---*
So you get the missed subsets:{(3,a)(2,b)(1,c)}, {(2,a)(1,b)(3,c)} and {(1,a)(3,b)(2,c)}.
If you have more than 3 example 4. Easy: 1234 (rotate N times where N is the number of variables and print with each movement), swap 1 and 4 -> 4231 (Rotate and Print), swap 2 and 3 -> 4321 (Rotate and Print), swap 4 and 1 --> 1324 (Rotate and Print).
I hope this helped.

Resources