All Paths Between 2 vertexes in R - algorithm

I use igraph.
I want yo find all the possible paths between 2 nodes.
For the moment, there doesn't seem to exist any function to find all the paths between 2 nodes in igraph
I found this subject that gives code in python:
All possible paths from one node to another in a directed tree (igraph)
I tried to port it to R but I have some little problems. It gives me the error:
Error of for (newpath in newpaths) { :
for() loop sequence incorrect
Here is the code:
find_all_paths <- function(graph, start, end, mypath=vector()) {
mypath = append(mypath, start)
if (start == end) {
return(mypath)
}
paths = list()
for (node in graph[[start]][[1]]) {
if (!(node %in% mypath)){
newpaths <- find_all_paths(graph, node, end, mypath)
for (newpath in newpaths){
paths <- append(paths, newpath)
}
}
}
return(paths)
}
test <- find_all_paths(graph, farth[1], farth[2])
Here is a dummy code taken from the igrah package, from which to get a sample graph and nodes:
actors <- data.frame(name=c("Alice", "Bob", "Cecil", "David",
"Esmeralda"),
age=c(48,33,45,34,21),
gender=c("F","M","F","M","F"))
relations <- data.frame(from=c("Bob", "Cecil", "Cecil", "David",
"David", "Esmeralda"),
to=c("Alice", "Bob", "Alice", "Alice", "Bob", "Alice"),
same.dept=c(FALSE,FALSE,TRUE,FALSE,FALSE,TRUE),
friendship=c(4,5,5,2,1,1), advice=c(4,5,5,4,2,3))
g <- graph.data.frame(relations, directed=FALSE, vertices=actors)
farth <- farthest.nodes(g)
test <- find_all_paths(graph, farth[1], farth[2])
thanks!
If anyone sees where the problem, that would be of great help...
Mathieu

I also attempted to translate that same solution from Python to R and came up with the following which seems to do the job for me:
# Find paths from node index n to m using adjacency list a.
adjlist_find_paths <- function(a, n, m, path = list()) {
path <- c(path, list(n))
if (n == m) {
return(list(path))
} else {
paths = list()
for (child in a[[n]]) {
if (!child %in% unlist(path)) {
child_paths <- adjlist_find_paths(a, child, m, path)
paths <- c(paths, child_paths)
}
}
return(paths)
}
}
# Find paths in graph from vertex source to vertex dest.
paths_from_to <- function(graph, source, dest) {
a <- as_adj_list(graph, mode = "out")
paths <- adjlist_find_paths(a, source, dest)
lapply(paths, function(path) {V(graph)[unlist(path)]})
}

Related

Is there a way to find a path in a tree?

Let's say we have a tree like the one below. Is there an algorithm that given 2 nodes find the path that connects them. For example, given (A,E) it will return [A,B,E], or given (D,G) it will return [D,B,A,C,G]
A
/ \
B C
/ \ / \
D E F G
You will need to have a tree implementation where a child node has a link to its parent.
Then for both nodes you can build the path from the node to the root, just by following the parent link.
Then compare the two paths, starting from the ends of the paths (where the root is): as long as they are the same, remove that common node from both paths.
Finally you are left with two diverting paths. Reverse the second, and join the two paths, putting the last removed node in between the two.
Here is an implementation in JavaScript:
function getPathToRoot(a) {
if (a.parent == null) return [a];
return [a].concat(getPathToRoot(a.parent));
}
function findPath(a, b) {
let p = getPathToRoot(a);
let q = getPathToRoot(b);
let common = null;
while (p.length > 0 && q.length > 0 && p[p.length-1] == q[q.length-1]) {
common = p.pop();
q.pop();
}
return p.concat(common, q.reverse());
}
// Create the example tree
let nodes = {};
for (let label of "ABCDEFG") {
nodes[label] = { label: label, parent: null };
}
nodes.B.parent = nodes.C.parent = nodes.A;
nodes.D.parent = nodes.E.parent = nodes.B;
nodes.F.parent = nodes.G.parent = nodes.C;
// Perform the algorithm
let path = findPath(nodes.E, nodes.G);
// Output the result
console.log("Path from E to G is:");
for (let node of path) {
console.log(node.label);
}

How to best build a persistent binary tree from a sorted stream

For a side project I wanted a simple way to generate a persistent binary search tree from a sorted stream. After some cursory searching I was only able to find descriptions of techniques that involved storing a sorted array where you can access any element by index. I ended up writing something that works but I figured this is well trodden territory and a canonical example is probably documented somewhere (and probably has a name).
The make shift code I made is included just for clarity. (It's also short)
object TreeFromStream {
sealed trait ImmutableTree[T] {
def height: Int
}
case class ImmutableTreeNode[T](
value: T,
left: ImmutableTree[T],
right: ImmutableTree[T]
) extends ImmutableTree[T] {
lazy val height = left.height + 1
}
case class NilTree[T]() extends ImmutableTree[T] {
def height = 0
}
#tailrec
def treeFromStream[T](
stream: Stream[T],
tree: ImmutableTree[T] = NilTree[T](),
ancestors: List[ImmutableTreeNode[T]] = Nil
): ImmutableTree[T] = {
(stream, ancestors) match {
case (Stream.Empty, _) =>
ancestors.foldLeft(tree) { case(right, root) => root.copy(right=right) }
case (_, ancestor :: nextAncestors) if ancestor.left.height == tree.height =>
treeFromStream(stream, ancestor.copy(right=tree), nextAncestors)
case (next #:: rest, _) =>
treeFromStream(
rest, NilTree(),
ImmutableTreeNode(next, tree, NilTree()) :: ancestors
)
}
}
}
To create a balanced tree, which I will guess you want to do, you will need to visit each node at least once. First, collect all the nodes into a buffer, and then recursively convert the buffer into a tree:
def tfs[T](stream: Stream[T]): ImmutableTree[T] = {
val ss = scala.collection.mutable.ArrayBuffer.empty[T]
def treeFromSubsequence(start: Int, end: Int): ImmutableTree[T] =
if (end == start) NilTree()
else if (end - start == 1) ImmutableTreeNode(ss(start), NilTree(), NilTree())
else {
val mid = (end - start) / 2
ImmutableTreeNode(ss(mid), treeFromSubsequence(start, mid), treeFromSubsequence(mid + 1, end))
}
stream.foreach { x => ss += x }
treeFromSubsequence(0, ss.length)
}
It will visit each value exactly twice, once to collect it and once to put it into the value field of a tree.

Scala - Shortest Path Between Two Nodes Recursive Algorithm

I am implementing Dijkstra's shortest path algorithm recursivingly in Scala, but I am having some trouble. I am getting the incorrect output for nodes 3 to 2, called like this, shortestPath(3, 2, x, BitSet.empty). This outputs 6, but the correct answer should be 7. I cannot seem to figure out what's wrong with my code.
var x = ListBuffer(ListBuffer(0, 2, 3, 4),
ListBuffer(2, 0, 0, 0),
ListBuffer(3, 0, 0, 0),
ListBuffer(4, 0, 0, 0))
My code is here shown below.
def shortestPath(cur: Int, dest: Int, graph: ListBuffer[ListBuffer[Int]], visited: BitSet) :Int = {
val newVisited = visited + cur
if(cur == dest) 0
else {
var pathLength = for(i <- graph(cur).indices; if(!visited(i) && graph(cur)(i) > 0)) yield {
graph(cur)(i) + shortestPath(i, dest, graph, newVisited)
}
if (pathLength.isEmpty) 0 else pathLength.min
}
}
As pointed out by obourgain, the critical error of the code is at interpreting the min-distance as 0 when two nodes are not connected.
The min-distance between two nodes should be infinity if they are disconnected, this is because the cost of two disconnected nodes must be greater than the cost of any connected nodes, and one simple fix to your code is to identify infinity with Int.MaxValue.
def shortestPath(cur: Int, dest: Int, graph: ListBuffer[ListBuffer[Int]], visited: BitSet) :Int = {
val newVisited = visited + cur
if(cur == dest) 0
else {
var pathLength = for(i <- graph(cur).indices; if(!visited(i) && graph(cur)(i) > 0)) yield {
val sLen = shortestPath(i, dest, graph, newVisited)
if (graph(cur)(i) > Int.MaxValue - sLen) Int.MaxValue else graph(cur)(i) + sLen // change #1
}
if (pathLength.isEmpty) Int.MaxValue else pathLength.min // change #2
}
}
This modification will give the expected answer Int = 7 when invoking shortestPath(3, 2, x, new BitSet()).
The code commented with "change #1" is to prevent integer overflow when the destination node is not reachable by the neighbor node (thus the min-distance is Int.MaxValue), and the code commented with "change #2" is to treat the min-distance between two nodes as "infinite" when they are disconnected.
The error is on the last line:
if (pathLength.isEmpty) 0 else pathLength.min
If pathLength.isEmpty, it means the two points are not connected. However, the function returns 0, which is interpreted as a connection with weight 0.

Applying popbio "projection.matrix" to multiple fertilities and generate list of matrices

I usually find the answers to my questions by looking around here (I'm glad stackovergflow exists!), but I haven't found the answer to this one... I hope you can help me :)
I am using the projection.matrix() function from the "popbio" package to create transition matrices. In the function, you have to specify the "stage" and "fate" (both categorical variables), and the "fertilities" (a numeric column).
Everything works fine, but I would like to apply the function to 1:n fertility columns within the data frame, and get a list of matrices generated from the same categorical variables with the different fertility values.
This is how my data frame looks like (I only include the variables I am using for this question):
stage.fate = data.frame(replicate(2, sample(0:6,40,rep=TRUE)))
stage.fate$X1 = as.factor(stage.fate$X1)
stage.fate$X2 = as.factor(stage.fate$X2)
fertilities = data.frame(replicate(10,rnorm(40, .145, .045)))
df = cbind(stage.fate, fertilities)
colnames(df)[1:2]=c("stage", "fate")
prefix = "control"
suffix = seq(1:10)
fer.names = (paste(prefix ,suffix , sep="."))
colnames(df)[3:12] = c(fer.names)
Using
library(popbio)
projection.matrix(df, fertility=control.1)
returns a single transition matrix with the fertility values incorporated into the matrix.
My problem is that I would like to generate a list of matrices with the different fertility values in one go (in reality the length of my data is >=300, and the fertility columns ~100 for each of four different treatments...).
I will appreciate your help!
-W
PS This is how the function in popbio looks like:
projection.matrix =
function (transitions, stage = NULL, fate = NULL, fertility = NULL,
sort = NULL, add = NULL, TF = FALSE)
{
if (missing(stage)) {
stage <- "stage"
}
if (missing(fate)) {
fate <- "fate"
}
nl <- as.list(1:ncol(transitions))
names(nl) <- names(transitions)
stage <- eval(substitute(stage), nl, parent.frame())
fate <- eval(substitute(fate), nl, parent.frame())
if (is.null(transitions[, stage])) {
stop("No stage column matching ", stage)
}
if (is.null(transitions[, fate])) {
stop("No fate column matching ", fate)
}
if (missing(sort)) {
sort <- levels(transitions[, stage])
}
if (missing(fertility)) {
fertility <- intersect(sort, names(transitions))
}
fertility <- eval(substitute(fertility), nl, parent.frame())
tf <- table(transitions[, fate], transitions[, stage])
T_matrix <- try(prop.table(tf, 2)[sort, sort], silent = TRUE)
if (class(T_matrix) == "try-error") {
warning(paste("Error sorting matrix.\n Make sure that levels in stage and fate columns\n match stages listed in sort option above.\n Printing unsorted matrix instead!\n"),
call. = FALSE)
sort <- TRUE
T_matrix <- prop.table(tf, 2)
}
T_matrix[is.nan(T_matrix)] <- 0
if (length(add) > 0) {
for (i in seq(1, length(add), 3)) {
T_matrix[add[i + 0], add[i + 1]] <- as.numeric(add[i +
2])
}
}
n <- length(fertility)
F_matrix <- T_matrix * 0
if (n == 0) {
warning("Missing a fertility column with individual fertility rates\n",
call. = FALSE)
}
else {
for (i in 1:n) {
fert <- tapply(transitions[, fertility[i]], transitions[,
stage], mean, na.rm = TRUE)[sort]
F_matrix[i, ] <- fert
}
}
F_matrix[is.na(F_matrix)] <- 0
if (TF) {
list(T = T_matrix, F = F_matrix)
}
else {
T_matrix + F_matrix
}
}
<environment: namespace:popbio>
My question was answered via ResearchGate by Caner Aktas
Answer:
fertility.list<-vector("list",length(suffix))
names(fertility.list)<-fer.names
for(i in suffix) fertility.list[[i]]<-projection.matrix(df,fertility=fer.names[i])
fertility.list
Applying popbio “projection.matrix” to multiple fertilities and generate list of matrices?. Available from: https://www.researchgate.net/post/Applying_popbio_projectionmatrix_to_multiple_fertilities_and_generate_list_of_matrices#5578524f60614b1a438b459b [accessed Jun 10, 2015].

Pouring water using Scala

I am trying to solve the pouring water problem from codechef using scala. The problem statement is as follows:
Given two vessels, one of which can accommodate a liters of water and
the other which can accommodate b liters of water, determine the
number of steps required to obtain exactly c liters of water in one of
the vessels.
At the beginning both vessels are empty. The following operations are
counted as 'steps':
emptying a vessel,
filling a vessel,
pouring water from one vessel to the other, without spilling, until one of the vessels is either full or empty.
Input
An integer t, 1<=t<=100, denoting the number of test cases, followed
by t sets of input data, each consisting of three positive integers a
(the number of liters the first container can hold), b (the number of
liters the second container can hold), and c (the final amount of
liters of water one vessel should contain), not larger than 40000,
given in separate lines.
Output
For each set of input data, output the minimum number of steps
required to obtain c liters, or -1 if this is impossible.
Example Sample input:
2
5
2
3
2
3
4
Sample output:
2
-1
I am approaching this problem as a graph theory problem. Given the initial configuration of containers to be (0, 0), I get the next state of the containers by applying the operations:
FillA, FillB, PourAtoB, PourBtoA, EmptyA, EmptyB recursively until the target is reached.
My code is as follows:
import scala.collection.mutable.Queue
def pour(initA:Int, initB:Int, targetCapacity:Int) {
var pourCombinations = new scala.collection.mutable.HashMap[(Int, Int),Int]
val capacityA = initA
val capacityB = initB
val processingQueue = new Queue[(Int, Int, Int, Int)]
def FillA(a:Int, b:Int) = {
(capacityA, b)
}
def FillB(b:Int, a:Int) = {
(a, capacityB)
}
def PourAtoB(a:Int, b:Int): (Int, Int) = {
if((a == 0) || (b == capacityB)) (a, b)
else PourAtoB(a - 1, b + 1)
}
def PourBtoA(b:Int, a:Int): (Int, Int) = {
if((b == 0) || (a == capacityA)) (a, b)
else PourBtoA(b - 1, a + 1)
}
def EmptyA(a:Int, b:Int) = {
(0, b)
}
def EmptyB(a:Int, b:Int) = {
(a, 0)
}
processingQueue.enqueue((0, 0, targetCapacity, 0))
pourCombinations((0, 0)) = 0
def pourwater(a:Int, b:Int, c:Int, numSteps:Int): Int = {
println(a + ":" + b + ":" + c + ":" + numSteps)
if((a == c) || (b == c)) {return numSteps}
if(processingQueue.isEmpty && (pourCombinations((a,b)) == 1)) {return -1}
//Put all the vals in a List of tuples
val pStateList = scala.List(FillA(a, b), FillB(a, b), PourAtoB(a, b), PourBtoA(b, a), EmptyA(a, b), EmptyB(a, b))
pStateList.foreach{e =>
{
if(!pourCombinations.contains(e)) {
pourCombinations(e) = 0
processingQueue.enqueue((e._1, e._2, c, numSteps + 1))
}
}
}
pourCombinations((a, b)) = 1
val processingTuple = processingQueue.dequeue()
pourwater(processingTuple._1, processingTuple._2, processingTuple._3, processingTuple._4)
}
val intialvalue = processingQueue.dequeue()
pourwater(intialvalue._1, intialvalue._2, intialvalue._3, intialvalue._4)
}
There are a couple of issues with this, first of all I am not sure if I have my base cases of my recursive step set-up properly. Also, it might be that I am not using the proper Scala conventions to solve this problem. Also, I want the pour function to return the numSteps once it is finished executing. It is not doing that at the moment.
It will be great if somebody can go through my code and point out the mistakes with my approach.
Thanks

Resources