示例#1
0
 def delta(self, n, o, d):
     dK = 0
     dW = {o:0, d:0}
     nE = set()
     dE = set()
     for v in self.neighbors(n):
         w = self[n][v]['weight']
         e = self[n][v]['edge']
         p = self.node[v]['partition']
         if p == d:
             dK -= w
             dW[d] += w
             dE.add(e)
         elif p == o:
             dK += w
             dW[o] -= w
             nE.add(e)
     W = {p: self.W[p] for p in self.W}
     W[o] += dW[o]
     W[d] += dW[d]
     dB = max(W.values()) * self.k / float(sum(W.values())) - self.eval['to']['balance']
     Wop = self.W[o] + dW[o]
     Wdp = self.W[d] + dW[d]
     Ko = self.K[o] * self.W[d] * Wop * Wdp
     Kd = self.K[d] * self.W[o] * Wop * Wdp
     Kop = (self.K[o] + dK) * self.W[o] * self.W[d] * Wdp
     Kdp = (self.K[d] + dK) * self.W[o] * self.W[d] * Wop
     Dn = self.W[o] * self.W[d] * Wop * Wdp
     dR = division(Kop + Kdp - Ko - Kd , Dn)
     return {'+e': nE, '-e': dE, 'dK': dK, 'dW': dW,
             'cut': dK, 'balance': dB, 'ratio': dR}
示例#2
0
    def partition(self, k=2, depth=None, theta=None, preemption=['ratio'], replays=0, rand=False, log=Stub()):
        eval = preemption[0]

        # Get P, E and C from a greedy solution
        super(Local, self).partition(k, select='weight', rand=rand)

        self.eval = {'from': {}, 'to': {}}
        self.eval['from']['cut'] = self.cut()
        self.eval['to']['cut'] = self.eval['from']['cut']
        self.eval['from']['balance'] = self.balance()
        self.eval['to']['balance'] = self.eval['from']['balance']
        self.eval['from']['ratio'] = sum([division(self.K[p], self.W[p]) for p in range(k)])
        self.eval['to']['ratio'] = self.eval['from']['ratio']

        min = {e: self.eval['to'][e] for e in self.eval['to']}
 
        iter = 0
        path = []
        best = []

        done = set()
        pool = [self.set_pool(eval, done)]

        move = Depth()

        step = 0

        try:

            while iter >= 0:
                while len(pool[iter]) != 0:
                    label = pool[iter].pop()
                    delta = label.delta[eval]

                    self.do(label)
                    if not self.broke(label, move.value, eval=eval, depth=depth, theta=theta):
                        step += 1
                        path.append(label)

                        log.write('Iteration ' + str(step) + '\n')
                        log.write('Eval(' + eval + ') ' + str(self.eval['to'][eval]) + '\n')
        
                        if compare(self.eval['to'], min, preemption) < 0:
                            min = {e: self.eval['to'][e] for e in self.eval['to']}
                            best = [l for l in path]
                            move.set(label=label)
                        move.forward(label, eval=eval)
                        pool.append(self.set_pool(eval, done, label=label))
                        iter += 1
                    else:
                        self.undo(label)

                if iter != 0: 
                    label = path.pop()
                    self.undo(label)
                    move.backward(label, eval=eval)
                    if self.broke(label, move.value, eval=eval, back=True, depth=depth, theta=theta):
                        break
                pool.pop()
                iter -= 1

            while len(path) != 0:
                label = path.pop()
                self.undo(label)

            for label in best:
                self.do(label)

            if compare(self.eval['to'], self.best['to'], preemption) < 0:
                P = [set() for p in range(self.k)]
                for n in self.nodes_iter():
                    P[self.node[n]['partition']].add(n)
                self.best['state'] = P
                self.best['step'] = step
                self.best['from'] = {e: self.eval['from'][e] for e in self.eval['from']}
                self.best['to'] = {e: self.eval['to'][e] for e in self.eval['to']}

            log.write('Operation success in ' + str(step) + ' iterations\n')
            log.write(str(self) + '\n\n')

        except KeyboardInterrupt:
            if compare(self.eval['to'], self.best['to'], preemption) < 0:
                self.best['state'] = P
                self.best['step'] = step
                self.best['from'] = {e: self.eval['from'][e] for e in self.eval['from']}
                self.best['to'] = {e: self.eval['to'][e] for e in self.eval['to']}
            eval  = 'Operation interrupted during process\n'
            eval += 'Iteration ' + str(self.best['step']) + '\n'
            eval += 'Best solution found:\n'
            eval += str(self) + '\n'
            raise KeyboardInterrupt(eval)

        if replays > 0:
            self.partition(k=k, depth=depth, theta=theta, preemption=preemption, replays=replays - 1, rand=True, log=log)
        else:
            self.apply(self.best)