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);
}
}
}