package edu.nd.nina.alg;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import edu.nd.nina.Graphs;
import edu.nd.nina.Type;
import edu.nd.nina.graph.TypedSimpleGraph;
import edu.nd.nina.math.Moment;
import edu.nd.nina.structs.Triple;
public class ConstrainedRandomWalkWithRestart {
float restartProbability;
TypedSimpleGraph tsg;
public ConstrainedRandomWalkWithRestart(TypedSimpleGraph tsg,
float restartProbability) {
this.restartProbability = restartProbability;
this.tsg = tsg;
}
public Triple<Map<Type, Integer>, Float, Map<Type, Moment>> allTopoCounts(
MetaPath constraint, Integer maxIters) {
Triple<Map<Type, Integer>, Float, Map<Type, Moment>> pathCount =
new Triple<Map<Type, Integer>, Float, Map<Type, Moment>>(
new HashMap<Type, Integer>(), 0f, new HashMap<Type, Moment>());
// start recursion Graphs.neighborListOf(tsg, start);
MetaPath mp = new MetaPath(constraint.getStart(), constraint.getEnd());
allTopoCounts(tsg, mp.getStart(), constraint, mp, 1f, maxIters, pathCount);
return pathCount;
}
public Triple<Map<Type, Integer>, Float, Map<Type, Moment>> allTopoCounts(
MetaPath constraint) {
Triple<Map<Type, Integer>, Float, Map<Type, Moment>> pathCount =
new Triple<Map<Type, Integer>, Float, Map<Type, Moment>>(
new HashMap<Type, Integer>(), 0f, new HashMap<Type, Moment>());
// start recursion Graphs.neighborListOf(tsg, start);
MetaPath mp = new MetaPath(constraint.getStart(), constraint.getEnd());
allTopoCounts(tsg, mp.getStart(), constraint, mp, 1f, Integer.MAX_VALUE, pathCount);
return pathCount;
}
private boolean allTopoCounts(TypedSimpleGraph tsg, Type start,
MetaPath constraint, MetaPath path, float weight, int maxIters,
Triple<Map<Type, Integer>, Float, Map<Type, Moment>> pathCount) {
List<Type> l = Graphs.neighborListOf(tsg, start);
float s = 0f;
int i = 0;
for (Type t : l) {
if (++i > maxIters)
continue;
if (constraint.matches(path, t.getClass())) {
s++;
}
}
i = 0;
for (Type t : l) {
if (++i > maxIters)
continue;
if (constraint.matches(path, t.getClass())) {
float w = weight * ((1f - restartProbability) / (float) s);
path.addToPath(t.getClass());
if (constraint.matchesFully(path)) {
pathCount.v2++;
if (pathCount.v1.containsKey(t)) {
Moment m = pathCount.v3.get(t);
m.add(w);
pathCount.v3.put(t, m);
Integer i2 = pathCount.v1.get(t);
i2++;
pathCount.v1.put(t, i2);
} else {
pathCount.v1.put(t, 1);
Moment m = new Moment();
m.add(w);
pathCount.v3.put(t, m);
}
path.removeLast();
continue;
}
allTopoCounts(tsg, t, constraint, path, w, maxIters, pathCount);
path.removeLast();
}
}
return false;
}
public Map<Type, Integer> pathCount(MetaPath constraint) {
Map<Type, Integer> pathCount = new HashMap<Type, Integer>();
// start recursion Graphs.neighborListOf(tsg, start);
MetaPath mp = new MetaPath(constraint.getStart(), constraint.getEnd());
pathCount(tsg, mp.getStart(), constraint, mp, pathCount);
return pathCount;
}
private boolean pathCount(final TypedSimpleGraph tsg, final Type start,
final MetaPath constraint, MetaPath path,
Map<Type, Integer> pathCount) {
List<Type> l = Graphs.neighborListOf(tsg, start);
for (Type t : l) {
if (constraint.matches(path, t.getClass())) {
path.addToPath(t.getClass());
if (constraint.matchesFully(path)) {
if (pathCount.containsKey(t)) {
Integer m = pathCount.get(t);
m++;
pathCount.put(t, m);
} else {
pathCount.put(t, 1);
}
path.removeLast();
continue;
}
pathCount(tsg, t, constraint, path, pathCount);
path.removeLast();
}
}
return false;
}
public Map<Type, Moment> randomWalk(MetaPath constraint) {
Map<Type, Moment> randomWalk = new HashMap<Type, Moment>();
// start recursion Graphs.neighborListOf(tsg, start);
MetaPath mp = new MetaPath(constraint.getStart());
randomWalk(tsg, constraint.getStart(), constraint, mp, 1f, randomWalk);
return randomWalk;
}
private boolean randomWalk(TypedSimpleGraph tsg, Type start,
MetaPath constraint, MetaPath path, float weight,
Map<Type, Moment> randomWalk) {
List<Type> l = Graphs.neighborListOf(tsg, start);
float s = 0f;
for (Type t : l) {
if (constraint.matches(path, t.getClass())) {
s++;
}
}
for (Type t : l) {
if (constraint.matches(path, t.getClass())) {
float w = weight * ((1f - restartProbability) / (float) s);
path.addToPath(t.getClass());
if (constraint.matchesFully(path)) {
if (randomWalk.containsKey(t)) {
Moment m = randomWalk.get(t);
m.add(w);
randomWalk.put(t, m);
} else {
Moment m = new Moment();
m.add(w);
randomWalk.put(t, m);
}
path.removeLast();
continue;
}
randomWalk(tsg, t, constraint, path, w, randomWalk);
path.removeLast();
}
}
return false;
}
public Integer pathNormCount(MetaPath constraint) {
// start recursion Graphs.neighborListOf(tsg, start);
MetaPath mp = new MetaPath(constraint.getStart());
return pathNormCount(tsg, constraint.getStart(), constraint, mp, 0);
}
private Integer pathNormCount(final TypedSimpleGraph tsg, final Type start,
final MetaPath constraint, MetaPath path, Integer pathCount) {
List<Type> l = Graphs.neighborListOf(tsg, start);
for (Type t : l) {
if (constraint.matches(path, t.getClass())) {
path.addToPath(t.getClass());
if (constraint.matchesFully(path)) {
pathCount++;
path.removeLast();
continue;
}
pathCount = pathNormCount(tsg, t, constraint, path, pathCount);
path.removeLast();
}
}
return pathCount;
}
}