Acelerar la variante de luces de luces en python puro -- python campo con performance campo con algorithm campo con programming-challenge campo con mathematics camp codereview Relacionados El problema

Speed up lights-out variant solver in pure Python


5
vote

problema

Español

Estoy haciendo algunos desafíos para aprender conceptos nuevos e interesantes, este es sobre una luces fuera Variante, en lugar de alternar solo los azulejos adyacentes, alterna toda la fila y el col.

Debe resolverse en python puro, por lo que no se permite que las bibliotecas adormecidas u otras que puedan ayudar se permitan aquí.

Adaptué el algoritmo de este excelente Ressource . Uso de un 2 * n 2 toggle matriz y un rompecabezas aplanado 9988776655544331 Podemos usar un álgebra lineal para calcular < CÓDIGO> T*x = P mod 22 , donde 9988776655544333 es la matriz de botones que debemos empujar para resolver el rompecabezas.

desde 1 & lt; n & lt; 16, este algoritmo puede necesitar resolver matrices de hasta 225x225, que lleva ~ 420 ms en mi máquina. Las restricciones de tiempo exactas no se dan, pero obtengo un error de tiempo de espera después de enviar.

Pasté un ejemplo en ejecución aquí , esto genera un rompecabezas aleatorio 15x15 e imprime algunos tiempos y la solución a ese rompecabezas particular.

El método performGaussianElimination(toggle, puzzle) lleva mucho más tiempo y parece ser el único cuello de botella, pero no veo un lugar donde pueda usar memoización u otros accesos directos para ahorrar tiempo. He buscado otros solversadores de álgebra lineal Python Pure, pero solo hay algunos (adormecidos es mucho más fácil) y no parecen ser mucho diferentes.

  def performGaussianElimination(toggle, puzzle):     nextFreeRow = 0     n = len(puzzle)     for col in xrange(n):         pivotRow = findPivot(toggle, nextFreeRow, col)         if pivotRow is None:             continue          swap(toggle, nextFreeRow, pivotRow)         swap(puzzle, nextFreeRow, pivotRow)          for row in xrange(pivotRow + 1, n):             if toggle[row][col]:                 for i in xrange(len(toggle[row])):                     toggle[row][i] ^= toggle[nextFreeRow][i]                 puzzle[row] ^= puzzle[nextFreeRow]          nextFreeRow += 1      return toggle, puzzle   

¿Puedo acelerar esto? ¿Es posible que este algoritmo tradicionalmente rápido no sea el más rápido para esta variante?

Original en ingles

I'm doing some challenges to learn new and interesting concepts, this one is about a Lights out variant, instead of toggling only the adjacent tiles, it toggles the whole row and col.

It must be solved in pure python, so no numpy or other libraries that might help are allowed here.

I adapted the algorithm of this excellent ressource. Using a n2*n2 toggle matrix and a flattened puzzle P we can use a linear algebra to calculate T*x = P mod 2, where x is the matrix of buttons we need to push to solve the puzzle.

Since 1 < n < 16, this algorithm may need to solve matrices up to 225x225, which takes ~420ms on my machine. The exact time constraints aren't given, but I get a timeout error after submitting.

I pasted a running example here, this generates a random 15x15 puzzle and prints out a few timings and the solution to that particular puzzle.

The method performGaussianElimination(toggle, puzzle) takes by far the longest and seems to be the only bottleneck, but I don't see a place where I could use memoization or other shortcuts to save time. I've looked for other pure python linear algebra solvers, but there are only a few (numpy is so much easier) and don't seem to be a lot different.

def performGaussianElimination(toggle, puzzle):     nextFreeRow = 0     n = len(puzzle)     for col in xrange(n):         pivotRow = findPivot(toggle, nextFreeRow, col)         if pivotRow is None:             continue          swap(toggle, nextFreeRow, pivotRow)         swap(puzzle, nextFreeRow, pivotRow)          for row in xrange(pivotRow + 1, n):             if toggle[row][col]:                 for i in xrange(len(toggle[row])):                     toggle[row][i] ^= toggle[nextFreeRow][i]                 puzzle[row] ^= puzzle[nextFreeRow]          nextFreeRow += 1      return toggle, puzzle 

Can I speed this up? Might this traditionally fast algorithm not be the fastest for this variant?

              
   
   

Lista de respuestas

4
 
vote
vote
La mejor respuesta
 

Tienes una matriz de bits. Podrías representar cada fila por un solo entero. (Recuerde que en Python, el tamaño de int es ilimitado, por lo que trabajar con 255 bits no es un problema). Luego, usted podría evitar el bucle interno aquí

  for row in xrange(pivotRow + 1, n):     if toggle[row][col]:         for i in xrange(len(toggle[row])):             toggle[row][i] ^= toggle[nextFreeRow][i]   

y haz esto en lugar

  public List<Employee> search(PersonalSpecs personalSpecs, EmployeeSpecs employeeSpecs, boolean nameComparable) {     List<Employee> result = new ArrayList<Employee>();      if (personalSpecs == null && employeeSpecs == null) {         return result;     }      // there is actually something to search on.     for (Employee employee : getAll()) {         if (employee.getPersonalSpecs().matches(personalSpecs, nameComparable) || (!nameComparable && employee.getEmployeeSpecs().matches(employeeSpecs))) {             result.add(employee);         }     }      return result; } 0  
 

You have a matrix of bits. You could represent each row by a single integer. (Remember that in Python the size of int is unlimited, so working with 255 bits is not a problem.) Then you would be able to avoid the inner loop here

for row in xrange(pivotRow + 1, n):     if toggle[row][col]:         for i in xrange(len(toggle[row])):             toggle[row][i] ^= toggle[nextFreeRow][i] 

and do this instead

col_mask = 1 << col for row in xrange(pivotRow + 1, n):     if toggle[row] & col_mask:         toggle[row] ^= toggle[nextFreeRow] 
 
 
       
       

Relacionados problema

4  Algoritmo más rápido para adaptar la expresión matemática dada  ( Faster algorithm to tailor given mathematical expression ) 
¿Hay una solución más optimizada para resolver el problema declarado? Dada una matriz 'Arr' de 'n' elementos y un número 'M', encuentra el menor índice 'Z' ...

2  Optimización del código para la secuencia A064604  ( Optimizing code for sequence a064604 ) 
Estoy implementando a064604 - oeis para enteros positivos de hasta 10 mil millones. Estoy encontrando a los divisores en $ o ( sqrt n) $. Por lo tanto, ...

13  Numérica para un cálculo de teoría de juegos usando la utilidad esperada  ( Numerics for a game theory calculation using expected utility ) 
Estoy tratando de replicar los resultados de Bruce B. de Mesquita (BDM) en la teoría del juego político para la predicción. Sobre la base de dónde se encuentr...

6  Determinar si f (n) = n ^ 2 + 3n + 5 es divisible por 121  ( Determining if fn n2 3n 5 is ever divisible by 121 ) 
Dado el siguiente problema: Se conjeture eso para cualquier $ N & GT; 0 $, $ N ^ 2 + 3n + 5 $ nunca es divisible por 121. Pruebe esta conjetura por ...

13  Plantilla de expresión para calcular la distancia euclidiana  ( Expression template to compute the euclidean distance ) 
Estaba escribiendo un código relacionado con el geometría nuevamente y tuvo un vistazo más de cerca a mi función que se supone que calcula la distancia euclid...

15  Función de sine en C / C ++  ( Sine function in c c ) 
Debido a las restricciones de software, No puedo usar las bibliotecas estándar, cmath , 9988776655544334 , plantillas, en línea o impulso . También estoy u...

3  Código C ++ para encontrar la distancia entre la línea y el punto  ( C code to find distance between line and point ) 
Así que hice este simple programa que permite a los usuarios construir puntos y líneas y luego devolver la distancia más pequeña entre un punto dado y una lín...

11  Números de colmena - usando goto en C ++  ( Beehive numbers using goto in c ) 
Entiendo que el uso de orca_array.hpp4 en el código C ++ está estrictamente no aconsejado, pero a veces, realmente reduce la cantidad de líneas de código co...

3  Análisis de simetría para arreglos atómicos en un cristal  ( Symmetry analysis for atom arrangements in a crystal ) 
Por un tiempo ahora he tenido la intención de publicar un poco de mi código Haskell aquí para que alguien pueda decirme qué partes de la biblioteca de idiomas...

4  Verificación computacional de la conjetura de Collatz utilizando OpenCl  ( Computational verification of collatz conjecture using opencl ) 
Esta solicitud de revisión de código sigue mi solicitud anterior Verificación computacional de Collatz Conyecture . A diferencia del programa anterior (que ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos