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 qui va collecter les donnees sur le cash :
    def initialiser_fichier_cash(self,liste_agents_TA_init,nb_migrants,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 m in range (nb_migrants) :
            donnees.append("Migrant" + str(m))
        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_avant_migrants(self,myfile_cash,iteration,liste_agents_TA_init,liste_agents_TA,nb_migrants,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 m in range (nb_migrants) :
            donnees.append("x")
        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 mettre les donnees concernant le cash dans un fichier output :
    def collecter_donnees_cash_apres_migrants(self,myfile_cash,iteration,liste_agents_TA_init,liste_agents_TA,nb_migrants,liste_agents_EV_init,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,cash_total_systeme,liste_init_migrants) :
        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)
        print "len curseur TA : " + str(curseur_TA)
        for m in range (len(liste_init_migrants)) :
            if liste_init_migrants[m] 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 effectif 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
        
        
    #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 pour integrer les migrants :
    def integrer_migrants(self,parametres,liste_agents_TA,liste_agents_EV,nb_migrants,matrice_TE,matrice_AV) :
        #Stockage du contenu de la matrice TE :
        matrice1 = []
        liste_init_migrants = []
        for i in range (matrice_TE.m) :
            ligne_matrice = []
            for j in range (matrice_TE.n) :
                ligne_matrice.append(matrice_TE.data[i][j])
            matrice1.append(ligne_matrice)
        #Stockage du contenu de la matrice AV :
        matrice2 = []
        for i in range (matrice_AV.m) :
            ligne_matrice = []
            for j in range (matrice_AV.n) :
                ligne_matrice.append(matrice_AV.data[i][j])
            matrice2.append(ligne_matrice)
        #Ajout des migrants a la liste des agents TA :
        for m in range (nb_migrants) :
            migrant = Agent_TA(8,100)
            liste_agents_TA.append(migrant)
            liste_init_migrants.append(migrant)
        print "len nouvelle liste de TA" + str(len(liste_agents_TA))
        #Reformation de la matrice TE :
        #Initialisation de la matrice :
        m = len(liste_agents_TA)
        n = len(liste_agents_EV)
        new_matrice_TE = Matrice(m,n) 
        #Remplissage de la matrice :
        for i in range (len(matrice1)) :
            for j in range (len(liste_agents_EV)) :
                new_matrice_TE.data[i][j] = matrice1[i][j]
        M = len(liste_agents_TA)
        I = len(matrice1)
        for m in range (I,M) :
            for j in range (len(liste_agents_EV)) :
                if parametres.proba_matrice_TE == 0.50 :
                    new_matrice_TE.data[m][j] = random.randint(0,1)
                else :
                    r = random.random()
                    new_matrice_TE.data[m][j] = int(r + float(parametres.proba_matrice_TE))
        #Reformation de la matrice AV :
        #Initialisation de la matrice :
        m = len(liste_agents_TA)
        n = len(liste_agents_EV)
        new_matrice_AV = Matrice(m,n) 
        #Remplissage de la matrice :
        for i in range (len(matrice2)) :
            for j in range (len(liste_agents_EV)) :
                new_matrice_AV.data[i][j] = matrice2[i][j]
        M = len(liste_agents_TA)
        I = len(matrice2)
        for m in range (I,M) :
            for j in range (len(liste_agents_EV)) :
                if parametres.proba_matrice_AV == 0.50 :
                    new_matrice_AV.data[m][j] = random.randint(0,1)
                else :
                    r = random.random()
                    new_matrice_AV.data[m][j] = int(r + float(parametres.proba_matrice_AV))
        #On renomme les matrices :
        matrice_TE = new_matrice_TE
        matrice_AV = new_matrice_AV
        return liste_agents_TA,matrice_TE,matrice_AV,liste_init_migrants
            
    #Methode pour lire input migrants :
    def lire_input_migrants(self) :
        fname = "input_migrants.csv"
        file = open(fname,"r")
        try :
            #Cash agents TA :
            liste_cash_agents_TA = file.readline().split(",")
            del liste_cash_agents_TA[0]
            liste_cash_agents_TA = [v.replace("\n","") for v in liste_cash_agents_TA]    
            liste_cash_agents_TA = [float(valeur) for valeur in liste_cash_agents_TA]
            #Liste agents TA :
            liste_agents_TA = [Agent_TA(8,cash) for cash in liste_cash_agents_TA] 
            #Cash agents EV :
            liste_cash_agents_EV = file.readline().split(",") 
            del liste_cash_agents_EV[0]
            liste_cash_agents_EV = [v.replace("\n","") for v in liste_cash_agents_EV]    
            liste_cash_agents_EV = [float(valeur) for valeur in liste_cash_agents_EV]
            #Salaires proposes par les EV :
            liste_salaires_indicatifs_str = file.readline().split(",")
            del liste_salaires_indicatifs_str[0]
            liste_salaires_indicatifs = []
            for v in liste_salaires_indicatifs_str:
                v = v.replace("\n","")
                if v == "":
                    v = None
                else:
                    v = float(v)
                liste_salaires_indicatifs.append(v)
            #Prix proposes par les EV :
            liste_prix_indicatifs_str = file.readline().split(",")
            del liste_prix_indicatifs_str[0]
            liste_prix_indicatifs = []
            for v in liste_prix_indicatifs_str :
                v = v.replace("\n","")
                if v == "":
                    v = None
                else:
                    v = float(v)
                liste_prix_indicatifs.append(v)
            #Liste agents EV :
            liste_agents_EV = []
            for j in range (len(liste_cash_agents_EV)) :
                cash = liste_cash_agents_EV[j]
                salaire = liste_salaires_indicatifs[j]
                prix = liste_prix_indicatifs[j]
                liste_agents_EV.append(Agent_EV(cash,0.5,salaire,prix))
            #Liste benefices entreprises :
            liste_benefices_entreprises_str = file.readline().split(",")
            del liste_benefices_entreprises_str[0]
            liste_benefices_entreprises = []
            for v in liste_benefices_entreprises_str :
                v = v.replace("\n","")
                if v == "":
                    v = None
                else:
                    v = float(v)
                liste_benefices_entreprises.append(v)
            #Cash total systeme :
            cash_total_systeme = file.readline().split(",")[1]
            cash_total_systeme = float(cash_total_systeme)
            #Dette totale : 
            dette_totale = file.readline().split(",")[1]
            dette_totale = float(dette_totale)
            #Matrice TE :
            #Initialisation de la matrice TE :
            m = len(liste_agents_TA)
            n = len(liste_agents_EV)
            matrice_TE = Matrice(m,n)
            #Remplissage de la matrice TE :
            for i in range (matrice_TE.m) :
                ligne = file.readline().split(",")
                del ligne[0]
                ligne = [v.replace("\n","") for v in ligne]
                ligne = [int(float(valeur)) for valeur in ligne]
                for j in range (matrice_TE.n) :
                    matrice_TE.data[i][j] = ligne[j]
            #Matrice AV :
            #Initialisation de la matrice AV :
            m = len(liste_agents_TA)
            n = len(liste_agents_EV)
            matrice_AV = Matrice(m,n)
            #Remplissage de la matrice AV :
            for i in range (matrice_AV.m) :
                ligne = file.readline().split(",")
                del ligne[0]
                ligne = [v.replace("\n","") for v in ligne]
                ligne = [int(float(valeur)) for valeur in ligne]
                for j in range (matrice_AV.n) :
                    matrice_AV.data[i][j] = ligne[j]      
        finally :
            file.close()
        return cash_total_systeme,dette_totale,matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,liste_salaires_indicatifs,liste_prix_indicatifs,liste_cash_agents_TA,liste_cash_agents_EV,liste_benefices_entreprises

    #Methode pour conserver des listes d'agents initiales :
    def conserver_listes_agents_init(self,liste_agents_TA,liste_agents_EV) :
        liste_agents_TA_init = []
        liste_agents_EV_init = []
        for i in range (len(liste_agents_TA)) :
            liste_agents_TA_init.append(liste_agents_TA[i])
        for j in range (len(liste_agents_EV)) :
            liste_agents_EV_init.append(liste_agents_EV[j])
        return liste_agents_TA_init,liste_agents_EV_init

    
        
    
    ###METHODE RUN :      
        
    def run(self) :
    
        t0 = time.clock()
 
        print "INITIALISATION"
        
        #Lecture des parametres :
        parametres = Parametres('input.txt')
        parametres.parse()
        
        nb_migrants = int(parametres.nb_migrants)
        
        #Instanciation des marches du travail et des biens :
        marche_travail = Marche_travail(parametres)
        marche_biens = Marche_biens(parametres)
        
        nb_TA_elimines = 0
        nb_EV_elimines = 0
        dette_totale = 0
        
        ###Recuperation de l'input migrants :
        print "RECUPERATION"
        cash_total_systeme,dette_totale,matrice_TE,matrice_AV,liste_agents_TA,liste_agents_EV,liste_salaires_indicatifs,liste_prix_indicatifs,liste_cash_agents_TA,liste_cash_agents_EV,liste_benefices_entreprises = self.lire_input_migrants()
        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_TE.data,fmt='%i',delimiter='\t')
        
        liste_agents_TA_init, liste_agents_EV_init = self.conserver_listes_agents_init(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,nb_migrants,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()
        #Collecte des donnees :
        self.collecter_donnees_cash_avant_migrants(myfile_cash,"Initialisation",liste_agents_TA_init,liste_agents_TA,nb_migrants,liste_agents_EV_init,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,cash_total_systeme)
        self.collecter_donnees_salaires(myfile_salaires,"Initialisation",liste_agents_EV_init,liste_agents_EV,liste_salaires_indicatifs)
        self.collecter_donnees_prix(myfile_prix,"Initialisation",liste_agents_EV_init,liste_agents_EV,liste_prix_indicatifs)

        moyenne_cash_TA = self.moyenne_cash_TA(liste_agents_TA)
        moyenne_cash_EV = self.moyenne_cash_EV(liste_agents_EV)
        
        print "\n"
        
        
        ###ITERATION 1 A 10 :
        for iteration in range (1,10) : 
        
            print "ITERATION " + str(iteration)
            
            liste_salaires_effectifs_precedente = self.maj_liste_salaires_effectifs_precedente(liste_salaires_indicatifs)
            liste_prix_indicatifs_precedente = self.maj_liste_prix_indicatifs_precedente(liste_prix_indicatifs)
            
            #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)
        
            #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_TE.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_avant_migrants(myfile_cash,iteration,liste_agents_TA_init,liste_agents_TA,nb_migrants,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_indicatifs)
            self.collecter_donnees_prix(myfile_prix,iteration,liste_agents_EV_init,liste_agents_EV,liste_prix_indicatifs)
        
            print "\n"
        
        
        
        
        ###INTEGRATION DES MIGRANTS :
        liste_agents_TA,matrice_TE,matrice_AV,liste_init_migrants = self.integrer_migrants(parametres,liste_agents_TA,liste_agents_EV,nb_migrants,matrice_TE,matrice_AV)
        np.savetxt(os.path.join(parametres.dossier,'matrice_TE_migrants' + str(0)),matrice_TE.data,fmt='%i',delimiter='\t')
        np.savetxt(os.path.join(parametres.dossier,'matrice_AV_migrants' + str(0)),matrice_TE.data,fmt='%i',delimiter='\t')
        
        
        
        
        ###RECHERCHE DE LA NOUVELLE HOMEOSTASIE :
        for iteration in range (1,parametres.it) : 
        
            print "ITERATION AVEC MIGRANTS " + 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)
        
            #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_TE.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_apres_migrants(myfile_cash,iteration,liste_agents_TA_init,liste_agents_TA,nb_migrants,liste_agents_EV_init,liste_agents_EV,liste_cash_agents_TA,liste_cash_agents_EV,cash_total_systeme,liste_init_migrants)
            self.collecter_donnees_salaires(myfile_salaires,iteration,liste_agents_EV_init,liste_agents_EV,liste_salaires_indicatifs)
            self.collecter_donnees_prix(myfile_prix,iteration,liste_agents_EV_init,liste_agents_EV,liste_prix_indicatifs)
        
            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"
        
        
        
        #Duree de la simulation :
        temps = time.clock() - t0
        self.collecter_donnees_temps(myfile_temps,temps)