Files
BUT2-DEV34-CPOO-Public/PartyStub.java

223 lines
6.6 KiB
Java
Raw Normal View History

2025-12-12 10:06:41 +01:00
import java.util.Arrays;
/**
* This is a stub, you should rename the file to Party.java
*
* Party is a class to solve the party problem in general (not just for trees).
*
* The party problem takes a graph as input.
* A vertex of this graph models a person.
* Each vertex has a positive weight modelling the Person's fun factor.
* An edge between two vertices indicates an incompatibility to organise a party : e.g. dislike, one person is a direct boss of the other etc.
*
* A Party is a subset of the vertices that are pairwise not connected by an edge (an independent set in graph jargon).
* The sum of the fun factors of guests (member of the subset) evaluates the quality of the party.
* The higher it is, the best it is.
*
* The Party Problem consists in computing the best possible party value / computing a solution with the best party value.
*
* In graph parlance, this problem is known as Maximum Weighted Independent Set. It is known to be NP-complete for general graphs as inputs.
* This means that it is very unlikely that a polynomial time (in the size of the input graph) algorithm exists.
*
* This class proposes an exponential time algorithm that proceeds as follows.
* It initialises the search with a greedy method to yield a lower bound on the best Party.
* It proceeds with a backtracking method to search through (partial) parties.
* A search may be cut off if :
* adding the current vertex would not yield a Party (the added vertex is a neighbour of a vertex already present) above in the search; or,
* adding all remaining vertices would not yield a Party better than the currently known best one (just pretend all remaining vertices would be added).
*
* @author Florent Madelaine
*
*/
public class Party {
// graphe (il faut des 0 et des 1) pour arêtes pas arêtes.
private int[][] graphe;
// entier positifs ce sont les fun factors
private int[] poids;
// pour marquer les éléments visités.
private boolean[] marked;
// pour stocker la solution partielle en cours de fabrication
private int[] psolution;
// valeur de la meilleur fête.
private int best;
// meilleure solution jusqu'à présent
private int[] bestParty;
/**
* getter
*
* @return the value of the best known Party.
*/
public int getBest(){
return this.best;
}
/**
* getter
*
* @return the value of the best known Party.
*/
public int[] getBestParty(){
return this.bestParty;
}
/**
*
* @return a String representing the current state of the Party object
*/
public String toString(){
String out = "";
out+="poids: " + Arrays.toString(this.poids)+"\n";
out+="graphe:\n"; //+ Arrays.deepToString(this.graphe)+"\n";
for(int i = 0; i < this.graphe.length; i++){
out+="\t" + Arrays.toString(graphe[i])+"\n";
}
out+="marked: "+ Arrays.toString(this.marked)+"\n";
out+="psolution: " + Arrays.toString(this.psolution)+"\n";
out+="bestParty: " + Arrays.toString(this.bestParty)+"\n";
out+="best: "+ this.best+"\n";
return out;
}
/**
* constructor
*
* @param graph a 0/1 (square) adjacency matrix
* @param poids an array of int representing the weights of the vertices
* @throws IllegalArgumentException if the matrix is not square or array of weights of inconsitent size with matrix.
*/
public Party(int[][] graphe, int[] poids){
int n = graphe.length;
if ((graphe[0].length != graphe.length) || (graphe.length != poids.length)) throw new IllegalArgumentException("graphe should be a square matrix of the same side as the length of poids.");
this.graphe=graphe;
this.poids=poids;
this.marked = new boolean[n];
this.psolution = new int[n];
this.best=0;
this.bestParty= new int[n];
}
/**
* getter
*
* @return the value of the current party (psolution).
*/
public int getCurrentPartyValue(){
int res = 0;
for(int i = 0; i < this.psolution.length; i++){
res+= psolution[i]*poids[i];
}
return res;
}
/**
* getter
*
* @param j an index in the solution that should represent the index to the left of which we have stored a partial solution.
* @return the max value that the current party (psolution) could possibly reach (simulate adding vertices after j)
*/
public int getUpperBoundCurrentPartyValue(int j){
// j should be an index of psolution
int res = 0;
for(int i = 0; i < this.psolution.length; i++){
if (i<j){
res+= psolution[i]*poids[i];
}
else{
// à partir de j on compte le poids forcément.
res+= poids[i];
}
}
return res;
}
/**
* Method to compute a first Party with a greedy method
*
* It sets bestParty to a bitmap representing a legal Party in a greedy fashion
* It updates best to be the value of this computed party
*/
public void greedy(){
// work here
}
/**
* Method to search and compute the best Party using bactracking.
* @param next represent the integer from which psolution (the current partial solution under study) should be extended
*
* If next is beyond psolution size, psolution is a complete candidate solution to the Party problem.
* The method should update bestParty with this solution if it is better.
* (you should clone the array to avoid problems).
*
* otherwise, if next falls within the bitmap, it will search the two cases one after the other
* adding the vertex at index next to the psolution (case1)
* or not adding this vertex (case2).
* If both cases are legal / can not be removed from the search, it proceeds by caling backtrack with parameter next+1
*/
public void backtrack(int next){
if (next >= psolution.length)
{// fini de construire une solution
}
else{
// cas value=1 d'abord.
int value =1;
// mise à jour solution partielle si possible
boolean ajoute = true;
// TO DO : tester si ajoute est OK sinon mettre ajoute à faux
if (ajoute){
psolution[next]=value;
// TO DO : on pourrait peut-être s'arrêter?
backtrack(next+1);
}
// cas value=0 ensuite
value=0
// TO DO
}
}
public static void main(String[] args) {
// A B C forment un triangle, E et D voisins de C.
// poids 4, 5, 2, 6, 1.
int[][] graphe = {
{ 0, 1, 1, 0, 0},
{ 1, 0, 1, 0, 0},
{ 1, 1, 0, 1, 1},
{ 0, 0, 1, 0, 0},
{ 0, 0, 1, 0, 0}
};
int [] poids = {4,5,2,6,1};
Party p = new Party(graphe, poids);
p.greedy();
System.out.println(Arrays.toString(p.getBestParty())); // Display the string.
System.out.println(p.getBest()); // Display the best Pary
System.out.println(p);
}
}