-
thibault.capt authoredthibault.capt authored
Simplex.java 6.13 KiB
import java.util.Arrays;
public class Simplex {
private Matrix matEcart;
private Matrix tabAux;
private int nbSousCondition;
private int x;
private int y;
private int nbPivot;
private static double EPSILON = 0E-7;
private int nbContraintes;
public Matrix getTabAux() {
return tabAux;
}
public Matrix getMatEcart() {
return matEcart;
}
public int getNbPivot() {
return nbPivot;
}
public Simplex(int x, int y, int nbSousCondition, int nbContraintes) {
this.x = x;
this.y = y;
this.matEcart = new Matrix(x, y);
this.nbSousCondition = nbSousCondition;
this.tabAux = new Matrix(x + 2, y + nbSousCondition + 1);
this.nbPivot = 0;
this.nbContraintes = nbContraintes;
}
void createSimplex(Equation eq, int nbContraintes) {
// Matrice Amxn
for (int i = 0; i < this.x; i++) {
for (int j = 0; j < this.y; j++) {
if (j < nbContraintes) {
this.matEcart.setData(i, j, eq.getMatAtId(i, j));
} else {
this.matEcart.setData(i, j, j - nbContraintes == i ? 1.0 : 0.0);
}
}
}
// Membre de droite
for (int i = 0; i <= this.x - 1; i++)
this.matEcart.setData(i, this.y - 1, eq.getRightVec().get(i));
// Fonction obj
this.matEcart.matrixRealloc(this.matEcart.getX() + 1, this.matEcart.getY());
for (int i = 0; i < nbContraintes; i++)
this.matEcart.setData(this.x, i, eq.getFuncObj().get(i));
}
/**
* Si b[i] < 0 phase 1 sinon phase 2
*
* @return true = phase 1 | false = phase 2
*/
int which_phase() {
int res = -1;
for (int i = 0; i < this.x; i++) {
if (signe(this.matEcart.getData(i, this.y - 1))) res = i;
}
return res;
}
void tabAux(int line) {
double[] tabRes = new double[this.y + this.nbSousCondition + 1];
Arrays.fill(tabRes, 1.0);
for (int j = 0; j < this.y; j++) {
if (this.matEcart.getData(line, j) != 0.0) {
double res = this.matEcart.getData(line, j) * -1;
this.matEcart.setData(line, j, res);
}
double tmpSum = 0;
for (int i = 0; i < this.x; i++) {
tmpSum += -1 * this.matEcart.getData(i, j);
}
tabRes[j] = tmpSum;
}
System.out.println();
// -2 car => tabRes[(tabRes.length-1) - (this.nbSousCondition - 1)];
tabRes[tabRes.length - 1] = tabRes[tabRes.length - this.nbSousCondition - 2];
tabRes[tabRes.length - this.nbSousCondition - 2] = 0;
for (int i = 0; i < this.tabAux.getX(); i++) {
for (int j = 0; j < this.tabAux.getY(); j++) {
if (i < this.matEcart.getX() && j < this.matEcart.getY())
this.tabAux.setData(i, j, this.matEcart.getData(i, j));
else if (i == this.tabAux.getX() - 1)
this.tabAux.setData(i, j, tabRes[j]);
else // membre de droite à la fin du tab
this.tabAux.setData(i, j, this.matEcart.getData(i, j - this.matEcart.getX()));
}
}
this.tabAux.printTabAux("Tableau auxiliaire", this.nbContraintes, this.nbSousCondition, this.tabAux.getY() - this.matEcart.getY() - 1);
pivot(this.tabAux);
double solutionOptimale = this.tabAux.getData(this.tabAux.getX() - 1, this.tabAux.getY() - 1);
if (solutionOptimale > 0 + EPSILON) {
System.out.println("Il n'y a pas de solutions admissibles pour ce problème.");
}
if (solutionOptimale == 0) {
// Il y a une solution optimale
// Il faut enlever les variables auxilaires
Matrix res = new Matrix(matEcart.getX(), matEcart.getY());
res.matrixFill(res.getX(), res.getY(), tabAux.getDatas());
res.matrixPrint("Petit tableau", 2);
nbPivot = 0;
pivot(res);
res.matrixPrint("Résultat ", 3);
System.out.println("Nombre de pivot : " + nbPivot);
}
}
int getFirstNeg(Matrix mat) {
for (int j = 0; j < mat.getY(); j++) {
if (signe(mat.getData(mat.getX() - 1, j))) return j;
}
return -1;
}
void pivot(Matrix mat) {
this.nbPivot += 1;
int firstNeg = getFirstNeg(mat);
if (firstNeg == -1) return; // si pas de négatif
boolean has_neg = false;
int id = ligneSortante(mat, firstNeg);
double val_pivot = mat.getData(id, firstNeg);
for (int i = 0; i < mat.getY(); i++) {
mat.setData(id, i, mat.getData(id, i) / val_pivot);
}
for (int i = 0; i < mat.getX(); i++) {
val_pivot = mat.getData(i, firstNeg);
for (int j = 0; j < mat.getY(); j++) {
if (i != id) {
mat.setData(i, j, mat.getData(i, j) - val_pivot * mat.getData(id, j));
}
}
}
mat.matrixPrint("Pivot numéro " + this.nbPivot, 2);
for (int j = 0; j < mat.getY(); j++)
if (signe(mat.getData(mat.getX() - 1, j))) {
has_neg = true;
if (has_neg) {
break;
}
}
if (has_neg)
pivot(mat);
}
// TODO : A REFAIRE POUR SWITCH DE Y AU CAS OU
int ligneSortante(Matrix mat, int y) {
int id = 0;
while (!(mat.getData(id, y) > 0)) {
id++;
}
double tmp = mat.getData(id, mat.getY() - 1) / mat.getData(id, y);
double tmp_s;
for (int i = 1; i < mat.getX() - 1; i++) {
if (mat.getData(i, y) > 0) {
tmp_s = mat.getData(i, mat.getY() - 1) / mat.getData(i, y);
if (tmp_s < tmp) {
id = i;
tmp = tmp_s;
}
}
}
return id;
}
public void printSimplex(Matrix mat, String s, int precision) {
mat.matrixPrint(s, precision);
}
boolean signe(Double x) {
return x < 0;
}
}