from parametres import Parametres
from agentta import *
from agentev import *
from marchetravail import Marche_travail
from marchebiens import Marche_biens
from matrice import Matrice
import numpy as np
import os  
import csv
import time
    
    
class Programme :

    ###METHODES POUR SUPPRIMER DES AGENTS :   
    #Suppression des agents TA dans le cas ou ils ne sont initialement connectes a aucune entreprise ou aucun vendeur
    #Pas besoin de supprimer des agents EV si pas de connexion car si personne ne travaille chez eux > production nulle > prix indic None > coupure > les acheteurs n'achetent pas > l'entreprise sort naturellement de la boucle
    #Agents TA et EV supprimes quand leur cash est negatif (faillite)      
    
    #Methode pour supprimer des agents TA dans le cas ou ils ne sont initialement connectes a aucune entreprise ou a aucun vendeur :
    def supprimer_agents_TA(self,matrice_TE,matrice_AV,liste_agents_TA,nb_TA_elimines) :
        liste_agents_TA_tmp = [] 
        for i in range (matrice_TE.m) :
            compteur_TE = 0
            compteur_AV = 0
            #Check dans la matrice TE initiale :
            for j in range (matrice_TE.n) :
                if matrice_TE.data[i][j] == 1 :
                    compteur_TE += 1
                    break
            #Check dans la matrice AV initiale :
            for j in range (matrice_AV.n) :
                visited = True
                if matrice_AV.data[i][j] == 1 :
                    compteur_AV += 1
                    break  
            #Seuls sont conserves les agents TA qui sont connectes a au moins une entreprise et au moins un acheteur :
            if compteur_TE > 0 and compteur_AV > 0 :
                liste_agents_TA_tmp.append(liste_agents_TA[i])
            else :
                nb_TA_elimines += 1
                print "Un TA elimine dans supprimer agents TA"
        return liste_agents_TA_tmp,nb_TA_elimines

    def faire_faillite(self,dette_totale,liste_agents_TA_tmp,liste_agents_EV,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines) :
        new_liste_agents_TA = []
        new_liste_agents_EV = []
        TA_en_faillite = []
        EV_en_faillite = []
        new_liste_salaires_effectifs = []
        new_liste_prix_indicatifs = []
        #Faillite des agents TA :
        for i in range (len(liste_agents_TA_tmp)) :
            if liste_agents_TA_tmp[i].cash < 0 :
                TA_en_faillite.append(liste_agents_TA_tmp[i])
                dette_totale += liste_agents_TA_tmp[i].cash
                nb_TA_elimines += 1
                print "Un TA elimine dans faire faillite"
            else :
                new_liste_agents_TA.append(liste_agents_TA_tmp[i])
        #Faillite des agents EV :
        for j in range (len(liste_agents_EV)) :
            if liste_agents_EV[j].cash < 0 :
                EV_en_faillite.append(liste_agents_EV[j])
                dette_totale += liste_agents_EV[j].cash
                nb_EV_elimines += 1
            else :
                new_liste_agents_EV.append(liste_agents_EV[j])
                #On ne garde les salaires effectifs de l'iteration precedente que des agents EV qui n'ont pas fait faillite :
                new_liste_salaires_effectifs.append(liste_salaires_effectifs[j])
                #On ne garde les prix indicatifs de le l'iteration precedente que des agents EV qui n'ont pas fait faillite :
                new_liste_prix_indicatifs.append(liste_prix_indicatifs[j])
        liste_salaires_effectifs = new_liste_salaires_effectifs
        liste_prix_indicatifs = new_liste_prix_indicatifs
        return dette_totale,new_liste_agents_TA,new_liste_agents_EV,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines
        
    #Methode pour reformer la matrice TE a partir de la liste des agents TA conserves :
    def reformer_matrice_TE(self,matrice_TE,liste_agents_TA,liste_agents_EV,new_liste_agents_TA,new_liste_agents_EV) :
        #Initialisation de la nouvelle matrice TE :
        m = len(new_liste_agents_TA)
        n = len(new_liste_agents_EV)
        new_matrice_TE = Matrice(m,n) 
        #Stockage des valeurs de la matrice TE a conserver :
        bloc_data = []
        for a in range (len(liste_agents_TA)) :
            if liste_agents_TA[a] in new_liste_agents_TA :
                ligne_data = []
                for b in range (len(liste_agents_EV)) :
                    if liste_agents_EV[b] in new_liste_agents_EV :
                        ligne_data.append(matrice_TE.data[a][b])
                bloc_data.append(ligne_data)
        #Remplissage de la nouvelle matrice TE :
        for i in range (new_matrice_TE.m) :
            for j in range (new_matrice_TE.n) :
                new_matrice_TE.data[i][j] = bloc_data[i][j]
        matrice_TE = new_matrice_TE
        return matrice_TE
    
    #Methode pour reformer la matrice AV a partir de la liste des agents TA conserves :
    def reformer_matrice_AV(self,matrice_AV,liste_agents_TA,liste_agents_EV,new_liste_agents_TA,new_liste_agents_EV) :
        #Initialisation de la nouvelle matrice AV :
        m = len(new_liste_agents_TA)
        n = len(liste_agents_EV)
        new_matrice_AV = Matrice(m,n) 
        #Stockage des valeurs de la matrice AV a conserver :
        bloc_data = []
        for a in range (len(liste_agents_TA)) :
            if liste_agents_TA[a] in new_liste_agents_TA : 
                ligne_data = []
                for b in range (len(liste_agents_EV)) :
                    if liste_agents_EV[b] in new_liste_agents_EV :
                        ligne_data.append(matrice_AV.data[a][b])
                bloc_data.append(ligne_data)
        #Remplissage de la nouvelle matrice AV :
        for i in range (len(new_liste_agents_TA)) :
            for j in range (len(new_liste_agents_EV)) :
                new_matrice_AV.data[i][j] = bloc_data[i][j]
        matrice_AV = new_matrice_AV
        return matrice_AV  
        
    #Methode globale pour la mise a jour a l'initialisation :
    def maj_matrices_initialisation(self,matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,nb_TA_elimines) :
        #Suppression des agents TA qui ne sont initialement connectes a aucune entreprise ou aucun vendeur :
        liste_agents_TA_tmp, nb_TA_elimines = self.supprimer_agents_TA(matrice_TE,matrice_AV,liste_agents_TA,nb_TA_elimines)
        #Pas encore de faillite :
        new_liste_agents_TA = liste_agents_TA_tmp
        #MAJ des matrices TE et AV :
        matrice_TE = self.reformer_matrice_TE(matrice_TE,liste_agents_TA,liste_agents_EV,new_liste_agents_TA,liste_agents_EV) 
        matrice_AV = self.reformer_matrice_AV(matrice_AV,liste_agents_TA,liste_agents_EV,new_liste_agents_TA,liste_agents_EV)
        liste_agents_TA = new_liste_agents_TA
        return liste_agents_TA,matrice_TE,matrice_AV,nb_TA_elimines
    
    #Methode globale :
    def maj_matrices(self,dette_totale,matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines) :
        #Suppression des agents TA qui ne sont connectes a aucune entreprise ou aucun vendeur :
        liste_agents_TA_tmp,nb_TA_elimines = self.supprimer_agents_TA(matrice_TE,matrice_AV,liste_agents_TA,nb_TA_elimines)
        #Suppression des agents qui ont fait faillite et des salaires effectifs et prix indicatifs relatifs :
        dette_totale,new_liste_agents_TA,new_liste_agents_EV,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines = self.faire_faillite(dette_totale,liste_agents_TA_tmp,liste_agents_EV,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines) 
        #MAJ des matrices TE et AV :
        matrice_TE = self.reformer_matrice_TE(matrice_TE,liste_agents_TA,liste_agents_EV,new_liste_agents_TA,new_liste_agents_EV) 
        matrice_AV = self.reformer_matrice_AV(matrice_AV,liste_agents_TA,liste_agents_EV,new_liste_agents_TA,new_liste_agents_EV)
        liste_agents_TA = new_liste_agents_TA
        liste_agents_EV = new_liste_agents_EV
        return liste_agents_TA,liste_agents_EV,matrice_TE,matrice_AV,dette_totale,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines
  
    #Methode pour calculer le cash total dans le systeme :
    def calculer_cash_total(self,liste_agents_TA,liste_agents_EV) :
        somme = 0
        for i in range (len(liste_agents_TA)) :
            somme += liste_agents_TA[i].cash
        for j in range (len(liste_agents_EV)) :
            somme += liste_agents_EV[j].cash
        return somme
        
          
    ###METHODES POUR COLLECTER LES DONNEES :   

    #Methode pour initialiser le fichier contenant le total des heures de travail dans chaque entreprise :
    def initialiser_fichier_heures(self,liste_agents_EV_init) :
        myfile_heures = csv.writer(open("output_heures.csv","wb"))
        donnees = []
        donnees.append("Iteration")
        for j in range (len(liste_agents_EV_init)) :
            donnees.append("Total heures agent EV" + str(j))
        myfile_heures.writerow(donnees)
        return myfile_heures
    
    #Methode pour remplir le fichier contenant le total des heures de travail dans chaque entreprise :
    def collecter_donnees_heures(self,myfile_heures,iteration,liste_agents_EV_init,liste_agents_EV,liste_total_heures) :
        donnees = []
        donnees.append(iteration)
        curseur = 0
        for j in range (len(liste_agents_EV_init)) :
            if liste_agents_EV_init[j] in liste_agents_EV :
                curseur += 1
                donnees.append(liste_total_heures[curseur-1])
            else : 
                donnees.append(-1)
        myfile_heures.writerow(donnees)
        
    #Methode pour initialiser le fichier qui va collecter les donnees sur le cash :
    def initialiser_fichier_cash(self,liste_agents_TA_init,liste_agents_EV_init) :
        myfile_cash = csv.writer(open("output_cash.csv", "wb"))
        donnees = []
        donnees.append("Iteration")
        for i in range (len(liste_agents_TA_init)) :
            donnees.append("Agent TA" + str(i))
        for j in range (len(liste_agents_EV_init)) :
            donnees.append("Agent EV" + str(j))
        donnees.append("Cash total systeme")
        myfile_cash.writerow(donnees)
        return myfile_cash
     
    #Methode pour mettre les donnees concernant le cash dans un fichier output :
    def collecter_donnees_cash(self,myfile_cash,iteration,liste_agents_TA_init,liste_agents_TA,liste_agents_EV_init,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,cash_total_systeme) :
        donnees = []
        donnees.append(iteration)
        curseur_TA = 0
        curseur_EV = 0
        for i in range (len(liste_agents_TA_init)) :
            if liste_agents_TA_init[i] in liste_agents_TA :
                curseur_TA += 1
                donnees.append(liste_cash_agents_TA[curseur_TA-1])
            else :
                donnees.append(-9999999)
        for j in range (len(liste_agents_EV_init)) :
            if liste_agents_EV_init[j] in liste_agents_EV :
                curseur_EV += 1
                donnees.append((liste_cash_agents_EV[curseur_EV-1]))
            else :
                donnees.append(-9999999)
        donnees.append(cash_total_systeme)
        myfile_cash.writerow(donnees)

    #Methode pour initialiser le fichier qui va collecter les donnees sur les salaires indicatifs et les salaires effectifs :
    def initialiser_fichier_salaires(self,liste_agents_EV_init) :
        myfile_salaires = csv.writer(open("output_salaires.csv","wb"))
        donnees = []
        donnees.append("Iteration")
        for j in range (len(liste_agents_EV_init)) :
            donnees.append("Salaire effectifs agent EV" + str(j))
        myfile_salaires.writerow(donnees)
        return myfile_salaires
    
    #Methode pour mettre les donnees concernant les salaires dans un fichier output :
    def collecter_donnees_salaires(self,myfile_salaires,iteration,liste_agents_EV_init,liste_agents_EV,liste_salaires_effectifs) :
        donnees = []
        donnees.append(iteration)
        curseur = 0
        for j in range (len(liste_agents_EV_init)) :
            if liste_agents_EV_init[j] in liste_agents_EV :
                curseur += 1
                donnees.append(liste_salaires_effectifs[curseur-1])
            else : 
                donnees.append(-1)
        myfile_salaires.writerow(donnees)
    
    #Methode pour initialiser le fichier qui va collecter les donnees sur les prix : (le prix indicatif correspond au prix reel, c'est la qte de biens recu en echange qui peut varier)
    def initialiser_fichier_prix(self,liste_agents_EV_init) :
        myfile_prix = csv.writer(open("output_prix.csv","wb"))
        donnees = []
        donnees.append("Iteration")
        for j in range (len(liste_agents_EV_init)) :
            donnees.append("Prix indic agent EV" + str(j))
        myfile_prix.writerow(donnees)
        return myfile_prix
    
    #Methode pour mettre les donnees concernant les prix dans un fichier output :
    def collecter_donnees_prix(self,myfile_prix,iteration,liste_agents_EV_init,liste_agents_EV,liste_prix_indicatifs) :
        donnees = []
        donnees.append(iteration)
        curseur = 0
        for j in range (len(liste_agents_EV_init)) :
            if liste_agents_EV_init[j] in liste_agents_EV :
                curseur += 1
                donnees.append(liste_prix_indicatifs[curseur-1])
            else : 
                donnees.append(-1)
        myfile_prix.writerow(donnees)
                
    #Methode pour initialiser le fichier qui va enregistrer le temps de la simulation :
    def initialiser_fichier_temps(self) :
        myfile_temps = csv.writer(open("output_temps.csv","wb"))
        return myfile_temps
   
    #Methode pour mettre les donnees concernant le cash dans un fichier output :
    def collecter_donnees_temps(self,myfile_temps,temps) :
        donnees = []
        donnees.append(temps)
        myfile_temps.writerow(donnees)
    
    
    def moyenne_cash_TA(self,liste_agents_TA) :
        somme = 0
        for a in range (len(liste_agents_TA)) :
            somme += liste_agents_TA[a].cash
        moyenne_cash_TA = somme/len(liste_agents_TA)
        return moyenne_cash_TA
    
    def moyenne_cash_EV(self,liste_agents_EV) :
        somme = 0
        for a in range (len(liste_agents_EV)) :
            somme += liste_agents_EV[a].cash
        moyenne_cash_EV = somme/len(liste_agents_EV)
        return moyenne_cash_EV
        
        
    #Methode pour creer un nouveau fichier input afin d'integrer des migrants :
    def creer_input_migrants(self,matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,dette_totale,cash_total_systeme,liste_salaires_effectifs,liste_prix_indicatifs,liste_benefices_entreprises) :
        #Initialisation du fichier input migrants :
        myfile_migrants = csv.writer(open("input_migrants.csv","wb"))
        #Cash agents TA :
        donnees = []
        donnees.append("Cash agents TA")
        for i in range (len(liste_agents_TA)) :
            donnees.append(liste_cash_agents_TA[i])
        myfile_migrants.writerow(donnees)
        #Cash agents EV :
        donnees = []
        donnees.append("Cash agents EV")
        for j in range (len(liste_agents_EV)) :
            donnees.append(liste_cash_agents_EV[j])
        myfile_migrants.writerow(donnees)
        #Salaires proposes par les EV :
        donnees = []
        donnees.append("Salaires proposes par EV")
        for j in range (len(liste_agents_EV)) :
            donnees.append(liste_salaires_effectifs[j])
        myfile_migrants.writerow(donnees)   
        #Prix proposes par EV :
        donnees = []
        donnees.append("Prix proposes par EV")
        for j in range (len(liste_agents_EV)) :
            donnees.append(liste_prix_indicatifs[j])
        myfile_migrants.writerow(donnees) 
        #Liste benefices entreprises :
        donnees = []
        donnees.append("Liste benefices entreprises")
        for j in range (len(liste_agents_EV)) :
            donnees.append(liste_benefices_entreprises[j])
        myfile_migrants.writerow(donnees) 
        #Cash total systeme :
        donnees = []
        donnees.append("Cash total systeme")
        donnees.append(cash_total_systeme)
        myfile_migrants.writerow(donnees)
        #Dette totale :
        donnees = []
        donnees.append("Dette totale")
        donnees.append(dette_totale)
        myfile_migrants.writerow(donnees)
        #Matrice_TE :
        for i in range (matrice_TE.m) :
            donnees = []
            donnees.append("Mat TE Connexions du TA " + str(i))
            for j in range (matrice_TE.n) :
                donnees.append(matrice_TE.data[i][j])
            myfile_migrants.writerow(donnees)
        #Matrice_AV :
        for i in range (matrice_TE.m) :
            donnees = []
            donnees.append("Mat AV Connexions du TA " + str(i))
            for j in range (matrice_AV.n) :
                donnees.append(matrice_AV.data[i][j])   
            myfile_migrants.writerow(donnees)
        
    #Initialiser la liste de salaires effectifs precedente :
    def initialiser_liste_salaires_effectifs_precedente(self,liste_agents_EV) :
        liste_salaires_effectifs_precedente = []
        for j in range(len(liste_agents_EV)) :
            liste_salaires_effectifs_precedente.append(0)
        return liste_salaires_effectifs_precedente
    
    #MAJ liste salaires effectifs precedente :
    def maj_liste_salaires_effectifs_precedente(self,liste_salaires_effectifs) :
        liste_salaires_effectifs_precedente = []
        for j in range (len(liste_salaires_effectifs)) :
            liste_salaires_effectifs_precedente.append(liste_salaires_effectifs[j])
        return liste_salaires_effectifs_precedente
        
    #Initialiser la liste des prix indicatifs precedente :
    def initialiser_liste_prix_indicatifs_precedente(self,liste_agents_EV) :
        liste_prix_indicatifs_precedente = []
        for j in range(len(liste_agents_EV)) :
            liste_prix_indicatifs_precedente.append(0)
        return liste_prix_indicatifs_precedente
    
    #MAJ liste prix indicatifs precedente :
    def maj_liste_prix_indicatifs_precedente(self,liste_prix_indicatifs) :
        liste_prix_indicatifs_precedente = []
        for j in range (len(liste_prix_indicatifs)) :
            liste_prix_indicatifs_precedente.append(liste_prix_indicatifs[j])
        return liste_prix_indicatifs_precedente    
        
        
        
    
    ###METHODE RUN :      
        
    def run(self) :
    
        t0 = time.clock()
 
        print "INITIALISATION"
        
        #Lecture des parametres :
        parametres = Parametres('input.txt')
        parametres.parse()
        
        #Instanciation des listes d'agents TA et EV :
        liste_agents_TA = obtenir_liste_agents_TA(parametres)
        liste_agents_EV = obtenir_liste_agents_EV(parametres)
        
        liste_agents_TA_init = liste_agents_TA
        liste_agents_EV_init = liste_agents_EV
        
        nb_TA_elimines = 0
        nb_EV_elimines = 0
        dette_totale = 0
        
        #Instanciation des marches du travail et des biens :
        marche_travail = Marche_travail(parametres)
        marche_biens = Marche_biens(parametres)
        
        #Initialisation de la matrice travailleurs/acheteurs :
        matrice_TE = marche_travail.creer_matrice_TE(liste_agents_EV,liste_agents_TA)
        np.savetxt(os.path.join(parametres.dossier,'matrice_TE_initiale'),matrice_TE.data,fmt='%i',delimiter='\t')
        #Initialisation de la matrice acheteurs/vendeurs :
        matrice_AV = marche_biens.creer_matrice_AV(liste_agents_EV,liste_agents_TA)
        np.savetxt(os.path.join(parametres.dossier,'matrice_AV_initiale'),matrice_AV.data,fmt='%i',delimiter='\t')
        
        #MAJ des matrices avec suppression des agents TA connectes a aucune entreprise ou aucun vendeur :
        liste_agents_TA,matrice_TE,matrice_AV,nb_TA_elimines = self.maj_matrices_initialisation(matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,nb_TA_elimines)
        np.savetxt(os.path.join(parametres.dossier,'matrice_TE0'),matrice_TE.data,fmt='%i',delimiter='\t')
        np.savetxt(os.path.join(parametres.dossier,'matrice_AV0'),matrice_AV.data,fmt='%i',delimiter='\t')
        
        #Visualisation du cash initial des agents :
        liste_cash_agents_TA = obtenir_liste_cash_agents_TA(liste_agents_TA)
        liste_cash_agents_EV = obtenir_liste_cash_agents_EV(liste_agents_EV)
        #Calcul du cash total du systeme :
        cash_total_systeme = self.calculer_cash_total(liste_agents_TA,liste_agents_EV) 
 
        #Collecte des donnees a l'initialisation :
        #Initialisation des fichiers output :
        myfile_cash = self.initialiser_fichier_cash(liste_agents_TA_init,liste_agents_EV_init)
        myfile_salaires = self.initialiser_fichier_salaires(liste_agents_EV_init)
        myfile_prix = self.initialiser_fichier_prix(liste_agents_EV_init)
        myfile_temps = self.initialiser_fichier_temps()
        myfile_heures = self.initialiser_fichier_heures(liste_agents_EV_init)
        #Collecte des donnees :
        self.collecter_donnees_cash(myfile_cash,"Initialisation",liste_agents_TA_init,liste_agents_TA,liste_agents_EV_init,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,cash_total_systeme)
       
        print "\n"
       
        moyenne_cash_TA = self.moyenne_cash_TA(liste_agents_TA)
        moyenne_cash_EV = self.moyenne_cash_EV(liste_agents_EV)
        print "moyenne cash TA init : " + str(moyenne_cash_TA)
        print "moyenne cash EV init : " + str(moyenne_cash_EV)
        print "cash total systeme : " + str(cash_total_systeme)
       
       
        ###ITERATION 0 :
        
        print "ITERATION 0"
        
        liste_salaires_effectifs_precedente = self.initialiser_liste_salaires_effectifs_precedente(liste_agents_EV)
        liste_prix_indicatifs_precedente = self.initialiser_liste_prix_indicatifs_precedente(liste_agents_EV)
        
        #Le marche du travail tourne avec la liste des salaires indicatifs initiaux :
        matrice_TE,liste_salaires_indicatifs,repartition_heures_travailleurs,liste_total_heures,liste_production_entreprises,liste_salaires_effectifs,liste_payes_totales_employes = marche_travail.initialiser_marche_travail(liste_agents_EV,liste_agents_TA,matrice_TE,liste_salaires_effectifs_precedente,parametres)
             
        #Le marche des biens tourne avec la liste des prix indicatifs initiaux :
        matrice_AV,liste_prix_indicatifs,repartition_cash_acheteurs,somme_repartition_cash_acheteurs,liste_benefices_entreprises = marche_biens.initialiser_marche_biens(0,liste_agents_EV,liste_agents_TA,matrice_AV,liste_production_entreprises)      
          
        #MAJ des matrices TE et AV en enlevant les agents qui ont fait faillite :
        liste_agents_TA,liste_agents_EV,matrice_TE,matrice_AV,dette_totale,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines = self.maj_matrices(dette_totale,matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines)
        #Stockage des matrices :
        np.savetxt(os.path.join(parametres.dossier,'matrice_TE' + str(0)),matrice_TE.data,fmt='%i',delimiter='\t')
        np.savetxt(os.path.join(parametres.dossier,'matrice_AV' + str(0)),matrice_AV.data,fmt='%i',delimiter='\t')  
      
        #Visualisation du cash des agents :
        liste_cash_agents_TA = obtenir_liste_cash_agents_TA(liste_agents_TA)
        liste_cash_agents_EV = obtenir_liste_cash_agents_EV(liste_agents_EV)
        #Calcul du cash total du systeme :
        cash_total_systeme = self.calculer_cash_total(liste_agents_TA,liste_agents_EV)     

        #Collecte des donnees a la fin de l'iteration 0 :
        self.collecter_donnees_cash(myfile_cash,0,liste_agents_TA_init,liste_agents_TA,liste_agents_EV_init,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,cash_total_systeme)
        self.collecter_donnees_salaires(myfile_salaires,0,liste_agents_EV_init,liste_agents_EV,liste_salaires_effectifs)
        self.collecter_donnees_prix(myfile_prix,0,liste_agents_EV_init,liste_agents_EV,liste_prix_indicatifs) 
        self.collecter_donnees_heures(myfile_heures,0,liste_agents_EV_init,liste_agents_EV,liste_total_heures)
        
        liste_salaires_effectifs_precedente = self.maj_liste_salaires_effectifs_precedente(liste_salaires_effectifs)
        liste_prix_indicatifs_precedente = self.maj_liste_prix_indicatifs_precedente(liste_prix_indicatifs)
        
        print "\n"
        
        
        ###ITERATION 1 A N :
        
        for iteration in range (1,parametres.it) : 
        
            print "ITERATION " + str(iteration)
            
            #Appel de la methode travailler :
            matrice_TE,liste_salaires_indicatifs,repartition_heures_travailleurs,liste_total_heures,liste_production_entreprises,liste_salaires_effectifs,liste_payes_totales_employes = marche_travail.travailler(matrice_TE,liste_agents_EV,liste_agents_TA,liste_salaires_effectifs_precedente,parametres)
            
            #MAJ des matrices TE et AV en enlevant les agents qui ont fait faillite :
            liste_agents_TA,liste_agents_EV,matrice_TE,matrice_AV,dette_totale,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines = self.maj_matrices(dette_totale,matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines)            
                            
            #Appel de la methode pour faire tourner le marche des biens :
            matrice_AV,liste_prix_indicatifs,repartition_cash_acheteurs,somme_repartition_cash_acheteurs,liste_benefices_entreprises = marche_biens.faire_tourner_marches_biens(iteration,matrice_AV,liste_agents_EV,liste_agents_TA,liste_benefices_entreprises,liste_production_entreprises,liste_payes_totales_employes,liste_prix_indicatifs_precedente,parametres)
            
            #MAJ des matrices TE et AV en enlevant les agents qui ont fait faillite :
            liste_agents_TA,liste_agents_EV,matrice_TE,matrice_AV,dette_totale,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines = self.maj_matrices(dette_totale,matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,liste_salaires_effectifs,liste_prix_indicatifs,nb_TA_elimines,nb_EV_elimines)
            
            #Stockage des matrices toutes les 10 iterations :
            if iteration%10 == 0 or iteration == (parametres.it-1) :
                np.savetxt(os.path.join(parametres.dossier,'matrice_TE' + str(iteration)),matrice_TE.data,fmt='%i',delimiter='\t')
                np.savetxt(os.path.join(parametres.dossier,'matrice_AV' + str(iteration)),matrice_AV.data,fmt='%i',delimiter='\t')
            
            #Visualisation du cash des agents :
            liste_cash_agents_TA = obtenir_liste_cash_agents_TA(liste_agents_TA)
            liste_cash_agents_EV = obtenir_liste_cash_agents_EV(liste_agents_EV)
            
            #Calcul du cash total du systeme :
            cash_total_systeme = self.calculer_cash_total(liste_agents_TA,liste_agents_EV) 
       
            #Collecte des donnees a la fin de l'iteration n :
            self.collecter_donnees_cash(myfile_cash,iteration,liste_agents_TA_init,liste_agents_TA,liste_agents_EV_init,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,cash_total_systeme)
            self.collecter_donnees_salaires(myfile_salaires,iteration,liste_agents_EV_init,liste_agents_EV,liste_salaires_effectifs)
            self.collecter_donnees_prix(myfile_prix,iteration,liste_agents_EV_init,liste_agents_EV,liste_prix_indicatifs)
            self.collecter_donnees_heures(myfile_heures,iteration,liste_agents_EV_init,liste_agents_EV,liste_total_heures)            
        
            liste_salaires_effectifs_precedente = self.maj_liste_salaires_effectifs_precedente(liste_salaires_effectifs)
            liste_prix_indicatifs_precedente = self.maj_liste_prix_indicatifs_precedente(liste_prix_indicatifs)
        
            print "\n"
    
        
        
        #Creation du fichier input pour les migrants :
        self.creer_input_migrants(matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,dette_totale,cash_total_systeme,liste_salaires_effectifs,liste_prix_indicatifs,liste_benefices_entreprises)
    
    
    
        ###BILAN DES ITERATIONS :
        print "len liste_agents_TA", len(liste_agents_TA)
        print "len liste agents_EV : ", len(liste_agents_EV)
        moyenne_cash_TA = self.moyenne_cash_TA(liste_agents_TA)
        moyenne_cash_EV = self.moyenne_cash_EV(liste_agents_EV)
        print "moyenne cash TA final : " + str(moyenne_cash_TA)
        print "moyenne cash EV final : " + str(moyenne_cash_EV)
        print "cash_total_systeme : " + str(cash_total_systeme)
        print "nb_TA_elimines : " + str(nb_TA_elimines)
        print "nb_EV_elimines : " + str(nb_EV_elimines)
        print "La dette totale s'eleve a : " + str(dette_totale)
        
        temps = time.clock() - t0
        
        self.collecter_donnees_temps(myfile_temps,temps)