PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/KillerameiseGui/MainForm.cs

http://hwr-aco-g3.googlecode.com/
C# | 357 lines | 290 code | 52 blank | 15 comment | 25 complexity | 225cd309a7bccc6417cd67f4a458ab29 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using KillerAnts.Graph;
  10. using KillerAnts.Ants;
  11. using KillerAnts.Miscellaneous;
  12. using System.Threading;
  13. using KillerAnts.Properties;
  14. using System.IO;
  15. namespace KillerAnts
  16. {
  17. public partial class MainForm : Form
  18. {
  19. public String tspFileName = Settings.Default.tspFileName;
  20. private Node[] nodes;
  21. private AntStats globalAntStats;
  22. private SimulationParams globalSimParams;
  23. private int pgbMaximum = 0;
  24. private double bestDistance = 0;
  25. private double bestDistanceGlobal = 0;
  26. private double averageDistance = 0;
  27. private double averageDistanceGlobal = 0;
  28. private DateTime startTime;
  29. private DateTime stopTime;
  30. private DateTime lastGraphRefresh = DateTime.UtcNow;
  31. private const int graphRefreshTiming = 1000; // milliseconds
  32. private bool calculationIsRunning = false;
  33. private Thread workerThread;
  34. delegate void setIterationDelegate(string text);
  35. delegate void setAntDelegate(AntStats stats);
  36. public MainForm()
  37. {
  38. InitializeComponent();
  39. tspFileName = File.Exists(Settings.Default.tspFileName) ? Settings.Default.tspFileName : DefaultSettings.Default.tspFileName;
  40. if (File.Exists(tspFileName))
  41. {
  42. nodes = TourIO.NodesFromFile(tspFileName);
  43. }
  44. else
  45. {
  46. nodes = new Node[0]; // new empty tsp, because the tspFileName is still the same as the default one, it is can't be saved in the editor (save as works)
  47. }
  48. RedrawCanvas();
  49. ToolTip forButton = new ToolTip();
  50. string tooltiptext = "Fortschrittsbalken zeigt die relative Länge des Weges an";
  51. forButton.SetToolTip(groupBox1, tooltiptext);
  52. forButton.SetToolTip(groupBox2, tooltiptext);
  53. forButton.SetToolTip(labAverageDistance, tooltiptext);
  54. forButton.SetToolTip(labAverageDistanceGlobal, tooltiptext);
  55. forButton.SetToolTip(labBestDistance, tooltiptext);
  56. forButton.SetToolTip(labBestDistanceGlobal, tooltiptext);
  57. forButton.SetToolTip(valAverageDistance, tooltiptext);
  58. forButton.SetToolTip(valAverageDistanceGlobal, tooltiptext);
  59. forButton.SetToolTip(valBestDistance, tooltiptext);
  60. forButton.SetToolTip(valBestDistanceGlobal, tooltiptext);
  61. forButton.SetToolTip(pgbAverageDistance, tooltiptext);
  62. forButton.SetToolTip(pgbAverageDistanceGlobal, tooltiptext);
  63. forButton.SetToolTip(pgbBestDistance, tooltiptext);
  64. forButton.SetToolTip(pgbBestDistanceGlobal, tooltiptext);
  65. forButton.SetToolTip(pgbBestDistanceGlobal, tooltiptext);
  66. forButton.SetToolTip(imgWalkingAnt, "I'm walking");
  67. forButton.AutomaticDelay = 500;
  68. }
  69. private void koordinatenLadenToolStripMenuItem_Click(object sender, EventArgs e)
  70. {
  71. toolStripStatusLabel3.Text = "Geladene Datei:";
  72. dlgOpenTspFile.ShowDialog();
  73. if (dlgOpenTspFile.FileName != null && dlgOpenTspFile.FileName.Length > 0)
  74. {
  75. toolStripStatusLabel4.Text = dlgOpenTspFile.FileName;
  76. tspFileName = dlgOpenTspFile.FileName;
  77. nodes = TourIO.NodesFromFile(tspFileName);
  78. RedrawCanvas();
  79. }
  80. }
  81. private void Close(object sender, EventArgs e)
  82. {
  83. MainForm.ActiveForm.Close();
  84. }
  85. private void MainForm_Load(object sender, EventArgs e)
  86. {
  87. toolStripStatusLabel1.Visible = false;
  88. RedrawCanvas();
  89. }
  90. private void CancelCalculation(object sender, EventArgs e)
  91. {
  92. stopTime = DateTime.UtcNow;
  93. workerThread.Abort();
  94. SetCalculationMode(false);
  95. }
  96. public void RedrawCanvas()
  97. {
  98. graphCanvas.Clear();
  99. if (nodes.Length > 1)
  100. {
  101. graphCanvas.FitToNodes(nodes);
  102. graphCanvas.DrawNodes(nodes);
  103. }
  104. }
  105. private void StartSimulation(object sender, EventArgs e)
  106. {
  107. RedrawCanvas();
  108. toolStripStatusLabel1.Visible = true;
  109. toolStripStatusLabel2.Text = "0,0 ms";
  110. // reset progress bars
  111. pgbMaximum = 0;
  112. pgbBestDistance.Value = 0;
  113. pgbBestDistanceGlobal.Value = 0;
  114. pgbAverageDistance.Value = 0;
  115. pgbAverageDistanceGlobal.Value = 0;
  116. pgbIteration.Value = 0;
  117. pgbIteration.Maximum = paramPanel.GetSimulationParams().iterations;
  118. startTime = DateTime.UtcNow;
  119. // clear progress bar labels
  120. valBestDistance.Text = String.Empty;
  121. valBestDistanceGlobal.Text = String.Empty;
  122. valAverageDistance.Text = String.Empty;
  123. valAverageDistanceGlobal.Text = String.Empty;
  124. valIterationen.Text = "1 / 1";
  125. // solve trivial problems instantly
  126. switch (nodes.Length)
  127. {
  128. case 0:
  129. case 1:
  130. break;
  131. case 2:
  132. int[] wayPoints2 = { 0, 1 };
  133. graphCanvas.HighlightTour(nodes, wayPoints2);
  134. break;
  135. case 3:
  136. int[] wayPoints3 = { 0, 1, 2 };
  137. graphCanvas.HighlightTour(nodes, wayPoints3);
  138. break;
  139. default:
  140. valIterationen.Text = "0 / " + paramPanel.GetSimulationParams().iterations;
  141. SetCalculationMode(true);
  142. startTime = DateTime.UtcNow;
  143. statsTimer.Start();
  144. workerThread = new Thread(this.RunAnts);
  145. globalSimParams = paramPanel.GetSimulationParams();
  146. workerThread.Start(globalSimParams);
  147. break;
  148. }
  149. }
  150. private void RunAnts(Object data)
  151. {
  152. SimulationParams simParam = (SimulationParams)data;
  153. AntColony antColony = new AntColony(simParam, nodes);
  154. AntStats stats;
  155. int maxIterations = paramPanel.GetSimulationParams().iterations;
  156. for (int i = 1; i <= maxIterations; i++)
  157. {
  158. antColony.NextIteration();
  159. SetIteration(i + " / " + maxIterations);
  160. stats = antColony.GetStats();
  161. SetAntStats(stats);
  162. if (i == 1)
  163. {
  164. pgbMaximum = (int)(1.25 * stats.GetAverageDistance());
  165. }
  166. bestDistance = stats.GetBestDistance();
  167. bestDistanceGlobal = stats.GetBestDistanceGlobal();
  168. averageDistance = stats.GetAverageDistance();
  169. averageDistanceGlobal = stats.GetAverageDistanceGlobal();
  170. // always draw first and last iteration
  171. // and if the refresh checkbox is checked als every iterationModulo iteration
  172. bool draw = (i == maxIterations) || (i == 1) || (((DateTime.UtcNow - lastGraphRefresh).TotalMilliseconds > graphRefreshTiming) && cbRefreshCanvas.Checked);
  173. if (draw)
  174. {
  175. lastGraphRefresh = DateTime.UtcNow;
  176. graphCanvas.Clear();
  177. graphCanvas.DrawEdges(nodes, antColony.GetEdges());
  178. graphCanvas.HighlightTour(nodes, stats.GetBestTourGlobalWayPoints());
  179. graphCanvas.DrawNodes(nodes);
  180. }
  181. }
  182. calculationIsRunning = false;
  183. stopTime = DateTime.UtcNow;
  184. }
  185. private void SetIteration(string text)
  186. {
  187. if (this.valIterationen.InvokeRequired)
  188. {
  189. setIterationDelegate iterationDelegate = new setIterationDelegate(SetIteration);
  190. this.Invoke(iterationDelegate, new object[] { text });
  191. }
  192. else
  193. {
  194. valIterationen.Text = text;
  195. pgbIteration.PerformStep();
  196. }
  197. }
  198. private void SetAntStats(AntStats stats)
  199. {
  200. if (this.valIterationen.InvokeRequired)
  201. {
  202. setAntDelegate iterationDelegate = new setAntDelegate(SetAntStats);
  203. this.Invoke(iterationDelegate, new object[] { stats });
  204. }
  205. else
  206. {
  207. // save the stats to global
  208. globalAntStats = stats;
  209. ergebnisSpeichernToolStripMenuItem.Enabled = true;
  210. }
  211. }
  212. private void SetCalculationMode(bool calculating)
  213. {
  214. calculationIsRunning = calculating;
  215. btnStart.Enabled = !calculating;
  216. btnCancel.Enabled = calculating;
  217. menuStrip1.Enabled = !calculating;
  218. imgWalkingAnt.Enabled = calculating;
  219. ergebnisSpeichernToolStripMenuItem.Enabled = !calculating;
  220. if (calculating)
  221. {
  222. paramPanel.Disable();
  223. }
  224. else
  225. {
  226. paramPanel.Enable();
  227. }
  228. }
  229. private void StatsTimerTick(object sender, EventArgs e)
  230. {
  231. // refresh time running
  232. toolStripStatusLabel2.Text = String.Format("{0:0,0}", ((DateTime.UtcNow - startTime).TotalMilliseconds)) + " ms";
  233. // pgbMaximum will be set to 0 after starting a simulation and set to something above the average distance after
  234. // the first iteration
  235. if (pgbMaximum > 0)
  236. {
  237. RefreshStats();
  238. }
  239. if (!calculationIsRunning)
  240. {
  241. SetCalculationMode(false);
  242. // stop this timer
  243. ((System.Windows.Forms.Timer)sender).Stop();
  244. }
  245. }
  246. private void RefreshStats()
  247. {
  248. // if the progress bar maxima changed adjust it for all progress bars
  249. // this happens after the first iteration
  250. if (pgbBestDistance.Maximum != pgbMaximum)
  251. {
  252. pgbBestDistance.Maximum = pgbMaximum;
  253. pgbBestDistanceGlobal.Maximum = pgbMaximum;
  254. pgbAverageDistance.Maximum = pgbMaximum;
  255. pgbAverageDistanceGlobal.Maximum = pgbMaximum;
  256. }
  257. // refresh the progress bars, but do not set values above pbgMaximum
  258. // (which is also the maximum of the progress bars)
  259. pgbBestDistance.Value = (int)(bestDistance < pgbMaximum ? bestDistance : pgbMaximum);
  260. pgbBestDistanceGlobal.Value = (int)(bestDistanceGlobal < pgbMaximum ? bestDistanceGlobal : pgbMaximum);
  261. pgbAverageDistance.Value = (int)(averageDistance < pgbMaximum ? averageDistance : pgbMaximum);
  262. pgbAverageDistanceGlobal.Value = (int)(averageDistanceGlobal < pgbMaximum ? averageDistanceGlobal : pgbMaximum);
  263. // refresh labels right to the progress bars
  264. valBestDistance.Text = String.Format("{0:0.00}", bestDistance);
  265. valBestDistanceGlobal.Text = String.Format("{0:0.00}", bestDistanceGlobal);
  266. valAverageDistance.Text = String.Format("{0:0.00}", averageDistance);
  267. valAverageDistanceGlobal.Text = String.Format("{0:0.00}", averageDistanceGlobal);
  268. }
  269. private void editorToolStripMenuItem_Click(object sender, EventArgs e)
  270. {
  271. Editor editor = new Editor(tspFileName, nodes);
  272. editor.ShowDialog();
  273. nodes = editor.getNodes();
  274. tspFileName = editor.GetFileName();
  275. RedrawCanvas();
  276. }
  277. private void graphCanvas_Paint(object sender, PaintEventArgs e)
  278. {
  279. RedrawCanvas();
  280. }
  281. private void ergebnisSpeichernToolStripMenuItem_Click(object sender, EventArgs e)
  282. {
  283. SaveFileDialog saveFileDialog1 = new SaveFileDialog();
  284. saveFileDialog1.Filter = "Optimale Tour Datei|*.opt.tour";
  285. saveFileDialog1.Title = "Optimale Tour Datei speichern";
  286. saveFileDialog1.ShowDialog();
  287. if (saveFileDialog1.FileName != null && saveFileDialog1.FileName.Length > 0)
  288. {
  289. Tour bestTour = globalAntStats.GetBestTourGlobal();
  290. double time = (stopTime - startTime).TotalMilliseconds;
  291. TourIO.SaveOptimalTour(saveFileDialog1.FileName, globalSimParams, nodes, bestTour, globalAntStats.GetAverageDistanceGlobal(), time);
  292. }
  293. }
  294. private void OpenAbout(object sender, EventArgs e)
  295. {
  296. AboutForm about = new AboutForm();
  297. about.ShowDialog();
  298. }
  299. private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
  300. {
  301. Settings.Default.tspFileName = tspFileName;
  302. Settings.Default.Save();
  303. }
  304. }
  305. }