/// <summary> /// 改进版Dijkstra算法求最小风险路径 /// </summary> /// <param name="forbidCity">未使用Yen算法时,此参数为null即可,否则该参数表示不可到达的路径集合</param> /// <param name="risks">到达各个城市的最大风险</param> /// <returns>全路径矩阵</returns> public City[][] Dijkstra_Def(int[][] forbidCity, out double[] risks) { /* * 变量初始化 */ double[] risks_temp = new double[GlobleVariable.cityNumber]; // 储存始发站到对应城市的风险总值 for (int i = 0; i < GlobleVariable.cityNumber; i++) { risks_temp[i] = GlobleVariable.INF; } int[] time_temp = new int[GlobleVariable.cityNumber]; // 储存始发站到对应城市的时间总值 City[][] path = new City[GlobleVariable.cityNumber][]; // 存储路径 for (int i = 0; i < GlobleVariable.cityNumber; i++) { path[i] = new City[GlobleVariable.cityNumber]; } City nextCity; // 迭代到的城市 int originVehicle = _originVehicle; int curTime = _curTime; int target = _origin; int[] flag = new int[GlobleVariable.cityNumber]; // 算法处理过的城市标记 if (forbidCity == null) { nextCity = GlobleVariable.CreatCity(target, curTime, originVehicle); // 始发城市设定 } else { nextCity = GlobleVariable.CreatCity(target, curTime, originVehicle, forbidCity); } originVehicle = 0; // 除了始发站外,其它城市可用所有交通工具 // 初始化始发城市初始可达的城市 for (int i = 0; i < GlobleVariable.cityNumber; i++) { path[i][0] = nextCity; } for (int i = 0; i < nextCity.RiskInfo.Length; i++) { if (nextCity.RiskInfo[i] != GlobleVariable.INF) { if (forbidCity == null) { path[i][1] = GlobleVariable.CreatCity(i, nextCity.CurTime + nextCity.TimeInfo[i], originVehicle); // 始发城市直接可达的城市加入路径中 } else { path[i][1] = GlobleVariable.CreatCity(i, nextCity.CurTime + nextCity.TimeInfo[i], originVehicle, forbidCity); } risks_temp[i] = nextCity.RiskInfo[i]; time_temp[i] = nextCity.TimeInfo[i]; } } flag[target] = 1; for (int j = 1; j < GlobleVariable.cityNumber; j++) { double min = GlobleVariable.INF; for (int i = 0; i < GlobleVariable.cityNumber; i++) { if (flag[i] == 0 && risks_temp[i] < min) { min = risks_temp[i]; target = i; } } if (forbidCity == null) { nextCity = GlobleVariable.CreatCity(target, curTime + time_temp[target], originVehicle); } else { nextCity = GlobleVariable.CreatCity(target, curTime + time_temp[target], originVehicle, forbidCity); } flag[target] = 1; for (int i = 0; i < GlobleVariable.cityNumber; i++) { if (flag[i] == 0 && nextCity.Reachable[i] != 0 && min + nextCity.RiskInfo[i] < risks_temp[i]) { risks_temp[i] = min + nextCity.RiskInfo[i]; time_temp[i] = time_temp[target] + nextCity.TimeInfo[i]; for (int k = 0; k < GlobleVariable.cityNumber; k++) { path[i][k] = path[target][k]; if (path[i][k] == null) { if (forbidCity == null) { path[i][k] = GlobleVariable.CreatCity(i, nextCity.CurTime + nextCity.TimeInfo[i], originVehicle); } else { path[i][k] = GlobleVariable.CreatCity(i, nextCity.CurTime + nextCity.TimeInfo[i], originVehicle, forbidCity); } break; } } } } } risks = risks_temp; return(path); }
/// <summary> /// 按下确认键后的事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Accept_Click(object sender, EventArgs e) { #region 判断始发城市通过所选定交通工具是否可出发 bool canTravelFromOrigin = false; City tempCity = GlobleVariable.CreatCity(newOne.Origin, GlobleVariable.dt.Hour, newOne.Vehicle); for (int i = 0; i < tempCity.Reachable.Length; i++) { if (tempCity.Reachable[i] != 0) { canTravelFromOrigin = true; break; } } #endregion if (OriginCities_cob.SelectedItem == null || DestCities_cob.SelectedItem == null || Vehicle_cob.SelectedItem == null) { MessageBox.Show("请将您的出行信息填写完整"); } else if (OriginCities_cob.SelectedIndex == DestCities_cob.SelectedIndex) { MessageBox.Show("请填写不同的始发城市和目的城市"); } else if (!canTravelFromOrigin) { MessageBox.Show("无法使用该交通工具从" + GlobleVariable.cityMapping[OriginCities_cob.SelectedIndex] + "出发\n请更换您所在的交通枢纽"); } else if (Limit_rad.Checked && string.IsNullOrWhiteSpace(Time_text.Text)) { MessageBox.Show("请输入您本次旅程的时间限制"); } else if (Limit_rad.Checked && !Regex.IsMatch(Time_text.Text, @"^\d+$")) { MessageBox.Show("请输入正确的时间!\n应输入一个正整数"); Time_text.Clear(); } else { if (Limit_rad.Checked) { newOne.LimitTime = Convert.ToInt32(Time_text.Text); } newOne.LimitTimeStrategy = Limit_rad.Checked; GlobleVariable.users.Add(newOne); MessageBox.Show("您的信息录入成功!\n即将生成推荐旅行路径......"); // 信息录入后应当记录 using (FileStream logWriter = new FileStream(GlobleVariable.logPath, FileMode.OpenOrCreate, FileAccess.Write)) { logWriter.Seek(0, SeekOrigin.End); string content = DateTime.Now.ToString() + "(程序内时间:" + GlobleVariable.dt.ToString() + "): "; content += UserName.Text + "设定了"; content += "始发城市" + newOne.Location + ","; content += "目标城市" + GlobleVariable.cityMapping[newOne.Dest] + "。"; content += "初始交通枢纽为" + Vehicle_cob.SelectedItem.ToString() + "。"; if (Limit_rad.Checked) { content += "选择了限时最小风险策略。限定时间为" + newOne.LimitTime + "小时\n\n"; } else { content += "选择了最小风险策略。\n\n"; } byte[] buffer = Encoding.Default.GetBytes(content); logWriter.Write(buffer, 0, buffer.Length); } ShowPath_win showPath = new ShowPath_win(GlobleVariable.users.Count - 1, _updateUserList); showPath.ShowDialog(); Close(); } }