package circdesignagui.TripleSim;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map.Entry;
import circdesigna.TripleSim.ReactionGraph3X;
import circdesigna.TripleSim.ReactionGraph3X.BimolecularNode;
import circdesigna.TripleSim.ReactionGraph3X.GraphEdge;
import circdesigna.TripleSim.ReactionGraph3X.GraphNode;
import circdesigna.config.CircDesigNAConfig;
public class WidestPath {
private static class StructureComparator implements Comparator<GraphNode>{
public int compare(GraphNode o1, GraphNode o2) {
int a1 = new Integer(o1.structureString);
int a2 = new Integer(o2.structureString);
if (a1 < 0){
a1 += Integer.MAX_VALUE / 2;
}
if (a2 < 0){
a2 += Integer.MAX_VALUE / 2;
}
if (a1 < a2){
return -1;
}
if (a1 > a2){
return 1;
}
return 0;
}
}
private static class ReactionPathway{
public ArrayList<GraphEdge> reactionsInOrder = new ArrayList();
public TreeSet<GraphNode> species = new TreeSet(new StructureComparator());
public void updatePriority(double i, TreeMap<GraphNode, ReactionPathway> memo, PriorityQueue<GraphNode> unvisited) {
for(GraphNode e : species){
if (i < e.priority){
e.priority = i;
memo.put(e, this);
if (!e.visited){
unvisited.remove(e);
unvisited.add(e);
}
}
}
}
}
public static void main(String[] args) throws Throwable{
String inputFile = null;
{
Scanner in = new Scanner(System.in);
System.out.println("Please enter a URL of the .path file");
inputFile = in.nextLine();
}
Scanner in = new Scanner(new File(inputFile));
CircDesigNAConfig config = new CircDesigNAConfig();
TreeMap<String, String[]> pairings = new TreeMap();
ReactionGraph3X.Graph g = new ReactionGraph3X.Graph(config, new Comparator<GraphNode>(){
public int compare(GraphNode o1, GraphNode o2) {
if (o1.priority < o2.priority){
return -1;
} else if (o1.priority == o2.priority){
return 0;
} else {
return 1;
}
}
});
while(in.hasNextLine()){
String lineS = in.nextLine();
if (lineS.equals("END")){
break;
}
String[] line = lineS.split("\\s+");
String[] pair = new String[]{line[1],line[2]};
Arrays.sort(pair);
pairings.put(line[0], pair);
}
while(in.hasNextLine()){
String lineS = in.nextLine();
if (lineS.equals("END")){
break;
}
String[] line = lineS.split("\\s+",3);
GraphNode neu = new GraphNode(line[0]);
neu.genData = new double[]{new Double(line[1])};
g.allSingles.put(neu.structureString, neu);
}
for(Entry<String, String[]> pair : pairings.entrySet()){
BimolecularNode pairing = new BimolecularNode(pair.getKey(),g.allSingles.get(pair.getValue()[0]),g.allSingles.get(pair.getValue()[1]));
g.allSingles.put(pairing.structureString, pairing);
g.allDockings.put(pair.getValue()[0]+" "+pair.getValue()[1], pairing);
}
pairings = null;
while(in.hasNextLine()){
String lineS = in.nextLine();
if (lineS.equals("END")){
break;
}
String[] line = lineS.split("\\s+",4);
GraphEdge edge = new GraphEdge();
edge.k = new Double(line[2]);
edge.type = line[3];
edge.towards = g.allSingles.get(line[1]);
GraphNode from = g.allSingles.get(line[0]);
edge.reverse = new GraphEdge();
edge.reverse.towards = from;
from.neighbors.add(edge);
}
in.close();
for(GraphNode p : g.allSingles.values()){
p.priority = Double.POSITIVE_INFINITY;
}
g.unvisited.clear();
for(GraphNode p : g.allSingles.values()){
g.unvisited.add(p);
}
TreeMap<GraphNode, ReactionPathway> memo = new TreeMap(new StructureComparator());
{
ReactionPathway initialConditions = new ReactionPathway();
for(String n : g.allSingles.keySet()){
int val = new Integer(n);
if (val >= 0 && val <= 12){
initialConditions.species.add(g.allSingles.get(n));
}
};
initialConditions.updatePriority(0, memo, g.unvisited);
};
while(!g.unvisited.isEmpty()){
System.out.println(g.unvisited.size());
GraphNode visit = g.unvisited.poll();
if (visit.visited){
throw new RuntimeException();
}
visit.visited = true;
ReactionPathway bestFamily = memo.get(visit);
if (bestFamily == null){
break;
}
if (visit.isMonoMolecular()){
//Try to combine two monomolecule pathways
for(GraphNode brother : g.allSingles.values()){
if(!brother.visited){
continue;
}
GraphNode dock = g.allDockings.get(visit.structureString+" "+brother.structureString);
if (dock==null){
dock = g.allDockings.get(brother.structureString+" "+visit.structureString);
}
if(dock==null){
continue;
}
ReactionPathway brotherPath = memo.get(brother);
boolean obviousShortestPath = false;
if (brotherPath.species.contains(visit)){
if (brother.priority < dock.priority){
brotherPath.species.add(dock);
brotherPath.updatePriority(brother.priority, memo, g.unvisited);
obviousShortestPath = true;
}
}
if (bestFamily.species.contains(brother)){
if (visit.priority < dock.priority){
bestFamily.species.add(dock);
bestFamily.updatePriority(visit.priority, memo, g.unvisited);
obviousShortestPath = true;
}
}
if (!obviousShortestPath){
ReactionPathway unionPath = new ReactionPathway();
unionPath.species.addAll(bestFamily.species);
unionPath.species.addAll(brotherPath.species);
double edgePriority = visit.priority;
for(GraphEdge rxn : bestFamily.reactionsInOrder){
unionPath.reactionsInOrder.add(rxn);
}
for(GraphEdge rxn : brotherPath.reactionsInOrder){
boolean alreadyAdded = false;
for(GraphEdge q : bestFamily.reactionsInOrder){
if (q == rxn){
alreadyAdded = true;
break;
}
}
if (!alreadyAdded){
unionPath.reactionsInOrder.add(rxn);
edgePriority += 1. / rxn.k;
}
}
if (edgePriority > dock.priority){
throw new RuntimeException();
}
unionPath.species.add(dock);
if (edgePriority < dock.priority){
unionPath.updatePriority(edgePriority, memo, g.unvisited);
}
}
}
}
//Visit edges
for(GraphEdge edge : visit.neighbors){
GraphNode towards = edge.towards;
if (edge.k <= 0){
continue;
}
double edgePriority = visit.priority + 1. / edge.k;
if (edgePriority < towards.priority){
ReactionPathway newFamily = new ReactionPathway();
newFamily.species.addAll(bestFamily.species);
newFamily.species.add(towards);
if (towards.isBiMolecular()){
for(GraphNode component : ((BimolecularNode)towards).associate){
newFamily.species.add(component);
}
}
newFamily.reactionsInOrder.addAll(bestFamily.reactionsInOrder);
newFamily.reactionsInOrder.add(edge);
newFamily.updatePriority(edgePriority, memo, g.unvisited);
}
}
}
in = new Scanner(System.in);
while(true){
System.out.println("All-Shortest-Paths solved. Please enter in the name of a target:");
String targetS = in.nextLine();
GraphNode target = g.allSingles.get(targetS);
if (target==null){
continue;
}
ReactionPathway reactionPathway = memo.get(target);
if (reactionPathway==null){
continue;
}
TreeSet<GraphNode> actuallyUsed = new TreeSet(new StructureComparator());
//Output a .s file of the graph with optimum path labeled...
for(GraphEdge p : reactionPathway.reactionsInOrder){
actuallyUsed.add(p.reverse.towards);
actuallyUsed.add(p.towards);
}
for(GraphNode p : actuallyUsed){
System.out.print(p.structureString+"; ");
}
System.out.println();
for(GraphNode p : actuallyUsed){
if (p.isBiMolecular()){
for(GraphNode a : ((BimolecularNode)p).associate){
System.out.println(p.structureString+" [shape=point]");
System.out.println(p.structureString+" -> "+a.structureString+" [dir=none]");
}
}
}
for(GraphEdge p : reactionPathway.reactionsInOrder){
System.out.println(p.reverse.towards.structureString+" -> "+p.towards.structureString);
}
for(GraphEdge p : reactionPathway.reactionsInOrder){
System.out.println(p.type);
}
}
}
}