package Modèle;
//
//
//  Generated by StarUML(tm) Java Add-In
//
//  @ Project : Untitled
//  @ File Name : Probleme.java
//  @ Date : 25/04/2011
//  @ Author : 
//
//

import java.util.*;

public class Probleme {
	protected String nom;
	protected Vector<Variable> variables;
	protected Vector<Contrainte> contraintes;
	protected FonctionObjectif fctObj;
	protected Resultat res;

	public Probleme(String nom) {
		this.nom = nom;
		variables = new Vector<Variable>();
		contraintes = new Vector<Contrainte>();
		fctObj = null;
		res = null;
	}

	public void ajoutVar(Variable x) {
		variables.add(x);
	}

	public Vector<Contrainte> getContraintes() {
		return contraintes;
	}

	public Resultat getResultat() {
		return res;
	}

	public Vector<Variable> getVariables() {
		return variables;
	}

	public void ajoutContr(Contrainte c) {
		contraintes.add(c);
	}

	public FonctionObjectif getFctObj() {
		return fctObj;
	}

	public void setFctObj(FonctionObjectif f) {
		fctObj = f;
		variables = new Vector<Variable>();
		for (int i=0;i<f.getVariables().size();i++){
			variables.add(new Variable(f.getVariables().get(i).getNom(),null));
		}
	}

	public Resultat resoudre() {
		System.out.println("résolution");
		// forme standard
		Probleme p = formeStandard();
		System.out.println("fin résolution");
		// créer les variables d'écart
		// créer les variables artificielles
		// créer le tableau du simplexe
		// while(algo pas fini)
		// base réalisable
		// changement de base(var entrante+sortante)
		// trouver le pivot
		// opération sur les lignes et les colonnes
		// fin while
		// enregistrer solution
		return null;
	}

	public Probleme formeStandard() {
		try {
			Probleme p = new Probleme("formeStandard");
			if (this.fctObj.getObjectif().equals("maximiser")) {
				String newFct = "-" + fctObj.getNom() + "=";
				for (int i = 0; i < variables.size(); i++) {
					if (fctObj.getCoeffs().get(i) < 0)
						newFct += "+" + -1 * fctObj.getCoeffs().get(i) + fctObj.getVariables().get(i).getNom();
					else
						newFct += -1 * fctObj.getCoeffs().get(i) + fctObj.getVariables().get(i).getNom();
				}
				if (newFct.charAt(newFct.indexOf("=") + 1) == '+') {
					newFct.replaceFirst("\\+", "");
				}
				p.setFctObj(new FonctionObjectif("minimiser", newFct));
			}
			else
				p.setFctObj(new FonctionObjectif("minimiser", fctObj.getFonction()));
			boolean appartient=false;
			for (int i =0;i<contraintes.size();i++){
				for (int j=0;j<contraintes.get(i).getVariables().size();j++){
					appartient=false;
					for (int k=0;k<p.getVariables().size();k++){
						if (p.getVariables().get(k).getNom().equals(contraintes.get(i).getVariables().get(j).getNom()))
							appartient=true;
					}
					if(!appartient)
						p.getVariables().add(new Variable(contraintes.get(i).getVariables().get(j).getNom(),null));
				}
			}
			// forme standard des contraintes
			Contrainte c;
			// Ajout des variables d'écart :
			for (int i = 0; i < contraintes.size(); i++) {
				if (contraintes.get(i).getContrainte().contains("<=")) {
					c = new Contrainte(contraintes.get(i).getContrainte());
					c.ajoutVar("+xE" + (i + 1));
					c.setContrainte(c.getContrainte().replace("<", ""));
					c.setOperateur("=");
					c.parser();
					p.ajoutVar(new Variable("xE" + (i + 1), null));
					p.ajoutContr(c);
				}
				else {
					if (contraintes.get(i).getContrainte().contains(">=")) {
						c = new Contrainte(contraintes.get(i).getContrainte());
						c.ajoutVar("-xE" + i + 1);
						c.setContrainte(c.getContrainte().replace(">", ""));
						c.setOperateur("=");
						c.parser();
						p.ajoutVar(new Variable("xE" + i + 1, null));
						p.ajoutContr(c);
					}
					else {
						c = new Contrainte(contraintes.get(i).getContrainte());
						p.ajoutContr(c);
					}
				}
			}
			// Créer le tableau et vérifier si il faut ajouter des variables
			// artificielles
			// Gérer les variables, réfléchir à comment les avoir
			int[][] tab = creerTabSimplexe(p);
			for (int i = 0; i < tab.length; i++) {
				for (int j=0;j<tab[0].length;j++)
					System.out.print(tab[i][j] + "_");
				System.out.println();
			}
			for (int i = 0; i < p.getContraintes().size(); i++) {
				System.out.println("contrainte standard : " + p.getContraintes().get(i).getContrainte());
			}
			System.out.println("fonction standard : " + p.getFctObj().getFonction());
			return p;
		} catch (Exception e) {
			System.out.println("Exception : "+e);
			return null;
		}
	}

	public int[][] creerTabSimplexe(Probleme p) {
		System.out.println("variables du problèmes : ");
		for (int i=0;i<p.variables.size();i++)
			System.out.println(p.variables.get(i).getNom());
		int[][] tab = new int[p.getContraintes().size() + 1][p.getVariables().size() + 1];
		for (int i = 0; i < tab.length; i++) {
			for (int j = 0; j < tab[0].length; j++) {
				if (i == 0) { // Ligne des coûts
					if (j < p.getFctObj().getCoeffs().size() && !p.getFctObj().getVariables().get(j).getNom().equals(""))
						tab[i][j] = p.getFctObj().getCoeffs().get(j);
					else {
						if (j < p.getFctObj().getVariables().size() && p.getFctObj().getVariables().get(j).getNom().equals(""))
							tab[i][tab[0].length - 1] += p.getFctObj().getCoeffs().get(j);
						else
							tab[i][j] = 0;
					}
				}
				else { // Contraintes
					System.out.println("taille var contr : "+p.getContraintes().get(i-1).getVariables().size());
					if (j < p.getContraintes().get(i-1).getVariables().size()) {
						for (int k = 0; k < p.getContraintes().get(i-1).getVariables().size(); k++) {
							for (int l=0;l<p.getVariables().size();l++)
								if(p.getVariables().get(l).getNom().equals(p.getContraintes().get(i-1).getVariables().get(j).getNom()))
									tab[i][j]=p.getContraintes().get(i-1).getCoeffs().get(j);
						}
					}
					if (j==tab[0].length-1)
						tab[i][j]=p.getContraintes().get(i-1).getSndMembre();
				}
			}
		}
		return tab;
	}

	public void enregistrerSolution(Resultat r) {
		res = r;
	}

	public String getNom() {
		return nom;
	}

	public void setNom(String nom) {
		this.nom = nom;
	}

	public void afficher() {
		System.out.println(nom);
		System.out.println(fctObj.getObjectif() + " " + fctObj.getFonction());
		for (int i = 0; i < variables.size(); i++)
			System.out.println(contraintes.get(i));
	}
}
