package tspAco;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import pec.Event;
import pec.PEC;
import pec.PQPEC;
import graph.AdjListGraph;
import graph.InvalidGraphException;
/**
* Main class for Traveling Salesman Problem solving
* with Ant Colony Optimization. This class extends java.lang.Thread and
* overrides the run() method to simulate TSP-ACO. First, the simulation parameters and the graph are read from the
* xml file provided in the class constructor. Secondly, the PEC is filled with the first <antColSize>
* Mevents and an Observation Event. After that, the main function begins a cycle of removing Events from the PEC
* and adding new Events if they are generated. The output
* of the program are 20 observations of the system's current
* state and is redirected to the console. The simulation finishes when a
* finish Exception is caught.
*
* @author Sebastiao Miranda, 67713. sebastiao.miranda@outlook.com
* @author Tomas Ferreirinha, 67725. tomas619@hotmail.com
*/
public class TspAcoSimulator extends Thread{
/**
* Size of the ant colony
*/
public static Integer antColSize;
/**
* File from which to read the simulation.
*/
private File file;
/**
* Create a new TspAcoSimulator.
* @param file File from which to read the simulation.
*/
public TspAcoSimulator(File file){
this.file = file;
}
@Override
@SuppressWarnings("unchecked")
/**
* Thread Run Method of the TspAcoSimulator class. First, the simulation parameters and the graph are read from the
* xml file provided in the class constructor. Secondly, the PEC is filled with the first <antColSize>
* Mevents and an Observation Event. After that, the main function begins a cycle of removing Events from the PEC
* and adding new Events if they are generated. The simulation finishes when a
* finish Exception is caught.
*/
public void run(){
Event event;
LinkedList<ACOEvent> newEventList;//list to hold newly generated events
/*Create a new Adjacency list graph and pass its reference to the
*SaxParser.*/
AdjListGraph<Float> graph = new AdjListGraph<Float>();
try {
SimParser saxParser = new SimParser(graph, file);
saxParser.parse();
}catch (IOException e){
System.out.println("Failed to open dtd file: The file simulation.dtd must be in the same directory of the " +
"xml simulation file");
//e.printStackTrace();
return;
}catch (ParserConfigurationException e){
System.out.println("SAX related Error: "+e.getMessage());
//e.printStackTrace();
return;
}catch (SAXException e){
System.out.println("SAX related Error: "+e.getMessage());
//e.printStackTrace();
return;
}
/*Create a new PriorityQueue-PEC and fill it with a new
*Mevent for each ant in the ant colony*/
PEC pec = new PQPEC();
for(int i=0;i<antColSize;i++){
event = new Mevent(new Float(0), graph);
pec.addEvent(event);
}
/*Create the observation Event and put it in the PEC*/
event = new Observation();
pec.addEvent(event);
/*PEC event retrieval cycle*/
while((event = pec.getEvent())!=null){
try{//Simulate
newEventList = (LinkedList<ACOEvent>)event.processEvent();
}catch (FinishException finish){//If the Event processing throws a finish Exception
//System.out.println("Simulation finished: "+finish.getMessage());
return;//End of Simulation
}catch (InvalidGraphException invg){
System.out.println("Bad Graph Design Error: " + invg.getMessage());
return;
}catch (Exception e){//If the Event processing throws any other exception
System.out.println("Unexpected Error: " + e.getMessage());
//e.printStackTrace();
return;
}
while(!newEventList.isEmpty())//Add new generated Events to the PEC
pec.addEvent(newEventList.removeFirst());
}
return;
}
/**
* Method for reseting the simulation static variables when multiple simulations
* are issued sequentially by the simulator graphical user interface.
*/
public void reset() {
ACOEvent.HamiltonianCycle = null;
ACOEvent.HamiltonianCycleWeight = 0.0f;
ACOEvent.numberOfEevents = 0;
ACOEvent.numberOfMevents = 0;
return;
}
}