def gloutonV2(k, graph, verbose):
    g.gloutonWithCut(k, graph, verbose, True)
def kl(graph,verbose):
    print "Starting KL version 2.."
    startTime = time.time()
    ## Initialisation ##
    # Liste de partitions
    partitionsList = []
    # Initialisation des listes de sommets à étudier 
    # (une par partition)
    remainingNodesS1 = []
    remainingNodesS2 = []    
    
    ## Déroulement de l'algo ##    
    # bipartition
    partitionsList, graph = g.gloutonWithCut(2,graph,False,False)
    if verbose:
        print "Partition Init 1: ", partitionsList[0]
        print "Partition Init 2: ", partitionsList[1]

    deltaTime = -time.time()
    
    ratio = 20    
    
    # Mise a jour des listes des sommets à étudier
    remainingNodesS1 = list(partitionsList[0])[len(partitionsList[0])*(100-ratio)/100:]
    remainingNodesS2 = list(partitionsList[1])[len(partitionsList[1])*(100-ratio)/100:]

    # calcul du gain global initial
    globalMin = objf.calculateCut(remainingNodesS1,remainingNodesS2,graph)
    #  Initialisation du gain fictif
    GainGlobalFictif = globalMin
    if verbose:
        print "Global Min Initial:", globalMin
        print ""
        print "Recherche de sommets uniques à changer..."   
   
    nodesList = nx.nodes(graph)
    iterations = 100
    while iterations > 0 :
        improvement = False
        localMin = sys.maxint
        
        for node in nodesList:
            gain = calculateFictifGainUnique(node, partitionsList[0], partitionsList[1], graph)
            
            # recherche du meilleur gain local            
            if gain < localMin  and gain > 0 :
                improvement = True
                localMin = gain
                s = node
                GainGlobalFictif = globalMin - gain
                if verbose:
                    print "Nouveau gain local:", localMin, "Node: ", node
                    print "Gain Global Fictif =", GainGlobalFictif

        if improvement :
            nodesList.remove(s)        
        if (GainGlobalFictif < globalMin):
            globalMin = GainGlobalFictif
            if verbose:
                print "Nouveau gain global:", globalMin, "Node:", s
                print "Le noeud",s,"a été échangé de partition"
            partitionsList = switchNodesUnique(partitionsList,s)
        
        iterations = iterations - 1
 
    stopTime = time.time()
    deltaTime += time.time()
    print "Temps d'exécution total:", stopTime-startTime
    print "Temps d'exécution KL:", deltaTime
    if verbose:
        print "Partition Finale 1:", partitionsList[0]
        print "Partition Finale 2:", partitionsList[1]
    print "Global cut:", objf.calculateCut(partitionsList[0], partitionsList[1], graph)
def recuitSimule(graph, iterations, tempI, remonteeMax,verbose):
    print "Starting Recuit Simule with", iterations, "iterations,", tempI, "as initial temperature and", remonteeMax, "as max upgoing movements"

    deltaTime0 = -time.time()    
    
    ## Initialisation ##
    # Liste de partitions
    partitionsList = [] 
    
    # Appel du Glouton
    partitionsList, graph = g.gloutonWithCut(2,graph,False,False)
    P1Final = list(partitionsList[0])
    P2Final = list(partitionsList[1])
    if verbose :
        print "Partition P1 init :", P1Final
        print "Partition P2 init :", P2Final

    print "Number of nodes in graph:", nx.number_of_nodes(graph)
    # calcul du gain global initial
    globalMin = objf.calculateCut(partitionsList[0],partitionsList[1],graph)
    
    #  Initialisation du gain fictif
    GainGlobalFictif = globalMin
    print "Global Min Initial:", globalMin

    # Temps de départ
    deltaTime = -time.time()
    
    # Nombre d'iteration de l'algorithme
    iterationsC = 0

    # Nombre courant de remontée de temperature consecutives
    remontee = 0
    
    # Temperature courante
    tempC = tempI
    
    list_pourcentage = [0,10,20,30,40,50,60,70,80,90]
    
    nodesOnLimit,neighborsList = neighbors(partitionsList[0],graph)
    
    # Boucle principale
    while iterationsC < iterations :
        pourcentage = (iterationsC*100)/iterations
        if pourcentage in list_pourcentage:
            del(list_pourcentage[0])
            print '------------------',pourcentage, "% effectués", '------------------'            
            
        change = False

        # Candidat aleatoire de la partition P1
        nodeA = selectNode(nodesOnLimit)
        # Candidat aleatoire de la partition P2
        nodeB = selectNode(neighborsList)

        # Calcul du gain lié à l'échange de nodeA et nodeB : G(nodeA,nodeB)
        gainAB = calculateFictifGain(nodeA, nodeB, partitionsList[0], partitionsList[1], graph)
        
        if verbose:
            print "Gain entre",nodeA,"et",nodeB,"=",gainAB
        # Amelioration solution locale
        if gainAB >= 0 :
            change = True
            remontee = 0
            if verbose :
                print "Descente en temperature avec les noeuds", nodeA, "et", nodeB                
                
        else:
            # Acceptation de la solution dégradante 
            if random() < exp(gainAB/tempC) and remontee < remonteeMax :
                change = True
                remontee +=1
                if verbose :
                    print "Remontee en temperature avec les noeuds", nodeA, "et", nodeB                

        # Changement a effectuer                                        
        if change :
            # On echange les sommets nodeA et nodeB
            partitionsList = switchNodes(partitionsList,nodeA,nodeB)
            updateNeighbors(nodeA,nodeB,nodesOnLimit,neighborsList,partitionsList[0],partitionsList[1],graph)
            
            GainGlobalFictif = GainGlobalFictif - gainAB
            if verbose:
                print "Les noeuds",nodeA,"et",nodeB, "ont été échangés"
                print "Gain fictif =", GainGlobalFictif
            
            if GainGlobalFictif < globalMin and GainGlobalFictif > 0:
                globalMin = GainGlobalFictif
                print "Update globalMin =",globalMin
                P1Final = list(partitionsList[0])
                P2Final = list(partitionsList[1])
        
        # cas où la remontee de temperature n'a que fait dégrader la solution
        if remontee == remonteeMax and not change :
            if verbose:
                print "Degradation trop élevée --> récupération des anciennes partitions"
            # récupération de la meilleure partition
            partitionsList[0] = list(P1Final)
            partitionsList[1] = list(P2Final)
            nodesOnLimit,neighborsList = neighbors(partitionsList[0],graph)
        
        addRandomNode(nodesOnLimit, partitionsList[0])
        addRandomNode(neighborsList, partitionsList[1])        
        
        iterationsC +=1
        tempC = 0.99*tempC
    

    deltaTime += time.time()
    deltaTime0 += time.time()
    if verbose:
        print "Partition Finale 1:", P1Final
        print "Partition Finale 2:", P2Final    
    print "Temps d'exécution recuit-simule:", deltaTime
    print "Temps d'exécution global:", deltaTime0
    print "Global cut:", globalMin