/// <summary> /// HACK 計算が合っているかどうか、自身がない. /// </summary> /// <param name="prev"></param> /// <param name="fol"></param> /// <returns>そのブロックに初めて熱が伝わったかどうか</returns> public static bool gatherHeat(HeatMap.Block prev, HeatMap.Block fol) { float folTemp = 0f; folTemp += prev.temp * HeatingSearcher.partialTime / HeatingSearcher.blockSize * (1f - HeatingSearcher.k * prev.byBlocks.Count); foreach (var byPrev in prev.byBlocks) { folTemp += byPrev.temp * HeatingSearcher.partialTime / HeatingSearcher.blockSize * HeatingSearcher.k; } fol.temp = folTemp; return(!prev.heatedOnce && fol.heatedOnce); }
private void Dump() { StringBuilder mapBuilder = new StringBuilder(); StringBuilder lineBuilder = new StringBuilder(0, original.width); for (int y = original.height - 1; y >= 0; y--) { for (int x = 0; x < original.width; x++) { HeatMap.Block block = null; if (original[x, y] == Map.PATH) { foreach (var b in hMapFol.blocks) { if (x == b.pos.x && y == b.pos.y) { block = b; break; } } if (block != null) { lineBuilder.Append(block.heatedOnce ? "▲" : "△"); } else { lineBuilder.Append("●"); } } else { lineBuilder.Append("■"); } } mapBuilder.AppendLine(lineBuilder.ToString()); lineBuilder.Clear(); } Console.WriteLine("\n"); Console.WriteLine(mapBuilder.ToString()); }
public Map Solve() { heatedBlocks.Enqueue(hMapPrev.startBlock); double indexTime = 0f; double calcuTime = 0f; bool foundGoal = false; int count = 0; while (true) { count++; for (int i = 0; i < hMapPrev.blocks.Count; i++) { double t1 = Timer.ElapsedMilliSec(); var prev = hMapPrev.blocks[i]; var fol = hMapFol.blocks[i]; double t2 = Timer.ElapsedMilliSec(); indexTime += t2 - t1; bool transferredFirst = Mathf.gatherHeat(prev, fol); if (transferredFirst) { heatedBlocks.Enqueue(fol); // 入れるものは、PrevのとFolのとで、交互になるが、ルート生成時には距離で判断するので、多分問題にはならない if (fol.isGoal) { // 修了する foundGoal = true; goto FINISHED; } } double t3 = Timer.ElapsedMilliSec(); calcuTime += t3 - t2; } // 反転させる var tmpMap = hMapPrev; hMapPrev = hMapFol; hMapFol = tmpMap; } FINISHED :; Console.WriteLine("結果報告"); Console.WriteLine(" 総フレーム数: " + count); Console.WriteLine(" インデクス: " + indexTime / (double)count); Console.WriteLine(" 計算: " + calcuTime / (double)count); if (foundGoal) { Console.WriteLine("経路を求められました."); var heatedBlocks = this.heatedBlocks.ToArray(); HeatMap.Block lastBlock = heatedBlocks[heatedBlocks.Length - 1]; for (int i = heatedBlocks.Length - 2; i >= 0; i--) { var block = heatedBlocks[i]; if ((lastBlock.pos - block.pos).SqrDistance == 1) { original[block.pos.x, block.pos.y] = Map.ROUTE; lastBlock = block; } } return(original); } else { Console.WriteLine("経路を求められませんでした.\n作業内容を表示します.\n"); Dump(); return(null); } }