} // end of function CreateT_S_S_Network_db void initVirStartNode(ref List <T_S_S_Node> stateNodeList, ref Queue <T_S_S_Node> queue_T_S_S_Node) { foreach (T_S_Node base_start_point in base_start_pointList) { T_S_S_Node t_s_s_node = new T_S_S_Node(); // 将起点放在编号前列,便于连续编号 // 这段丑陋,先这样 //foreach (CrewBase crewbase in CrewBaseList) { // if (base_start_point.StaCode == crewbase.StaCode) { // t_s_s_node.ID = crewbase.OIDinTSS; // break; // } //} t_s_s_node.ID = BaseStationToODIDDict[base_start_point.StaCode][0]; t_s_s_node.Init_db(t_s_s_node.ID, -1, -1, 0, base_start_point.TrainCode, base_start_point.StaCode, base_start_point.TimeCode, 0, base_start_point.StaCode, base_start_point.ID, -1, null, base_start_point, null); t_s_s_node.Resources = new Resource(LineList.Count); t_s_s_node.Price = 0; stateNodeList.Add(t_s_s_node); queue_T_S_S_Node.Enqueue(t_s_s_node); } }
public void CreateT_S_S_Network_db(/*CrewRule crewRule*/) { Debug.Assert(BasicTimeRules.MinConnTime != -1); List <T_S_S_Node> allStateNodes = new List <T_S_S_Node>(); Queue <T_S_S_Node> queue = new Queue <T_S_S_Node>(); initVirStartNode(ref allStateNodes, ref queue); //List<T_S_S_Node> tempDNodeList = new List<T_S_S_Node>(); //Dictionary<int, T_S_S_Node> IDToNodeDict = new Dictionary<int, T_S_S_Node>(); //foreach (var startNode in allStateNodes) { // IDToNodeDict.Add(startNode.ID, startNode); //} int debug_count = 100000; int debug_iter = 0; int nodeCount = CrewBaseList.Count * 2; //其余时空状态点的编号从乘务基地虚拟起终点之后开始 T_S_S_Node top_node; while (queue.Count > 0) { //if (--debug_count < 0) { // debug_count = 100000; // debug_iter++; // Console.WriteLine("current Queue.Count is [{0}]", queue.Count); // Console.WriteLine("debug iter is [{0}]", debug_iter); //} top_node = queue.Dequeue(); //Console.WriteLine(Logger.stateNodeInfoToStr(top_node, OutputMode.console)); //if (debug_iter >= 10) { // if (debug_count < 3000) { // Console.WriteLine("cur debug count is [{0}]", debug_count); // } //} T_S_Node cur_super_point = top_node.SuperPoint; List <T_S_Arc> out_T_S_ArcList = cur_super_point.Out_T_S_ArcList; for (int i = 0; i < out_T_S_ArcList.Count; i++) { T_S_Arc cur_t_s_arc = out_T_S_ArcList[i]; // debug //if (top_node.PassLine.Contains(30) // && top_node.PassLine.Contains(143) // //&& top_node.PassLine.Contains(64) // //&& top_node.PassLine.Contains(157) // && cur_t_s_arc.EndTimeCode == 1029 // && cur_t_s_arc.ArcType == 21) { // Console.WriteLine("top_node.PenaltyMealViolate:" + top_node.PenaltyMealViolate); //} //end debug T_S_S_Node extendStateNode = new T_S_S_Node(); extendStateNode.Resources = new Resource(lineList.Count); if (!FeasibleDriveTime(top_node, cur_t_s_arc, ref extendStateNode.Resources)) { continue; } if (!FeasibleDayCrewTime(top_node, cur_t_s_arc, ref extendStateNode.Resources)) { continue; } // 交路退乘点必须与出乘点相同 (必须回基地的约束) if (cur_t_s_arc.ArcType == 32 && cur_t_s_arc.EndStaCode != top_node.OStation) { continue; } // 用餐软约束 // 必须是非运行弧,才可能可以用餐 if (cur_t_s_arc.ArcType != 1) { handleMealConstraint(top_node, cur_t_s_arc, ref extendStateNode); // NOTE:可以处理一下,若当前弧用餐成功,则标记为用餐弧 } else { extendStateNode.Resources.SetLunchStatus(top_node.Resources.LunchStatus); extendStateNode.Resources.SetDinnerStatus(top_node.Resources.DinnerStatus); } // extendStartNode基本属性赋值 extendStateNode.Init_db(nodeCount, top_node.ID, cur_t_s_arc.LineID, cur_t_s_arc.RountingID, cur_t_s_arc.TrainCode, cur_t_s_arc.EndStaCode, cur_t_s_arc.EndTimeCode, cur_t_s_arc.ArcType, top_node.OStation, cur_t_s_arc.EndPointID, cur_super_point.ID, top_node, cur_t_s_arc.EndPoint, cur_super_point); // 还有其他属性 // 1 途径运行线 extendStateNode.PassLine.AddRange(top_node.PassLine); if (cur_t_s_arc.ArcType == 1) { extendStateNode.PassLine.Add(cur_t_s_arc.LineID); extendStateNode.Resources.LinesVisitedArray[cur_t_s_arc.LineID - 1] += 1; } // 2 起终点的编号 if (cur_t_s_arc.ArcType == 31) { extendStateNode.Price = 1440; Debug.Assert(extendStateNode.PenaltyMealViolate == 0); } else if (cur_t_s_arc.ArcType == 32) { extendStateNode.ID = BaseStationToODIDDict[extendStateNode.StaCode][1]; extendStateNode.Price = 0; --nodeCount; // 终点有自己的编号,所以此次不用增加nodeCount; Debug.Assert(extendStateNode.PenaltyMealViolate == 0); } else if (cur_t_s_arc.ArcType == 33) { extendStateNode.ID = BaseStationToODIDDict[extendStateNode.StaCode][1]; extendStateNode.Price = virtualRoutingCost; --nodeCount; // 终点有自己的编号,所以此次不用增加nodeCount; Debug.Assert(extendStateNode.PenaltyMealViolate == 0); } else { extendStateNode.Price = cur_t_s_arc.Len;// + extendStateNode.PenaltyMealViolate; //后续对弧再赋值Penalty } // 比较标号优劣 //for (int stateIdx = cur_t_s_arc.EndPoint.StateNodeSet.Count; stateIdx >= 0; stateIdx--) { //} top_node.Out_T_S_S_NodeList.Add(extendStateNode); allStateNodes.Add(extendStateNode); queue.Enqueue(extendStateNode); ++nodeCount; //if (cur_t_s_arc.ArcType != 32 && cur_t_s_arc.ArcType != 33) { // IDToNodeDict.Add(extendStateNode.ID, extendStateNode); //} //else { // tempDNodeList.Add(extendStateNode); //} } // end of loop "out_T_S_ArcList" } // end of loop "while" // 找出所有可行的状态点(即可以到达虚拟终点的状态点) #region //基于回溯 //T_S_S_NodeList = new List<T_S_S_Node>(); //foreach (T_S_S_Node note in tempDNodeList) { // int d = note.PrevID; // do { // if (IDToNodeDict.ContainsKey(d)) { // IDToNodeDict[d].Isfeasible = 1; // T_S_S_NodeList.Add(IDToNodeDict[d]); // d = IDToNodeDict[d].PrevID; // } // } // while (d != -1); //} //T_S_S_NodeList.AddRange(tempDNodeList); //T_S_S_NodeList.Sort(T_S_S_Node_AscByTime.nodeAsc); //int virODNum = CrewBaseList.Count * 2; //int newIDCount = virODNum; //foreach (var node in T_S_S_NodeList) { // if (node.ID >= virODNum) { // node.ID = newIDCount; // ++newIDCount; // } //} //foreach (var node in T_S_S_NodeList) { // if (node.PrevID >= 0) { // node.PrevID = node.PrevNode.ID; // } //} #endregion keepAllFeasibleStateNode(allStateNodes); // 根据可行状态点建立时空状态弧 createT_S_S_Arcs(); } // end of function CreateT_S_S_Network_db