314 lines
7.1 KiB
Java
314 lines
7.1 KiB
Java
package chocobar.combi;
|
|
|
|
import java.io.*;
|
|
import java.util.*; // listes
|
|
import java.text.*; // streamtokenizer
|
|
|
|
import exception.*;
|
|
import graph.GenericGraph;
|
|
import graph.Vertice;
|
|
import conf.ChocoConfig;
|
|
|
|
public class Graph implements GenericGraph
|
|
{
|
|
private EdgeModel edgeModel;
|
|
private boolean isListModel;
|
|
private String name;
|
|
private VerticeSet verticeModel;
|
|
|
|
public Graph(){
|
|
this.edgeModel=null;
|
|
this.name=null;
|
|
this.isListModel=false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Constructeur par defaut
|
|
**/
|
|
public Graph(VerticeSet vmodel){
|
|
this.edgeModel=null;
|
|
this.name=null;
|
|
this.isListModel=false;
|
|
this.verticeModel=vmodel;
|
|
}
|
|
|
|
|
|
/**
|
|
* Constructeur d'un graphe non-initialise avec cardV sommets
|
|
**/
|
|
public Graph (VerticeSet vmodel,boolean isList, int cardV){
|
|
this(vmodel);
|
|
this.isListModel=isList;
|
|
if (isList){
|
|
this.edgeModel=new EdgeListModel(cardV);
|
|
} else {
|
|
this.edgeModel=new EdgeMatrixModel(cardV);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructeur d'un graphe initialise a partir
|
|
* du fichier filename
|
|
**/
|
|
public Graph(VerticeSet vmodel,boolean isList, String filename)
|
|
throws ParseException, IOException, FileNotFoundException
|
|
{
|
|
this(vmodel,isList,0);
|
|
this.loadFromFile(filename);
|
|
}
|
|
|
|
/** Initialize the Graph.
|
|
*/
|
|
public int setSize(int size)
|
|
{
|
|
try {
|
|
Class cEM = Class.forName("chocobar.combi."+ChocoConfig.edgeModel);
|
|
this.edgeModel = (EdgeModel) cEM.newInstance();
|
|
this.edgeModel.setSize(size);
|
|
} catch (Exception e) {
|
|
this.edgeModel = null;
|
|
e.printStackTrace();
|
|
|
|
return -1;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
public void addEdge(int x, int y)
|
|
{
|
|
try {
|
|
this.edgeModel.addEdge(x, y);
|
|
} catch (OutOfRangeVerticeException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fonction qui renvoie l'indice du vertice passe
|
|
* en parametre dans le vecteur des vertices de ce graphe
|
|
**/
|
|
public int indexOfVertice(Vertice e){
|
|
return this.verticeModel.getIdOf(e);
|
|
}
|
|
|
|
/**
|
|
* Fonction d'initialisation du graphe a partir d'un fichier
|
|
**/
|
|
public void loadFromFile(String filename)
|
|
throws ParseException, IOException, FileNotFoundException
|
|
{
|
|
int verticeNb;
|
|
FileReader fi=new FileReader(filename);
|
|
StreamTokenizer si=new StreamTokenizer(fi);
|
|
si.eolIsSignificant(false);
|
|
si.lowerCaseMode(false);
|
|
si.parseNumbers();
|
|
|
|
/* parse the name of the graph */
|
|
si.nextToken();
|
|
if (si.ttype==StreamTokenizer.TT_WORD){
|
|
this.name=new String(si.sval);
|
|
} else {
|
|
throw new ParseException("Bad graph name",0);
|
|
}
|
|
|
|
/* Parse number of vertices */
|
|
si.nextToken();
|
|
if (si.ttype==StreamTokenizer.TT_NUMBER){
|
|
verticeNb=(int)si.nval;
|
|
if (this.isListModel){
|
|
this.edgeModel=new EdgeListModel(verticeNb);
|
|
} else {
|
|
this.edgeModel=new EdgeMatrixModel(verticeNb);
|
|
}
|
|
} else {
|
|
throw new ParseException("Bad graph size",0);
|
|
}
|
|
|
|
/* Parse matrix */
|
|
for (int i=0; i<verticeNb;i++){
|
|
for (int j=0; j<verticeNb; j++){
|
|
si.nextToken();
|
|
if (si.ttype==StreamTokenizer.TT_NUMBER){
|
|
if (si.nval==0) {
|
|
// do nothing
|
|
} else {
|
|
// add an edge to the graph
|
|
try {
|
|
this.edgeModel.addEdge(i,j);
|
|
} catch (OutOfRangeVerticeException e){
|
|
throw new ParseException("Unknown vertice used",0);
|
|
}
|
|
}
|
|
} else {
|
|
throw new ParseException("Bad graph matrix",0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fonction qui verifie si les sommets adjacents a src sont
|
|
* uniquement les sommets contenus dans le tableau dst
|
|
* Si non alors elle renvoie -1 et si oui elle renvoie le premier
|
|
* sommet dst adjacent a src
|
|
**/
|
|
public int withOnlyEdges(int src, Vector dst){
|
|
return this.edgeModel.withOnlyEdges(src, dst);
|
|
}
|
|
|
|
/**
|
|
* Return the number of vertices of the Graph
|
|
**/
|
|
public int getCardV(){
|
|
return this.verticeModel.size();
|
|
}
|
|
|
|
public VerticeSet getVerticeModel(){
|
|
return this.verticeModel;
|
|
}
|
|
|
|
/**
|
|
* Return the vertice at index vertIdx
|
|
* range verification is done by verticetab...
|
|
**/
|
|
|
|
public Vertice getVertice(int vertIdx) {
|
|
return ((Vertice)this.verticeModel.elementAt(vertIdx));
|
|
}
|
|
|
|
|
|
/**
|
|
* Fonction qui verifie l'existence de l'arc
|
|
* du sommet srcV vers dstV
|
|
**/
|
|
public boolean isEdge(int srcV, int dstV){
|
|
return this.edgeModel.isEdge(srcV, dstV);
|
|
}
|
|
|
|
/**
|
|
* Fonction qui renvoie l'indice du vertice racine du graphe
|
|
* ou -1 s'il n'existe pas
|
|
**/
|
|
public int getInitialState(){
|
|
return this.edgeModel.getSourceVertice();
|
|
}
|
|
|
|
/**
|
|
* Fonction qui renvoie l'indice du vertice final du graphe
|
|
* ou -1 s'il n'existe pas
|
|
**/
|
|
public int getFinalState(){
|
|
return this.edgeModel.getFinalVertice();
|
|
}
|
|
|
|
/**
|
|
* Fonction qui renvoie la liste d'adjacence du sommet srcV
|
|
**/
|
|
public Collection getAdjacent(int srcV)
|
|
throws OutOfRangeVerticeException
|
|
{
|
|
if ((srcV<0) || (srcV >= verticeModel.size())){
|
|
throw new OutOfRangeVerticeException();
|
|
}
|
|
return this.edgeModel.getAdjacent(srcV);
|
|
}
|
|
|
|
public Collection getIncident(int dstV)
|
|
throws OutOfRangeVerticeException
|
|
{
|
|
if ((dstV<0) || (dstV >= verticeModel.size())){
|
|
throw new OutOfRangeVerticeException();
|
|
}
|
|
return this.edgeModel.getIncident(dstV);
|
|
}
|
|
|
|
|
|
/**
|
|
* Fonction qui renvoie representation (sous forme de String)
|
|
* du graphe en format .txt
|
|
**/
|
|
public String toTxt(){
|
|
StringBuffer output;
|
|
if (this.verticeModel != null)
|
|
output=new StringBuffer(4*this.verticeModel.size());
|
|
else
|
|
output=new StringBuffer(80);
|
|
String endl=System.getProperty("line.separator");
|
|
if ((this.name) != null){
|
|
output.append(this.name+endl);
|
|
} else {
|
|
output.append("noName"+endl);
|
|
}
|
|
if (this.edgeModel==null){
|
|
output.append("0"+endl);
|
|
} else {
|
|
int taille=this.edgeModel.getCardV();
|
|
output.append(""+taille+endl);
|
|
for (int i=0;i<taille;i++){
|
|
for (int j=0; j<taille; j++){
|
|
if (this.edgeModel.isEdge(i,j)){
|
|
output.append("1 ");
|
|
} else {
|
|
output.append("0 ");
|
|
}
|
|
}
|
|
output.append(endl);
|
|
}
|
|
}
|
|
return output.toString();
|
|
}
|
|
|
|
/**
|
|
* Fonction qui renvoie representation (sous forme de String)
|
|
* du graphe en format .dot
|
|
**/
|
|
public String toDot(){
|
|
StringBuffer output;
|
|
String tempName;
|
|
String endl=System.getProperty("line.separator");
|
|
|
|
if (this.name==null){
|
|
tempName="noName";
|
|
} else {
|
|
tempName=this.name;
|
|
}
|
|
output=new StringBuffer("digraph "+tempName+" {"+endl);
|
|
if (this.edgeModel==null) {
|
|
output.append("}"+endl);
|
|
} else {
|
|
output=new StringBuffer("digraph "+this.name+" {");
|
|
output=output.append(endl);
|
|
|
|
// Pour l'instant label vaut le sommet d'ou l'arc part
|
|
int taille=this.edgeModel.getCardV();
|
|
for (int i=0; i<taille; i++){
|
|
Collection adj=this.edgeModel.getAdjacent(i);
|
|
output.append(i);
|
|
output.append(" [label=");
|
|
output.append(i);
|
|
output.append("];");
|
|
output.append(endl);
|
|
//output.append(adj);
|
|
if (adj!=null){
|
|
Iterator j=adj.iterator();
|
|
while(j.hasNext()){
|
|
output.append(" ");
|
|
output.append(i);
|
|
output.append(" -> ");
|
|
output.append((Integer)j.next());
|
|
output.append(" ;");
|
|
output.append(endl);
|
|
}
|
|
}
|
|
}
|
|
output=output.append("}"+endl);
|
|
}
|
|
return output.toString();
|
|
}
|
|
|
|
}
|
|
|
|
|