package myFlowmap;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
public class Graph
{
private ArrayList<String> vertices = new ArrayList<String>();
private int[] edge_to;
private int[] edge_from;
private double[] edge_lengths;
private boolean[] hasEdgeWeight;
private boolean[] isFixedVertex;
private boolean[] isSuppressed;
private double[] vertx;
private double[] verty;
private int n_vertices;
private int n_edges;
private int max_edges,max_vertices;
public Graph(int e,int v){
this.max_edges=e;
this.max_vertices=v;
this.vertx = new double[v];
this.verty= new double[v];
this.isFixedVertex = new boolean[v];
this.isSuppressed = new boolean[v];
for(int i=0;i<this.max_vertices;i++)
{
this.isFixedVertex[i]=false;
this.isSuppressed[i]=false;
}
this.edge_to = new int[e];
this.edge_from = new int[e];
this.edge_lengths = new double[e];
this.hasEdgeWeight = new boolean[e];
this.n_vertices=0;
this.n_edges=0;
}
public void addVertex(String name){
//Do we have room?
if(this.n_vertices>=max_vertices) { System.out.println("No more vertices allowed"); throw new IllegalArgumentException("Too many vertices");}
this.vertices.add(name);
this.n_vertices++;
}
public void addFixedVertex(String name, double x, double y){
//Do we have room?
if(this.n_vertices>=max_vertices) { System.out.println("No more vertices allowed"); throw new IllegalArgumentException("Too many vertices");}
this.vertices.add(name);
this.vertx[n_vertices]=x;
this.verty[n_vertices]=y;
this.isFixedVertex[n_vertices]=true;
this.n_vertices++;
}
public void addEdge(String name_orig, String name_targ)
{
//Do we have room?
if(this.n_edges>=max_edges) { System.out.println("No more edges allowed"); throw new IllegalArgumentException("Too many edges");}
//Validity checking
boolean validOrig=false;
boolean validTarg=false;
int origIndex=0;
int targIndex=0;
for(int i=0;i<n_vertices;i++)
{
if(this.vertices.get(i).equals(name_orig)){ validOrig=true; origIndex=i;}
if(this.vertices.get(i).equals(name_targ)){ validTarg=true; targIndex=i;}
}
if(!validOrig) { System.out.println("Invalid origin "+name_orig); throw new IllegalArgumentException("Invalid Origin");}
if(!validTarg) { System.out.println("Invalid target "+name_targ); throw new IllegalArgumentException("Invalid Target");}
this.edge_from[n_edges]=origIndex;
this.edge_to[n_edges]=targIndex;
this.hasEdgeWeight[n_edges]=false;
this.n_edges++;
}
public void addEdge(String name_orig, String name_targ, double elength)
{
//Do we have room?
if(this.n_edges>=max_edges) { System.out.println("No more edges allowed"); throw new IllegalArgumentException("Too many edges");}
//Validity checking
boolean validOrig=false;
boolean validTarg=false;
int origIndex=0;
int targIndex=0;
for(int i=0;i<n_vertices;i++)
{
if(this.vertices.get(i).equals(name_orig)){ validOrig=true; origIndex=i;}
if(this.vertices.get(i).equals(name_targ)){ validTarg=true; targIndex=i;}
}
if(!validOrig) { System.out.println("Invalid origin "+name_orig); throw new IllegalArgumentException("Invalid Origin");}
if(!validTarg) { System.out.println("Invalid target "+name_targ); throw new IllegalArgumentException("Invalid Target");}
this.edge_from[n_edges]=origIndex;
this.edge_to[n_edges]=targIndex;
this.edge_lengths[n_edges]=elength;
this.hasEdgeWeight[n_edges]=true;
this.n_edges++;
}
public void printJSON()
{
System.out.println("{\n\t\"nodes\":[");
for(int i=0;i<this.n_vertices;i++){
if(this.isFixedVertex[i])
{
System.out.println("\t\t{\"name\":\""+this.vertices.get(i)+"\", \"x\":"+this.vertx[i]+", \"y\":"+this.verty[i]+", \"fixed\":true, \"type\":\"fixedPoint\"},");
}
else{
System.out.println("\t\t{\"name\":\""+this.vertices.get(i)+"\", \"x\":0, \"y\":0, \"fixed\":false, \"type\":\"mobilePoint\"}"+(i<this.n_vertices-1?",":""));
}
}
System.out.println("\t],");
System.out.println("\t\"edges\": [");
for(int j=0;j<this.n_edges;j++){
System.out.println("\t{\"source\":"+this.edge_from[j]+", \"target\":"+this.edge_to[j]+", \"weight\":"+this.edge_lengths[j]+"}"+(j<this.n_edges-1?",":""));
}
System.out.println("]");
System.out.println("}");
}
public void writeJSON() throws Exception
{
PrintWriter pw = new PrintWriter("graph.json"); pw.close(); //Clears any existing data in graph.json!!!
PrintWriter graphOut = new PrintWriter(new BufferedWriter(new FileWriter("graph.json", true)));
graphOut.println("{\n\t\"nodes\":[");
for(int i=0;i<this.n_vertices;i++){
if(this.isFixedVertex[i])
{
graphOut.println("\t\t{\"name\":\""+this.vertices.get(i)+"\", \"x\":"+this.vertx[i]+", \"y\":"+this.verty[i]+", \"fixed\":true, \"type\":\"fixedPoint\"},");
}
else{
graphOut.println("\t\t{\"name\":\""+this.vertices.get(i)+"\", \"x\":0, \"y\":0, \"fixed\":false, \"type\":\"mobilePoint\"}"+(i<this.n_vertices-1?",":""));
}
}
graphOut.println("\t],");
graphOut.println("\t\"edges\": [");
for(int j=0;j<this.n_edges;j++){
graphOut.println("\t{\"source\":"+this.edge_from[j]+", \"target\":"+this.edge_to[j]+", \"weight\":"+this.edge_lengths[j]+"}"+(j<this.n_edges-1?",":""));
}
graphOut.println("]");
graphOut.println("}");
graphOut.close();
System.out.println("Output written to graph.json");
}
public Graph reHang()
{
System.out.println("Identifying Source-root path");
int currentChild=0;
int currentParent=0;
int suppressedVertices=0;
System.out.println("\tParent of "+this.vertices.get(currentChild)+" is "+this.vertices.get(currentParent));
while(currentParent!=this.max_vertices-1){
//Find new parent
for(int j=0;j<this.max_edges;j++){
//System.out.println("Examining edge "+j+" from "+this.edge_from[j]+" to "+this.edge_to[j]);
if(this.edge_from[j]==currentChild){
currentParent=this.edge_to[j];
break;
}
}
System.out.println("\tParent of "+this.vertices.get(currentChild)+" is "+this.vertices.get(currentParent));
this.isSuppressed[currentParent]=true;
suppressedVertices++;
currentChild=currentParent;
}
Graph rootedMap= new Graph(this.max_edges,this.max_vertices-suppressedVertices);
for(int i=0;i<this.n_vertices;i++){
if(!this.isSuppressed[i]){
if(this.isFixedVertex[i]) rootedMap.addFixedVertex(this.vertices.get(i),this.vertx[i],this.verty[i]);
else rootedMap.addVertex(this.vertices.get(i));
}
}
System.out.println("Rewiring");
for(int j=0;j<this.n_edges;j++){
if(!this.isSuppressed[this.edge_from[j]]){
//edge from a vertex we've kept; does it go somewhere still valid?
if(this.isSuppressed[this.edge_to[j]]){
System.out.println("\tJoining "+this.vertices.get(this.edge_from[j])+" to "+this.vertices.get(0));
rootedMap.addEdge(this.vertices.get(this.edge_from[j]),this.vertices.get(0),this.edge_lengths[j]);
}
else{
rootedMap.addEdge(this.vertices.get(this.edge_from[j]),this.vertices.get(this.edge_to[j]),this.edge_lengths[j]);
}
}
}
return rootedMap;
}
}