Java JUNG EdmondsKarpMaxFlow getting stuck in infinite loop - java

I am trying to use JUNG's EdmondsKarpMaxFlow object to find the max flow between all node pairs in a directed graph. I created a simple directed graph and ran it on each combination of nodes with no error. Here's the working example for reference:
https://pastebin.com/TLsEduxZ
However, when I call the same 'edkAlg.evaluate()' code on a more complex graph, the loop stops on a certain edge/iteration each time.
public class SomeClass{
...
...
MyEdmondsKarpMaxFlow edk = new MyEdmondsKarpMaxFlow(dirGraph);
edk.runEdk();
}
public class MyEdmondsKarpMaxFlow {
int edgeFlowMapId = 0;
protected DirectedSparseMultigraph<GraphElements.MyVertex, GraphElements.MyEdge> dirGraph;
protected Map<GraphElements.MyEdge, Double> edgeFlowMap = new HashMap<GraphElements.MyEdge, Double>();
protected Transformer<GraphElements.MyEdge, Double> capTransformer = new Transformer<GraphElements.MyEdge, Double>() {
public Double transform(GraphElements.MyEdge edge) {
return edge.getCapacity();
}
};
// This Factory produces new edges for use by the algorithm
protected Factory<GraphElements.MyEdge> edgeFactory = new Factory<GraphElements.MyEdge>() {
public GraphElements.MyEdge create() {
return new GraphElements.MyEdge(Integer.toString(edgeFlowMapId++));
}
};
public MyEdmondsKarpMaxFlow(DirectedSparseMultigraph<GraphElements.MyVertex, GraphElements.MyEdge> dirGraph) {
this.dirGraph = dirGraph;
}
public void runEdk() {
Collection<GraphElements.MyVertex> vertexCollection = dirGraph.getVertices();
for (Iterator iterator1 = vertexCollection.iterator(); iterator1.hasNext(); ) {
GraphElements.MyVertex v1 = (GraphElements.MyVertex) iterator1.next();
Collection<GraphElements.MyVertex> vertexCollection2 = dirGraph.getVertices();
for (Iterator iterator2 = vertexCollection2.iterator(); iterator2.hasNext(); ) {
GraphElements.MyVertex v2 = (GraphElements.MyVertex) iterator2.next();
if (v1.equals(v2)) continue;
EdmondsKarpMaxFlow<GraphElements.MyVertex, GraphElements.MyEdge> edkAlg = new EdmondsKarpMaxFlow(dirGraph, v1, v2, capTransformer, edgeFlowMap, edgeFactory);
edkAlg.evaluate();
System.out.println("max edk flow between v1 and v2 is : " + edkAlg.getMaxFlow());
}
}
System.out.println("FIN");
}
}
I use custom definitions of Vertices and Edges which behave as expected but simply have more attributes than the trivial example. The code finds max flow between v1 and v2 perfectly fine up to the first 201 iterations, but gets stuck in '.evaluate()' after each time (it uses the same order of pairs each time so it is always stuck on problemNode123 -> problemNode456). Not too sure where I'm going wrong, and there isn't much help online so any pointers are appreciated!

You're not providing quite enough information to be sure, but the problem is almost certainly related to the fact that you haven't defined hashCode() and equals() for your custom node and edge objects.

Related

Bfs game Map implementation in java

I'm trying to implement a bfs algorithm in Java,but it doesn't work as it should be.
I've made a game map comprised of HexTile objects(custom objects,similar to matrix elements). Each HexTile includes one adjacency list containing references to the elements that it's connected to, one function that returns those elements and one function that computes the distance between two HexTiles. The bfs algorithm is excecuted in another class called unit(units are placed in HexTiles) and finds every unit available in a given range from the room(currentTile). It then creates an ArrayList with the given units.
class HexTile {
static final int MAX_NEIGHBOURS = 6;
private HexTile[] neighbours;
public HexTile[] getNeighbours() {
return this.neighbours;
}
public double distanceFromTarget(HexTile target) {
double distance = Math.sqrt(Math.pow((this.getRow() - target.getRow()), 2) + Math.pow((this.getCol() - target.getCol()), 2));
return distance;
}
}
class Unit {
private ArrayList<Unit> unitsWithinRange = new ArrayList<Unit>();
private void findUnitsWithinRange(HexTile currentTile, int attackRange) {
Queue<HexTile> queue = new LinkedList<>();
ArrayList<HexTile> visited = new ArrayList<HexTile>();
queue.add(currentTile);
visited.add(currentTile);
while (!queue.isEmpty()) {
HexTile aux = queue.poll();
for (HexTile auxNeigh : aux.getNeighbours()) {
if (auxNeigh != null && (!visited.contains(auxNeigh))) {
visited.add(auxNeigh);
queue.add(auxNeigh);
}
}
if (aux != null && (currentTile.distanceFromTarget(aux) <= attackRange)) {
Unit auxUnit = aux.getUnitOnTile();
this.unitsWithinRange.add(auxUnit);
}
}
queue.clear();
visited.clear();
}
}
What happens whenever findUnitsWithinRange is excecuted is that it return a list of units,but the units that are in range 1 are not included(direct neighbours to root).Sometimes the program crashes,because units need to be able to know if there are any nearby units,to excecute some other functions.Any advice would be appreciated!

Jenetics , how to find subset of set using GA

I am trying to find best subset of set. Imagine that we need to find subset of objects. We have got some fitness function for this subset. So at the beginning we should make a population of subsets and then using GA we should try to find the best subset.
I would like to use Jenetics.io but I do not know how to use it in this case. Problem for me is that chromosomes are much different data structure than subset.
I would like to have a function( population, fitness function) which makes all needed job.
I tried to understand how Jenetics exactly works. Maybe I am wrong but I think there is no way to make it works the way I want.
Please give me advice , maybe there is option to use Jenetics in this case?
There is a sub-set example in the Jenetics library. Essentially, it has the following form:
class SubsetExample
implements Problem<ISeq<MyObject>, EnumGene<MyObject>, Double>
{
// Define your basic set here.
private final ISeq<MyObject> basicSet = ISeq.empty();
private final int subSetSize = 5;
#Override
public Function<ISeq<MyObject>, Double> fitness() {
return subSet -> {
assert(subset.size() == subSetSize);
double fitness = 0;
for (MyObject obj : subSet) {
// Do some fitness calculation
}
return fitness;
};
}
#Override
public Codec<ISeq<MyObject>, EnumGene<MyObject>> codec() {
return codecs.ofSubSet(basicSet, subSetSize);
}
public static void main(final String[] args) {
final SubsetExample problem = new SubsetExample()
final Engine<EnumGene<MyObject>, Double> engine = Engine.builder(problem)
.minimizing()
.maximalPhenotypeAge(5)
.alterers(
new PartiallyMatchedCrossover<>(0.4),
new Mutator<>(0.3))
.build();
final Phenotype<EnumGene<MyObject>, Double> result = engine.stream()
.limit(limit.bySteadyFitness(55))
.collect(EvolutionResult.toBestPhenotype());
System.out.print(result);
}
}

Dijkstra's algorithm in Java - Multiple requests/threads

I am trying to implement Dijkstra’s algorithm in Java REST webservice, I used this link for my help.
In this link, it is creating only one graph and calculating one route successfully. But in my program, I am creating multiple graphs and using different variables as cost for each graph. Then I use ExecutorService (total threads = total number of graphs) to find all paths in parallel. My program is working fine when I call it to test paths.
The problem is, when this algorithm receives multiple requests at the same time, it is returning “Unreached” message in printPath() function for some requests, and returning correct paths for other requests successfully. I tested each path one by one, and it is returning correct path each time without any error. Problem occurs only when webservice receives multiple requests at the same time. Below is my code, I only posted classes structure which I am using, rest of the code is same as in above mentioned link.
This is how I am using ExecutorService to find path:
List<RouteFutureResult> rfutureResult = new ArrayList();
executorService = Executors.newFixedThreadPool(graphs.size());//number of threads is equal to number of graphs
for (final Graph g : graphs) {
CalcRoutes calcRoutes = new CalcRoutes(g, other_parameters);
Future<String> submit = executorService.submit(calcRoutes);
rfutureResult.add(new RouteFutureResult(submit));
}
executorService.shutdown();
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
//reading response from future object
List<String> st = new ArrayList();
for (RouteFutureResult resQuery : rfutureResult) {
String path = resQuery.getFuture().get();
st.add(path);
}
This is my CalcRoutes.java call function:
#Override
public String call() throws Exception {
List<Double> djst = new ArrayList();
g.dijkstra(s);
List<Double> st = g.printPath(d, djst);
//other processing and returning results
}
Here is the Graph class which I used from mentioned link:
class Graph {
private final Map<Double, Vertex> graph;
public class Edge {
public final double v1, v2;
public final double dist;
}
public class Vertex implements Comparable<Vertex> {
public final double name;
double gid;
public double dist = Double.MAX_VALUE;
public Vertex previous = null;
public final Map<Vertex, Double> neighbours = new HashMap<>();
private void printPath(List<Double> st) {
if (this == this.previous) {
st.add(this.name);
} else if (this.previous == null) {
System.out.printf("%s(unreached)", this.name);//this is where I am getting a problem when service receives multiple requests at same time
} else {
this.previous.printPath(st);
st.add(this.name);
}
}
}
public Graph(HashMap<Double, RouteResult> edges) {
}
public void dijkstra(double startName) {
if (!graph.containsKey(startName)) {
System.err.printf("Graph doesn't contain start vertex \"%s\"\n", startName);
return;
}
final Vertex source = graph.get(startName);
NavigableSet<Vertex> q = new TreeSet<>();
for (Vertex v : graph.values()) {
v.previous = v == source ? source : null;
v.dist = v == source ? 0 : Double.MAX_VALUE;
q.add(v);
}
dijkstra(q);
}
private void dijkstra(final NavigableSet<Vertex> q) {
Vertex u, v;
while (!q.isEmpty()) {
}
}
public List<Double> printPath(double endName, List<Double> st) {
if (!graph.containsKey(endName)) {
System.err.printf("Graph doesn't contain end vertex \"%s\"\n", endName);
}
graph.get(endName).printPath(st);
return st;
}
}
This is how I am creating multiple graphs:
Graph cost = new Graph(MRoute); //MRoute is the hashmap
graphs.add(cost);//graphs is a list containing multiple graphs
I also checked already posted questions about Dijkstra's algorithm, but I couldn't find any relevant question to my problem. Somehow, this algorithm is unable to handle multiple requests, please guide me, any help would be highly appreciated.

how to filter edges based on weight (or other property) with Jung and display the new network

I have an SparseMultigraph< Node, Edge > g where edges have two attributes:
int weight;
ArrayList<Date> time;
I would like to filter the graph according to weight and time independently. Say I start filtering out according to weight using a JSlider called weightSlider (I am in Netbeans and Swing):
private void weightSliderMouseReleased(java.awt.event.MouseEvent evt) {
// filter network according to weight:
Predicate<Edge> edgeAboveWeight = new Predicate<Edge>() {
#Override
public boolean evaluate(Edge e) {
return e.getWeight() >= weightSlider.getValue();
}
};
EdgePredicateFilter<Node, Edge> edgePredicateFilter = new EdgePredicateFilter<>(edgeAboveWeight);
Graph<Node, Edge> transform = edgePredicateFilter.transform(g);
}
My question is: how do I push the new graph in the visualization, preserving the node position?
Since it is the first time I attempt to do something like that, I might have missed a simpler way to achieve my goal, so any suggestion is more than welcome!
EDIT: I succeeded to implement this with:
private void weightSliderMouseReleased(java.awt.event.MouseEvent evt) {
// filter network according to weight:
Predicate<Edge> edgeAboveWeight = new Predicate<Edge>() {
#Override
public boolean evaluate(Edge e) {
return e.getWeight() >= weightSlider.getValue();
}
};
EdgePredicateFilter<Node, Edge> edgePredicateFilter = new EdgePredicateFilter<>(edgeAboveWeight);
Graph<Node, Edge> transform = edgePredicateFilter.transform(g);
layout.setGraph(transform);
vv.validate();
vv.repaint();
}
Still don't know if it's the most efficient way, but it works...
If you want to filter the actual data, then what you're doing is fine.
If what you want to do is just filter the edges whose weight is below a certain value from being rendered, then you can tell the PluggableRendererContext that directly:
http://jung.sourceforge.net/doc/api/edu/uci/ics/jung/visualization/PluggableRenderContext.html#setEdgeIncludePredicate(org.apache.commons.collections15.Predicate)
This is demonstrated in PluggableRendererDemo.

deep copying a graph structure

I have a graph class with Node's, where each Node can connect to others:
public class Node {
List<Node> connections;
}
I would like to make a deep copy of the entire graph. As a first attempt, I tried making a copy constructor like:
public Node(Node other) {
connections = new ArrayList<Node>();
for (Node n : other.connections) {
connections.add(new Node(n));
}
}
So deep copying a graph would just be:
public Graph deepCopy () {
Graph g = new Graph();
g.nodes = new ArrayList<Node>();
for (Node n : nodes) {
g.nodes.add(new Node(n));
}
}
But that doesn't work as that destroys the connection relationship among the nodes. I am wondering if anyone has suggestions to do this in a simple way? Thanks.
The problem is that you need to copy the identities of the nodes, not just their values. Specifically, when you're copying some node, you need to deal with the identities of the nodes it refers to; that means that a copy constructor, or some other kind of purely local copying mechanism, can't do the job, because it only deals with one node at a time. I'm not sure that makes any sense, but I've typed it and my backspace key doesn't work.
Anyway, what you can do is pass around some other object which can tell which new node corresponds to which old node. If you wanted to be fancy (and who doesn't?) you could refer to this as a graph isomorphism. This can be something as simple as a map. As in this completely untested code:
// in Graph
public Graph deepCopy () {
Graph g = new Graph();
g.nodes = new ArrayList<Node>();
Map<Node, Node> isomorphism = new IdentityHashMap<Node, Node>();
for (Node n : nodes) {
g.nodes.add(n.deepCopy(isomorphism));
}
return g;
}
// in Node
public Node deepCopy(Map<Node, Node> isomorphism) {
Node copy = isomorphism.get(this);
if (copy == null) {
copy = new Node();
isomorphism.put(this, copy);
for (Node connection: connections) {
copy.connections.add(connection.deepCopy(isomorphism));
}
}
return copy;
}
Sergii mentions using serialization; serialization actually does something pretty similar when it traverses an object graph.
Yep, deep copy in java ( not only in java) can be made using memory serialization/deserialization
like this
public static Object copy(Object orig) {
Object obj = null;
try {
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(orig);
out.flush();
out.close();
// Make an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
obj = in.readObject();
}
catch(IOException e) {
e.printStackTrace();
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
return obj;
}
Kinda late input. But I had a similar problem but came to a different solution. But not shure if its bulletproof. So please feel free to comment so I can learn!
I have a Type called "Numbers" because I have no creativity naming stuff.
Each object of type "Numbers" has an internal list that can carry additional objects of type "Numbers" of which each has a list of additional "Numbers" of which each... and so on.
Basicaly you can make a tree structure similar to this:
I solved the deep copy problem by using a recursive copy-constructor inside the "Numbers" class.
Numbers class:
import java.util.ArrayList;
public class Numbers {
private ArrayList<Numbers> numbers = new ArrayList<>();
private int number;
public Numbers(int number) {
this.number = number;
}
public Numbers(Numbers numToCopy) {
this.number = numToCopy.getNumber();
ArrayList<Numbers> list = numToCopy.getNumbers();
for(int i = 0; i < list.size(); i++) {
Numbers n = new Numbers(list.get(i));
numbers.add(n);
}
}
public void addNumber(Numbers i) {
numbers.add(i);
}
public ArrayList<Numbers> getNumbers() {
return numbers;
}
public void setNumber(int i) {
this.number = i;
}
public int getNumber() {
return number;
}
public ArrayList<Numbers> getAllNumbers(ArrayList<Numbers> list) {
int size = numbers.size();
list.addAll(numbers);
for(int i = 0; i < size; i++) {
numbers.get(i).getAllNumbers(list);
}
return list;
}
}
Usage:
import java.util.ArrayList;
public class NumbersTest {
public NumbersTest() {
}
public static void main(String[] args) {
Numbers num0 = new Numbers(0);
Numbers num1 = new Numbers(1);
Numbers num2 = new Numbers(2);
Numbers num3 = new Numbers(3);
Numbers num4 = new Numbers(4);
Numbers num5 = new Numbers(5);
Numbers num6 = new Numbers(6);
num0.addNumber(num1);
num0.addNumber(num2);
num1.addNumber(num3);
num1.addNumber(num4);
num2.addNumber(num5);
num2.addNumber(num6);
num4.addNumber(num6);
//Deep copy here!
Numbers numCopy = new Numbers(num0);
//Change deep down in graph of original
num0.getNumbers().get(0).getNumbers().get(1).getNumbers().get(0).setNumber(799);
//Printout of copy to show it was NOT affected by change in original.
for(Numbers n : numCopy.getAllNumbers(new ArrayList<Numbers>())) {
System.out.println(n.getNumber());
}
}
}
Usage code shows that changing deep inside the "graph" of the original num0 object, does not change the copy made of it.
Theres two sixes (6) in the graph, and thats ok since they are on different branches.
Downside is if same number would repeat through one of the paths, like if there was a (1) somewhere under the first 1. It would then end up in an infinite loop.
Please do comment! :)

Categories

Resources