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
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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
#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
def test_argmin(self): self.assertEqual(argmin((1, 2, 3, 4), lambda x: -x), 4) self.assertEqual(argmin([], lambda x: -x), None)