def travel(self,
            points: "IList<(Real, Real)>") -> "Iterable<(Real, Real)>":
     path = [points[0]]
     unvisited = set(points[1:])
     while len(unvisited) > 0:
         nn = argmin(unvisited, lambda xy: d(path[-1], xy))
         unvisited.remove(nn)
         path.append(nn)
     path.append(points[0])
     return path  #]nn
Esempio n. 2
0
 def successors(self) -> Iterable["SudokuPS"]:
     pos = argmin(self.vacias,
                  lambda pos: len(posibles_en(self.s, pos[0], pos[1])))
     if pos is None: return
     f, c = pos
     vacias_copia = deepcopy(self.vacias)
     vacias_copia.remove(pos)
     for num in posibles_en(self.s, f, c):
         copia_sudoku = deepcopy(self.s)
         copia_sudoku[f][c] = num
         yield SudokuPS(copia_sudoku, vacias_copia)
Esempio n. 3
0
 def successors(self) -> Iterable["SudokuPS"]:
     v = vacias(self.s)
     posible = argmin(self.lv,
                      lambda pos: len(posibles_en(self.s, pos[0], pos[1])))
     f, c = posible
     new_lv = deepcopy(self.lv)
     new_lv.remove(posible)
     for item in posibles_en(self.s, f, c):
         new_sudoku = deepcopy(self.s)
         new_sudoku[f][c] = item
         yield SudokuPS(new_sudoku, new_lv)
Esempio n. 4
0
 def some_to_some_backpointers(self, G: "acyclic IDigraph<T>", d: "T, T -> R", #[back
         I: "SizedIterableContainer<T>", 
         F: "SizedIterableContainer<T>") -> "Iterable<(T, T or None)>": 
     mem= self.createMap(G.V)
     left = len(F)
     for v in self.createTopsorter(G).topsorted(G):
         if left == 0: break
         u = argmin(G.preds(v), lambda u: mem[u] + d(u, v), ifempty=None)
         mem[v] = mem[u] + d(u,v) if u != None else infinity
         if v in I and 0 < mem[v]: mem[v], u = 0, v
         yield v, u
         if v in F: left -= 1 #]back
 def _mst(self, G: "undirected IDigraph<T>", 
          d: "T, T -> R", u: "T", added: "set<T>"=None) -> "Iterable<(T, T)>": #[p1
     added.add(u)
     in_frontier_from = self.createMap(G.V)
     for v in sorted(G.succs(u)): in_frontier_from[v] = u
     while len(in_frontier_from) > 0:
         (v, u) = argmin(in_frontier_from.items(), d)
         del in_frontier_from[v]
         added.add(v)
         yield (u, v)
         for w in sorted(G.succs(v)):
             if w not in added and \
                    (w not in in_frontier_from or d(v, w) < d(in_frontier_from[w], w)):
                 in_frontier_from[w] = v #]p1
 def change(self, Q: "int") -> "IList<int>":
     mem, back = [None] * (Q + 1), [None] * (Q + 1)
     mem[0] = 0
     for q in range(1, Q + 1):
         i_prime = argmin((i for i in range(self.n) if self.v[i] <= q),
                          lambda i: mem[q - self.v[i]] + self.w[i])
         mem[q] = mem[q - self.v[i_prime]] + self.w[i_prime]
         back[q] = q - self.v[i_prime]
     if mem[Q] == infinity:
         return []
     coins = []
     q = Q
     while back[q] != None:
         coins.append(q - back[q])
         q = back[q]
     return coins  #]class
Esempio n. 7
0
 def some_to_some_distance(
         self,
         G: "Digraph<T>",
         I: "Iterable<T>",  #[some2some
         F: "Iterable<T>") -> "Iterable<(T, T)>":
     length, backpointer = self.createMap(G.V), self.createMap(G.V)
     for s in I:
         length[s] = 0
         backpointer[s] = s
     bft = self.createBreadthFirstTraverser(G)
     bft.visitor = lambda u, v: (v, u)
     for (u, v) in bft.traverse_from_some(G, I, lambda u, v: (u, v)):
         if v != u:
             length[v] = length[u] + 1
             backpointer[v] = u
     return Backtracer(backpointer).backtrace(argmin(
         F, lambda v: length[v]))  #]some2some
Esempio n. 8
0
 def some_to_some_backpointers(self, G: "acyclic IDigraph<T>", d: "T, T -> R", 
         I: "SizedIterableContainer<T>", 
         F: "SizedIterableContainer<T>") -> "Iterable<(T, T or None)>": 
     D = self.createMap(G.V)
     back = self.createMap(G.V)
     for v in G.V: 
         D[v] = infinity
         back[v] = None
     for s in I: 
         D[s] = 0
         back[s] = s
     for _ in range(len(G.V)-1):
         for v in G.V:
             u = argmin(G.preds(v), lambda u: D[u] + d(u,v), ifempty=None)
             if u != None and D[u] + d(u, v) < D[v]:
                 D[v] = D[u] + d(u, v)
                 back[v] = u
     return back.items()#]pre
Esempio n. 9
0
 def successors(self):
     '''
     posicion = primera_libre(self.mat)
     if posicion != None:
         (fila, columna) = posicion
         for n in posibles_en(self.mat, fila, columna):
             self.mat[fila][columna] = n
             yield SudokuPS(self.mat)
             self.mat[fila][columna] = 0
     '''
     if len(self.pos_huecos) > 0:
         fila, col = argmin(self.pos_huecos, lambda x:len(posibles_en(self.mat, x[0], x[1])))
         self.pos_huecos.remove((fila, col))
         for n in posibles_en(self.mat, fila, col):
             self.mat[fila][col] = n
             yield SudokuPS(self.mat, self.pos_huecos)    
         self.pos_huecos.append((fila, col))
         self.mat[fila][col] = 0
Esempio n. 10
0
 def _mst(self,
          G: "undirected IDigraph<T>",
          d: "T, T -> R",
          u: "T",
          added: "set<T>" = None) -> "Iterable<(T, T)>":  #[p1
     added.add(u)
     in_frontier_from = self.createMap(G.V)
     for v in G.succs(u):
         in_frontier_from[v] = u
     while len(in_frontier_from) > 0:
         (v, u) = argmin(in_frontier_from.items(), d)
         del in_frontier_from[v]
         added.add(v)
         yield (u, v)
         for w in G.succs(v):
             if w not in added and \
                    (w not in in_frontier_from or d(v, w) < d(in_frontier_from[w], w)):
                 in_frontier_from[w] = v  #]p1
Esempio n. 11
0
def dikstra(g: UndirectedGraph, d: WeightingFunction, v_origen, v_final):
    D = {v: float("infinity") for v in g.V}
    added = set()
    frontera = {v_origen: v_origen}
    D[v_origen] = 0
    resultado = []
    while len(frontera) > 0:
        v_destino = argmin(frontera.keys(), lambda x: D[x])
        added.add(v_destino)
        v_origen = frontera[v_destino]
        resultado.append((v_origen, v_destino))
        del frontera[v_destino]
        if v_destino == v_final:
            break
        for suc in g.succs(v_destino):
            if suc not in added and D[v_destino] + d(v_destino, suc) < D[suc]:
                frontera[suc] = v_destino
                D[suc] = D[v_destino] + d(v_destino, suc)
    return resultado
Esempio n. 12
0
def dijkstra(G: "Graph<T>", d: "(T,T)->Float", v_inicial: "T", v_final: "T") -> "List<(T,T)>":
    recorrido_aristas = []
    D = {}
    for v in G.V: D[v] = float("infinity")
    d[v_inicial] = 0
    in_fringe_from = {}
    in_fringe_from[v_inicial] = v_inicial
    added = set()
    while len(in_fringe_from)>0:
        v_destino = argmin(in_fringe_from.keys(), lambda  v: D[v])
        #Devuelve la key de cuyo D es menor
        added.add(v_destino)
        v_origen = in_fringe_from[v_destino]
        recorrido_aristas.append((v_origen, v_destino))
        del in_fringe_from[v_destino]
        if v_destino == v_final: break
        for w in G.succs(v_destino):
            if w not in added and D[v_destino] + d(v_destino, w)< D[w]:
                D[w] = D[v_destino] + d(v_destino, w)
                in_fringe_from[w] = v_destino
    return recorrido_aristas
Esempio n. 13
0
 def successors(self):
     # IMPLEMENTAR
     '''
     if primera_libre(self.mat) != None: 
         f,c = primera_libre(self.mat)
         posibles = posibles_en(self.mat, f, c)
         for posible_valor in posibles:
             mat_aux = [row[:] for row in self.mat]
             mat_aux[f][c] = posible_valor
             yield SudokuPS(mat_aux)
     '''
     if len(self.pos_huecos) != 0:
         f, c = argmin(self.pos_huecos,
                       lambda x: len(posibles_en(self.mat, x[0], x[1])))
         posibles = posibles_en(self.mat, f, c)
         self.pos_huecos.remove([f, c])
         for posible_valor in posibles:
             self.mat[f][c] = posible_valor
             yield SudokuPS(self.mat, self.pos_huecos)
         self.pos_huecos.append([f, c])
         self.mat[f][c] = 0
 def change(self, Q: "int") -> "Real":
     mem = self.createMap()
     mem[0, 0] = 0
     for q in range(1, Q + 1):
         mem[q, 0] = infinity
     back = self.createMap()
     for n in range(1, self.n + 1):
         for q in range(Q + 1):
             i_prime = argmin(
                 range(q // self.v[n - 1] + 1), lambda i: mem[
                     q - i * self.v[n - 1], n - 1] + i * self.w[n - 1])
             mem[q, n] = mem[q - i_prime * self.v[n - 1],
                             n - 1] + i_prime * self.w[n - 1]
             back[q, n] = i_prime
     (q, n) = (Q, self.n)
     decisions = []
     while (q, n) in back:
         i = back[q, n]
         q, n = q - i * self.v[n - 1], n - 1
         decisions.append(i)
     decisions.reverse()
     return decisions  #]class
Esempio n. 15
0
def dijkstra(g: Digraph, d: WeightingFunction, v_inicial, v_final):
    D = {}
    added = set()
    recorrido = []
    for v in g.V:
        D[v] = float("infinity")
    D[v_inicial] = 0
    frontera = {v_inicial: v_inicial}
    while len(frontera) > 0:
        v_destino = argmin(frontera.keys(), lambda v: D[v])
        added.add(v_destino)
        v_origen = frontera[
            v_destino]  # Como en el recorrido de backpointers, aquí el origen del v_destino es el valor de los vertices frontera
        recorrido.append((v_origen, v_destino))
        del frontera[v_destino]
        if v_destino == v_final:
            break
        for i in g.succs(v_destino):
            if i not in added and D[v_destino] + d(v_destino, i) < D[i]:
                frontera[i] = v_destino
                D[i] = D[v_destino] + d(v_destino, i)
    return recorrido
Esempio n. 16
0
 def minimum_spanning_forest(self, G: "undirected IDigraph<T>", 
         d: "T, T -> R") -> "Iterable<(T, T)>": 
     G2 = self.createEditableUndirectedGraph(G.V)
     ccf = self.createConnectedComponentsFinder(G)
     while True:
         C = [list(c) for c in ccf.connected_components(G2)]
         lbl = self.createMap(G.V)
         for i in range(len(C)):
             for v in C[i]:
                 lbl[v] = i
         merged = [False]*len(C)
         for i in range(len(C)):
             if not merged[i]:
                 e = argmin(((u,v) for u in C[i] for v in G.succs(u) if lbl[u] != lbl[v]),
                             lambda edge: d(edge))
                 if e!=None:
                     G2.E.add_unchecked(e)
                     yield e
                     merged[lbl[e[1]]] = True
                     for v in C[lbl[e[1]]]:
                         lbl[v] = lbl[e[0]]
         if not any(merged): break #]baruvka
Esempio n. 17
0
 def some_to_some_distance(self, G: "acyclic IDigraph<T>", d: "T, T -> R",
                           I: "IterableContainer<T>",
                           F: "IterableContainer<T>") -> "R":
     mindist = infinity
     D = self.createMap(G.V)
     for v in G.V:
         D[v] = infinity
     for s in I:
         D[s] = 0
     added = self.createSet(G.V)
     left = len(F)
     while len(D) > 0 and left > 0:
         (v, Dv) = argmin(D.items(), lambda v_Dv: v_Dv[1])
         del D[v]
         added.add(v)
         if v in F:
             left -= 1
             if Dv < mindist: mindist = Dv
         if left > 0:
             for w in G.succs(v):
                 if w not in added and Dv + d(v, w) < D[w]:
                     D[w] = Dv + d(v, w)
     return mindist
Esempio n. 18
0
 def some_to_some_backpointers(self, G: "acyclic IDigraph<T>",
                               d: "T, T -> R", I: "IterableContainer<T>",
                               F: "IterableContainer<T>") -> "R":
     D = self.createMap(G.V)
     for v in G.V:
         D[v] = infinity
     for s in I:
         D[s] = 0
     in_fringe_from = self.createMap(G.V)
     for s in I:
         in_fringe_from[s] = s
     added = self.createSet(G.V)
     left = len(F)
     while len(in_fringe_from) > 0 and left > 0:
         (v, u) = argmin(in_fringe_from.items(), lambda e: D[e[0]])
         del in_fringe_from[v]
         added.add(v)
         yield (v, u)
         if v in F: left -= 1
         if left > 0:
             for w in G.succs(v):
                 if w not in added and D[v] + d(v, w) < D[w]:
                     D[w] = D[v] + d(v, w)
                     in_fringe_from[w] = v  #]dijkstra
Esempio n. 19
0
#coding: latin1

#< full
from algoritmia.datastructures.digraphs import Digraph, WeightingFunction
from algoritmia.problems.shortestpaths.acyclic import DagShortestPathsFinder
from algoritmia.problems.shortestpaths.backtracer import Backtracer
from algoritmia.utils import argmin

d = WeightingFunction({
    (0, 1): 3,
    (0, 3): -1,
    (1, 2): 5,
    (1, 4): 2,
    (1, 5): 4,
    (2, 4): 3,
    (2, 5): 1,
    (3, 1): 1,
    (4, 5): 1
})
G, I, F = Digraph(E=d.keys()), [0, 3], [2, 5]
backtracer = Backtracer(DagShortestPathsFinder().some_to_some_backpointers(
    G, d, I, F))
t = argmin(F, lambda v: backtracer.distance(v))
print('El camino más corto entre {} y {} recorre distancia {} y es {}'.format(
    I, F, backtracer.backtrace(t), backtracer.distance(t)))
#> full
Esempio n. 20
0
 def test_argmin(self):
     self.assertEqual(argmin((1, 2, 3, 4), lambda x: -x), 4)
     self.assertEqual(argmin([], lambda x: -x), None)