private static Move Calculate44Border(int[] pieces, ref int countStep) { Move borderMove = null; BinaryHeap nextQueue = new BinaryHeap(); Hashtable used = new Hashtable(); Move firstMove = new Move(pieces, -1, null, 4, 4); nextQueue.Insert(firstMove.borderScore - firstMove.level / FACTOR, firstMove); used[firstMove.borderSignature] = true; while (true) { if (nextQueue.Count == 0) break; countStep++; //Console.WriteLine(countStep); Move m = (Move)(nextQueue.Remove()); if (m.IsBorderFinished || FoundBorderSolution(m)) { borderMove = m; break; } Move[] newMoves = new Move[] { m.DownMove(), m.UpMove(), m.RightMove(), m.LeftMove() }; for (int i = 0; i < newMoves.Length; i++) { if (newMoves[i] == null) continue; if (newMoves[i].IsBorderFinished || FoundBorderSolution(newMoves[i])) { borderMove = newMoves[i]; break; } if (used[newMoves[i].borderSignature] != null) continue; //if (m.borderScore > (newMoves[i].borderScore+1)) continue; used[newMoves[i].borderSignature] = true; nextQueue.Insert(newMoves[i].borderScore - newMoves[i].level / FACTOR, newMoves[i]); //Console.WriteLine(newMoves[i].ToBorderString()); //Console.WriteLine(newMoves[i].borderScore); //if (newMoves[i].IsInvalid) //Console.ReadKey(); } if (borderMove != null) break; } if (!borderMove.IsBorderFinished) { borderMove = GetBorderSolution(borderMove); } //Console.WriteLine("4x4 border = " + countStep); conn.Clone(); return borderMove; }
public static string[] Solve(int[,] initial, ref int countStep, int maxStep, long durationPerClickMs, long timeLimitMs) { #if TRIAL maxStep = 25; #endif InitializeDatabase(); int[] count = new int[maxStep + 1]; AvgPathMove bestAnswer = null; BinaryHeap[] nextQueue = new BinaryHeap[6]; for (int color = 1; color < 6; color++) nextQueue[color] = new BinaryHeap(); Hashtable used = new Hashtable(); for (int color = 1; color < 6; color++) { int[,] initialColor = new int[9, 9]; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) initialColor[i, j] = (initial[i, j] == color) ? 1 : 0; AvgPathMove firstMove = new AvgPathMove(initialColor, null, null); nextQueue[color].Insert(firstMove.score, firstMove); used[firstMove.pos] = true; if (FoundSolution(firstMove, maxStep)) { bestAnswer = firstMove; break; } } long startTime = System.DateTime.Now.Ticks; while (bestAnswer == null) { if (((System.DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond) > timeLimitMs) return null; bool isBreak = true; for (int color = 1; color < 6; color++) if (nextQueue[color].Count > 0) isBreak = false; if (isBreak == true) break; countStep++; bool end = false; for (int color = 1; color < 6; color++) { AvgPathMove m = (AvgPathMove)(nextQueue[color].Remove()); AvgPathMove[] newMoves = new AvgPathMove[] { m.next(0,'U'),m.next(1,'U'), m.next(2,'U'), m.next(0,'D'),m.next(1,'D'), m.next(2,'D'), m.next(0,'R'),m.next(1,'R'), m.next(2,'R'), m.next(0,'L'),m.next(1,'L'), m.next(2,'L') }; for (int i = 0; i < newMoves.Length; i++) { if (used[newMoves[i].pos] != null) continue; if (FoundSolution(newMoves[i], maxStep)) { bestAnswer = newMoves[i]; end = true; break; } #if TRIAL if (newMoves[i].level >= 19) continue; #else if (newMoves[i].level >= (maxStep - 6)) continue; #endif count[newMoves[i].level]++; used[newMoves[i].pos] = true; nextQueue[color].Insert(newMoves[i].score, newMoves[i]); } if (end == true) break; } if (end == true) break; } if (bestAnswer == null) return null; //refAnswer = bestAnswer; string[] steps = new string[bestAnswer.level]; AvgPathMove b = bestAnswer; for (int i = steps.Length - 1; i >= 0; i--) { steps[i] = b.move; b = b.parent; } string[] contSteps = GetSolution(bestAnswer); string[] final = new string[steps.Length + contSteps.Length]; for (int i = 0; i < steps.Length; i++) final[i] = steps[i]; for (int i = 0; i < contSteps.Length; i++) final[i + steps.Length] = contSteps[i]; conn.Close(); return final; }
private static string[] Calculate(int dx, int dy, int[] pieces, ref int countStep) { InitializeDatabase(); BinaryHeap nextQueue = new BinaryHeap(); Hashtable used = new Hashtable(); Move finish = null; Move firstMove = new Move(pieces, "", null, dx, dy); nextQueue.Insert(firstMove.score, firstMove); int clickD = dx - 1; int clickD2 = clickD * clickD; used[firstMove.signature] = true; while (true) { if (nextQueue.Count == 0) break; countStep++; Move m = (Move)(nextQueue.Remove()); if (m.IsFinished || FoundSolution(m,dx)) { finish = m; break; } Move[] newMoves = new Move[clickD2*2]; for (int k=0;k<newMoves.Length;k++) { if ((k%2) == 0) newMoves[k] = m.GenMove(k/2,Move.Direction.CLOCKWISE); else newMoves[k] = m.GenMove(k/2,Move.Direction.COUNTER_CLOCKWISE); } for (int i = 0; i < newMoves.Length; i++) { if (newMoves[i] == null) continue; if (newMoves[i].IsFinished || FoundSolution(m,dx)) { finish = newMoves[i]; break; } if (used[newMoves[i].signature] != null) continue; used[newMoves[i].signature] = true; nextQueue.Insert(newMoves[i].score,newMoves[i]); //Console.WriteLine(newMoves[i].ToString()); //Console.ReadKey(); } if (finish != null) break; } if (finish == null) return null; if (!finish.IsFinished) { finish = GetSolution(finish,dx); } List<string> steps = new List<string>(); while (finish != null) { steps.Insert(0, finish.move); finish = finish.parent; } steps.RemoveAt(0); return steps.ToArray(); }
public static string[] Solve(int[] food_limits, int[] spoon_limits,ref int countStep) { BinaryHeap nextQueue = new BinaryHeap(); Hashtable used = new Hashtable(); Move finish = null; int[] foods = new int[food_limits.Length]; for (int i = 0; i < foods.Length; i++) foods[i] = 0; int[] spoons = new int[spoon_limits.Length]; for (int i = 0; i < spoons.Length; i++) spoons[i] = 0; Move firstMove = new Move(foods,spoons,food_limits,spoon_limits,"",null); nextQueue.Insert(firstMove.score, firstMove); used[firstMove.signature] = true; while (true) { if (nextQueue.Count == 0) break; countStep++; Move m = (Move)(nextQueue.Remove()); if (m.IsFinished) { finish = m; break; } Move[] newMoves = m.GenNextMoves(); for (int i = 0; i < newMoves.Length; i++) { if (newMoves[i] == null) continue; if (newMoves[i].IsFinished) { finish = newMoves[i]; break; } if (used[newMoves[i].signature] != null) continue; used[newMoves[i].signature] = true; nextQueue.Insert(newMoves[i].score, newMoves[i]); } if (finish != null) break; } if (finish == null) return null; List<string> steps = new List<string>(); while (finish != null) { //Console.WriteLine(finish.ToString()); steps.Insert(0, finish.move); finish = finish.parent; } steps.RemoveAt(0); return steps.ToArray(); }
/// <summary>Initialize the synchronized heap.</summary> /// <param name="heap">The heap to synchronize.</param> internal SyncBinaryHeap(BinaryHeap heap) { _heap = heap; }
/// <summary>Initialize the heap with another heap.</summary> /// <param name="heap">The heap on which to perform a shallow-copy.</param> public BinaryHeap(BinaryHeap heap) { // Clone the list (the only state we have) _list = (ArrayList)heap._list.Clone(); }
/// <summary>Ensures that heap is wrapped in a synchronous wrapper.</summary> /// <param name="heap">The heap to be wrapped.</param> /// <returns>A synchronized wrapper for the heap.</returns> public static BinaryHeap Synchronize(BinaryHeap heap) { // Create a synchronization wrapper around the heap and return it. if (heap is SyncBinaryHeap) return heap; return new SyncBinaryHeap(heap); }
public static string[] Solve(int[,] initial, ref int countStep, ref Move refAnswer, int maxStep, long durationPerClickMs, long timeLimitMs) { long startTime = DateTime.Now.Ticks; int[] count = new int[maxStep + 1]; int[] countScore = new int[10]; Move bestAnswer = null; Move[] answer = new Move[6]; BinaryHeap[] nextQueue = new BinaryHeap[6]; for (int color = 1; color < 6; color++) nextQueue[color] = new BinaryHeap(); Hashtable used = new Hashtable(); for (int color=1;color<6;color++) { int[,] initialColor = new int[9, 9]; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) initialColor[i, j] = (initial[i, j] == color) ? color : 0; Move firstMove = new Move(initialColor, null, null); answer[color] = firstMove; nextQueue[color].Insert(firstMove.level * -100 + firstMove.score, firstMove); used[firstMove.signature] = true; } while (true) { bool isBreak = true; for (int color = 1; color < 6; color++) if (nextQueue[color].Count > 0) isBreak = false; if (isBreak == true) break; countStep++; bool end = false; for (int color = 1; color < 6; color++) { Move m = (Move)(nextQueue[color].Remove()); if (m.score == 9) { answer[color] = m; end = true; break; } Move[] newMoves = new Move[] { m.next(0,'U'),m.next(1,'U'), m.next(2,'U'), m.next(0,'D'),m.next(1,'D'), m.next(2,'D'), m.next(0,'R'),m.next(1,'R'), m.next(2,'R'), m.next(0,'L'),m.next(1,'L'), m.next(2,'L') }; for (int i = 0; i < newMoves.Length; i++) { if (newMoves[i].score == 9) { answer[color] = newMoves[i]; end = true; break; } if ((newMoves[i].score > answer[color].score && newMoves[i].level == maxStep) || newMoves[i].score == 9) answer[color] = newMoves[i]; if (used[newMoves[i].signature] != null && answer[color] != newMoves[i]) continue; count[newMoves[i].level]++; countScore[newMoves[i].score]++; used[newMoves[i].signature] = true; if (newMoves[i].level >= maxStep) continue; nextQueue[color].Insert(newMoves[i].level*-100 + newMoves[i].score, newMoves[i]); } if (end == true) break; } Console.Clear(); for (int color = 1; color < 6; color++) { Console.WriteLine("Optimal steps = " + answer[color].level + " score=" + answer[color].score); Console.WriteLine(); answer[color].Print(); Console.WriteLine(); Console.WriteLine("Time used = " + ((answer[color].ticks - startTime) / TimeSpan.TicksPerMillisecond) + "ms"); } for (int color = 1; color < 6; color++) { if (bestAnswer == null || (answer[color].score == 9) || (bestAnswer.score < answer[color].score && answer[color].level == maxStep)) { bestAnswer = answer[color]; } } long timeUsed = ((DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond); //Console.WriteLine("Since beginning = " + timeUsed + "ms"); if (((bestAnswer.level * durationPerClickMs) + timeUsed) > (timeLimitMs - 1000)) break; if (end == true) break; } for (int color = 1; color < 6; color++) { if (bestAnswer == null || bestAnswer.score < answer[color].score || (bestAnswer.score == answer[color].score && bestAnswer.level > answer[color].level)) { bestAnswer = answer[color]; } } refAnswer = bestAnswer; string[] steps = new string[bestAnswer.level]; for (int i = steps.Length-1; i >= 0; i--) { steps[i] = bestAnswer.move; bestAnswer = bestAnswer.parent; } return steps; }