package buffalo.twoTasksAnalysis; import java.util.Vector; import buffalo.dataStructures.*; import buffalo.util.Heap; /** Graphe biparti et réunion des domaines de définition des différents <CODE>Buffers</CODE> liant les deux <CODE>tâches</CODE> caractérisant ce <CODE>BufferBipartiteGraph</CODE>. */ public class BufferBipartiteGraph { private static BufferDomain[] domains; private Vector leftVerticesSet; private Vector rightVerticesSet; private Vector leftDomainsSet; private Vector rightDomainsSet; private Task task1; private Task task2; private int nbVertices; /*---------------------------------------------*/ /** S'instancie avec les deux tâches concernées par les buffers représentés par ce graphe. */ public BufferBipartiteGraph(Task firstTask, Task secondTask) { task1 = firstTask; task2 = secondTask; domains = new BufferDomain[Buffer.getNbBuffers()]; nbVertices = 0; leftVerticesSet = new Vector(); rightVerticesSet = new Vector(); leftDomainsSet = new Vector(); rightDomainsSet = new Vector(); } /*---------------------------------------------*/ /** Ajouter un <CODE>BufferDomain</CODE> au graphe. */ public void addBufferDomain(BufferDomain myBufferDomain) { domains[myBufferDomain.getIndex()] = myBufferDomain; if(myBufferDomain.getBuffer().getWritingTask()==task1) { leftDomainsSet.add(myBufferDomain); } else { rightDomainsSet.add(myBufferDomain); } } /*---------------------------------------------*/ /** Retourne le <CODE>BufferDomain</CODE> du <CODE>Buffer</CODE> passé en paramètre. */ public BufferDomain getBufferDomain(Buffer myBuffer) { if (domains[myBuffer.getIndex()] != null) { return domains[myBuffer.getIndex()]; } else { return new BufferDomain(this, myBuffer); } } /*---------------------------------------------*/ /** Ajoute une valeur pour le buffer passé en paramètre. */ public void addBufferValue(Buffer myBuffer, int value) { if (domains[myBuffer.getIndex()] != null) { domains[myBuffer.getIndex()].addBufferValue(value); } else { (new BufferDomain(this, myBuffer)). addBufferValue(value); } } /*---------------------------------------------*/ /** Vide tous les tas et place les valeurs pertinentes dans les sommets du graphe biparti. */ public void load() { int nbDomains = domains.length; for (int i = 0; i < nbDomains ; i++) { if (domains[i]!=null) { domains[i].load(); } } } /*---------------------------------------------*/ /** Retourne tous les domaines au format chaîne de caractères. */ public String toString() { String result = "\n"; int nbDomains = domains.length; for (int i = 0; i < nbDomains ; i++) { if (domains[i]!=null) { result += domains[i].toString(); } } return result; } /*-----------------------------------------------------*/ /** Retourne la première <CODE>tâche</CODE> concernée par ce <CODE>BufferDomain</CODE>. */ public Task getFirstTask() { return task1; } /*-----------------------------------------------------*/ /** Retourne la deuxième <CODE>tâche</CODE> concernée par ce <CODE>BufferDomain</CODE>. */ public Task getSecondTask() { return task2; } /*---------------------------------------------*/ /** Pour ajouter une arête dans le graphe biparti. */ public void addEdge(Buffer bufferFromTaskOne, Buffer bufferFromTaskTwo, int valueForFirstBuffer, int valueForSecondBuffer) { if (((bufferFromTaskOne.getWritingTask()==task1)|| (bufferFromTaskTwo.getWritingTask()==task1))&& ((bufferFromTaskOne.getWritingTask()==task2)|| (bufferFromTaskTwo.getWritingTask()==task2))&& (bufferFromTaskOne != bufferFromTaskTwo)) { if (bufferFromTaskOne.getWritingTask()==task2) { addEdge(bufferFromTaskTwo, bufferFromTaskOne, valueForSecondBuffer, valueForFirstBuffer); } else { BufferDomain firstBufferDomain = this.getBufferDomain(bufferFromTaskOne); BufferDomain secondBufferDomain = this.getBufferDomain(bufferFromTaskTwo); addEdge (firstBufferDomain, secondBufferDomain, valueForFirstBuffer, valueForSecondBuffer); } } } /*---------------------------------------------*/ /** Pour ajouter une arête dans le graphe biparti. */ private void addEdge(BufferDomain firstBufferDomain, BufferDomain secondBufferDomain, int valueForFirstBuffer, int valueForSecondBuffer) { BufferValue firstVertex = firstBufferDomain.findBufferValue(valueForFirstBuffer); BufferValue secondVertex = secondBufferDomain.findBufferValue(valueForSecondBuffer); if ((firstVertex != null)&&(secondVertex!=null)) { addEdge(firstVertex, secondVertex); } } /*---------------------------------------------*/ /** Pour ajouter une arête dans le graphe biparti. */ private void addEdge(BufferValue firstVertex, BufferValue secondVertex) { while(firstVertex.getIndex()>=1) { firstVertex.addEdges(secondVertex); firstVertex = firstVertex.getBufferDomain().getBufferValue(firstVertex.getIndex()-1); } } /*---------------------------------------------*/ /** Pour référencer les sommets, à invoquer à chaque ajout d'un sommet. */ public void addVertex(BufferValue myVertex) { nbVertices++; if(myVertex.getIndex()!=0) { if(myVertex.getBuffer().getWritingTask()==task1) { leftVerticesSet.add(myVertex); } else { rightVerticesSet.add(myVertex); } } } /*---------------------------------------------*/ /** Retourne le nombre de sommets contenus dans le graphe biparti. */ public int getNbVertices() { return nbVertices; } /*---------------------------------------------*/ /** Retourne les sommets contenus dans le sous-ensemble de "gauche" du graphe biparti. */ public Vector getLeftVerticesSet() { return leftVerticesSet; } /*---------------------------------------------*/ /** Retourne les sommets contenus dans le sous-ensemble de "droite" du graphe biparti. */ public Vector getRightVerticesSet() { return rightVerticesSet; } /*---------------------------------------------*/ /** Si la coupe dans le graphe a déjà été définie, cette méthode utilise cette coupe pour placer dans les champs <CODE>size</CODE> des buffers leurs dimensions. */ public void defineBuffersSizes() { int nbDomains = leftDomainsSet.size(); int nbValues; int totalBuffersWeight = 0; BufferDomain myBufferDomain; BufferValue myBufferValue; Buffer myBuffer; int indexOfBufferValue; for(int i = 0; i < nbDomains; i++) { myBufferDomain = (BufferDomain)leftDomainsSet.get(i); nbValues = myBufferDomain.getNbBufferValues(); indexOfBufferValue = nbValues - 1; myBufferValue = myBufferDomain.getBufferValue(indexOfBufferValue); myBuffer = myBufferValue.getBuffer(); while ((indexOfBufferValue > 0)&&(myBufferValue.isInTheCut())) { indexOfBufferValue--; myBufferValue = myBufferDomain.getBufferValue(indexOfBufferValue); } myBuffer.setSize(myBufferValue.getValue()); if (TwoTasksAnalysis.print) { System.out.println("Buffer ( " + myBuffer.getIndex() + " ) -> { " + " size = " + myBuffer.getSize() + ", weight = " + myBuffer.getWeight() + ", area = " + (myBuffer.getSize() * myBuffer.getWeight()) + "}"); } totalBuffersWeight += (myBuffer.getSize() * myBuffer.getWeight()); } nbDomains = rightDomainsSet.size(); for(int i = 0; i < nbDomains; i++) { myBufferDomain = (BufferDomain)rightDomainsSet.get(i); nbValues = myBufferDomain.getNbBufferValues(); indexOfBufferValue = nbValues - 1; myBufferValue = myBufferDomain.getBufferValue(indexOfBufferValue); myBuffer = myBufferValue.getBuffer(); while ((indexOfBufferValue > 0)&&(!myBufferValue.isInTheCut())) { indexOfBufferValue--; myBufferValue = myBufferDomain.getBufferValue(indexOfBufferValue); } myBuffer.setSize(myBufferValue.getValue()); if (TwoTasksAnalysis.print) { System.out.println("Buffer ( " + myBuffer.getIndex() + " ) -> { " + " size = " + myBuffer.getSize() + ", weight = " + myBuffer.getWeight() + ", area = " + (myBuffer.getSize() * myBuffer.getWeight()) + "}"); totalBuffersWeight += (myBuffer.getSize() * myBuffer.getWeight()); } } if (TwoTasksAnalysis.print) { System.out.println("La surface totale occupée par les buffers est " + totalBuffersWeight); } } }