Estoy aprendiendo los conceptos básicos de la teoría de juegos combinatorios ( juegos imparciales ). Después de aprender a descomponer un juego en la suma de juegos, me siento cómodo con los juegos que se pueden dividir en la suma de 1 pila de juegos. La situación me queda más o menos clara: tengo que encontrar la gráfica del juego, calcular los valores de Sprague-Grundy y utilizarlos para encontrar la solución a un juego.
Pero realmente no sé qué hacer en caso de que no pueda descomponer un juego en juegos de 1 pila. Aquí hay un ejemplo:
Tienes montones de piedras, la gente alterna turnos, la persona que no puede hacer un movimiento pierde. Durante el movimiento, un jugador puede seleccionar cualquiera de los montones y dividir las piedras en cualquier número de montones desiguales, de modo que dos de los montones recién creados no tengan el mismo número de piedras.
Tengo un gran problema al analizar el subjuego de 1 pila (calcular valores grundy para la pila de piedras en el montón), porque después de cada movimiento 1 montón se divide en más montones.
¿Cómo debo analizar tales juegos?
No es difícil usar la sugerencia de Jyrki para hacer una tabla de valores Sprague-Grundy de pequeños montones individuales:
Esperaba que el valor SG de sería , lo que sugiere un patrón de valores que aumentan en pero sumergiéndome en en cada potencia de . Dado que eso falló, no tengo una suposición razonable sobre el patrón real.
Probablemente valga la pena investigar la posibilidad de que para el valor SG de un montón de es simple ; Tengo la intención de pensarlo un poco.
Como comentó Jyrki , los movimientos en este juego descomponen montones en sumas de montones, y la regla xor aún se aplica cuando tienes una suma de más de dos montones.
Con un poco de código de Mathematica usando simplemente las reglas mex y xor para los valores de Sprague-Grundy, descubrí que los valores para una sola pila de tamaño medir son: . En particular, el valor de una sola pila de tamaño (dónde ) parece ser . Este tipo de patrón tiene sentido porque a medida que los números crecen, hay tantas formas de dividir la pila que puedes lograr cada número anterior como el xor de los valores que puedes alcanzar.
Sin embargo, no he podido ver un patrón obvio en los movimientos ganadores, así que no estoy seguro de cómo probar que este patrón continúa para siempre.
código:
moves[n_] := moves[n] =
Map[If[Union[#] == Sort[#] && Length[#] > 1, #, Nothing] &,
IntegerPartitions[n]];
mex[list_] := mex[list] =
Do[If[Not[MemberQ[list, i - 1]], Return[i - 1]], {i,Length[list] + 1}];
nimber[n_] := nimber[n] =
mex[Map[Apply[BitXor, Map[nimber, #]] &, moves[n]]];
Usando cgsuite, podemos llegar mucho más lejos. Si restringimos las reglas para decir que puede descomponer una pila en cinco pilas como máximo, entonces los valores de Sprague-Grundy se pueden calcular de manera muy eficiente mediante el código cgsuite :hr:=game.heap.HeapRules.MakeRules("&60;!.");
hr.NimValues(500)
Con esto, vemos que dividir en cinco montones como máximo es suficiente para que el patrón mencionado anteriormente persista hasta alcanzar el tamaño. con valor . Restringiendo a un máximo de cuatro montones pone un 0 entre 12 y 13, pero continúa un patrón a partir de entonces todo el camino hasta un tamaño de pila inicial de también. (A lo sumo tres pilas dan muy pocas opciones para un patrón simple).
Mariano Suárez-Álvarez
Jyrki Lahtonen
Salvador Dalí