public Distribution(string evt, MDPState target) { Event = evt; States = new List<KeyValuePair<double, MDPState>>(); States.Add(new KeyValuePair<double, MDPState>(1, target)); inMatrix = false; }
//re-calculate the distribution after removing selfloop //public Distribution DistrbutionReCalculate(List<string> newSCC, MDPState node, Distribution distr) //{ // double nonSelfLoopProb = 0.0; // for (int i = 0; i < distr.States.Count; i++) // { // KeyValuePair<double, MDPState> pair = distr.States[i]; // if (newSCC.Contains(pair.Value.ID)) // { // //selfLoopProb += pair.Key; // //hasSelfLoop = true; // //the self loop is removed in this distribution // distr.States.Remove(pair); // //i-- is used to keep the loop correct after removing one element // i--; // } // else // { // nonSelfLoopProb += pair.Key; // } // } // foreach (KeyValuePair<double, MDPState> pair in distr.States) // { // //KeyValuePair<double, MDPState> newPair = new KeyValuePair<double, MDPState>(pair.Key / nonSelfLoopProb, pair.Value); // distr.AddProbStatePair(pair.Key / nonSelfLoopProb, pair.Value); // distr.States.Remove(pair); // } // return distr; //} //this method is used to remove all loops in a DTMC. public MDP BuildQuotientMDPBisimulation(VerificationOutput VerificationOutput) { MDP toReturn = new MDP(Precision, MAX_DIFFERENCE); //calculate the nonsafe states, whose maximal prob is not 0 Stack<MDPState> NonSafe = new Stack<MDPState>(TargetStates); Stack<MDPState> helper = new Stack<MDPState>(TargetStates); //backward checking from target states while (helper.Count != 0) { MDPState t = helper.Pop(); foreach (MDPState s in t.Pre) { bool addState = false; //check each distribution; as long as s has a post state in NonSafe, then s should be added. foreach (Distribution distribution in s.Distributions) { foreach (KeyValuePair<double, MDPState> pair in distribution.States) { if (NonSafe.Contains(pair.Value)) { addState = true; //s.Distributions.Remove(distribution); break; } } if (addState) { break; } } if (addState && !NonSafe.Contains(s)) { helper.Push(s); NonSafe.Push(s); } } } //note here remaining doesn't include the target states and initial states HashSet<MDPState> remaining = new HashSet<MDPState>(); foreach (MDPState mdpState in NonSafe) { if (!TargetStates.Contains(mdpState) && InitState != mdpState) { remaining.Add(mdpState); } } //add Initial MDPState Initial = new MDPState(InitState.ID); toReturn.AddState(Initial); toReturn.SetInit(Initial); //add target MDPState Target = new MDPState("target"); toReturn.AddState(Target); toReturn.AddTargetStates(Target); //add safe MDPState Safe = new MDPState("safe"); toReturn.AddState(Safe); //add remaining //MDPState Remaining = new MDPState("remaining"); //toReturn.AddState(Remaining); //add selfloop at Target. //Target.AddDistribution(new Distribution(Constants.TAU, Target)); //add selfloop at Safe. //Safe.AddDistribution(new Distribution(Constants.TAU, Safe)); //add the group distributions in Remaining List<HashSet<MDPState>> SeperatingRemaining = new List<HashSet<MDPState>>(); SeperatingRemaining.Add(remaining); bool refinement = true; while (refinement)//if the former iteration has splitted some groups { refinement = false; for (int i = 0; i < SeperatingRemaining.Count; i++) { HashSet<MDPState> mdpStates = SeperatingRemaining[i]; if (mdpStates.Count > 1) { Dictionary<string, HashSet<MDPState>> groups = SeperateGroup(SeperatingRemaining, mdpStates, Initial, Target, Safe); if (groups.Count > 1) { SeperatingRemaining.RemoveAt(i--); foreach (KeyValuePair<string, HashSet<MDPState>> keyValuePair in groups) { SeperatingRemaining.Add(keyValuePair.Value); } refinement = true; } } } //List<HashSet<MDPState>> NewSeperating = new List<HashSet<MDPState>>(); //foreach (HashSet<MDPState> mdpStates in SeperatingRemaining) //{ // if (mdpStates.Count > 1) // { // int counter = 0; // foreach (HashSet<MDPState> grouped in SeperateGroup(SeperatingRemaining, mdpStates, Initial, Target, Safe).Values) // { // counter++; // NewSeperating.Add(grouped); // } // if (counter > 1) // { // refinement = true; // } // } // else // { // NewSeperating.Add(mdpStates); // } // } ////todo: reduce the loop number //SeperatingRemaining = NewSeperating; } //add distributions after all the refinement foreach (HashSet<MDPState> mdpStates in SeperatingRemaining) { //add representative state of each groupd states MDPState Grouped = StateFromHashset(mdpStates); toReturn.AddState(new MDPState(Grouped.ID)); } foreach (MDPState state in toReturn.States.Values) { if (state.ID == "target" || state.ID == "safe") { continue; } HashSet<Distribution> DistrToAdd = new HashSet<Distribution>(); foreach (Distribution Distr in this.States[state.ID].Distributions) { Distribution newDistr = calcGroupedDistr(SeperatingRemaining, Distr, Initial, Target, Safe, toReturn); DistrToAdd.Add(newDistr); } foreach (Distribution distribution in DistrToAdd) { toReturn.AddDistribution(state.ID, distribution); } } //foreach (HashSet<MDPState> mdpStates in SeperatingRemaining) //{ // MDPState Grouped = StateFromHashset(mdpStates); // FinalgroupedDistribution(SeperatingRemaining, Grouped, Target, Safe, toReturn);//calculate the grouped distributions //} //note: add initial state's distributions after refinement //FinalgroupedDistribution(SeperatingRemaining, InitState, Target, Safe, toReturn); return toReturn; }
public void AddProbStatePair(double prob, MDPState state) { States.Add(new KeyValuePair<double, MDPState>(prob, state)); }
public void SetInit(MDPState init) { InitState = init; }
protected MDP BuildMDP() { Stack<KeyValuePair<MDPConfiguration, MDPState>> working = new Stack<KeyValuePair<MDPConfiguration, MDPState>>(1024); string initID = InitialStep.GetID(); MDPState init = new MDPState(initID); working.Push(new KeyValuePair<MDPConfiguration, MDPState>(InitialStep as MDPConfiguration, init)); MDP mdp = new MDP(init, Ultility.Ultility.DEFAULT_PRECISION, Ultility.Ultility.MAX_DIFFERENCE); do { if (CancelRequested) { VerificationOutput.NoOfStates = mdp.States.Count; return mdp; } KeyValuePair<MDPConfiguration, MDPState> current = working.Pop(); IEnumerable<MDPConfiguration> list = current.Key.MakeOneMoveLocal(); VerificationOutput.Transitions += list.Count(); int currentDistriIndex = -1; Distribution newDis = new Distribution(Constants.TAU); //for (int i = 0; i < list.Count; i++) foreach (var step in list) { //MDPConfiguration step = list[i]; string stepID = step.GetID(); MDPState nextState; if (!mdp.States.TryGetValue(stepID, out nextState)) { nextState = new MDPState(stepID); mdp.AddState(nextState); ExpressionValue v = EvaluatorDenotational.Evaluate(ReachableStateCondition, step.GlobalEnv); if ((v as BoolConstant).Value) { mdp.AddTargetStates(nextState); } else { working.Push(new KeyValuePair<MDPConfiguration, MDPState>(step, nextState)); } } if (step.DisIndex == -1) { if (currentDistriIndex >= 0) { current.Value.AddDistribution(newDis); newDis = new Distribution(Constants.TAU); } Distribution newTrivialDis = new Distribution(step.Event); newTrivialDis.AddProbStatePair(1, nextState); current.Value.AddDistribution(newTrivialDis); } else if (currentDistriIndex != -1 && step.DisIndex != currentDistriIndex) { current.Value.AddDistribution(newDis); newDis = new Distribution(Constants.TAU); newDis.AddProbStatePair(step.Probability, nextState); } else { newDis.AddProbStatePair(step.Probability, nextState); } currentDistriIndex = step.DisIndex; } if (currentDistriIndex >= 0) { current.Value.AddDistribution(newDis); } } while (working.Count > 0); VerificationOutput.NoOfStates = mdp.States.Count; //mdp.BackUpTargetStates(); return mdp; }
//public void FinalgroupedDistribution(List<HashSet<MDPState>> AfterRefined, HashSet<MDPState> mdpStates, MDPState Target, MDPState Safe, MDP Returned) //{ // foreach (MDPState State in mdpStates) // { // FinalgroupedDistribution(AfterRefined, State, Target, Safe, Returned); // } //} //public void FinalgroupedDistribution(List<HashSet<MDPState>> AfterRefined, MDPState mdpState, MDPState Target, MDPState Safe, MDP Returned) //{ // HashSet<Distribution> DistrToAdd = new HashSet<Distribution>(); // foreach (Distribution Distr in mdpState.Distributions) // { // Distribution newDistr = calcGroupedDistr(AfterRefined, Distr, Returned.InitState, Target, Safe, Returned); // DistrToAdd.Add(newDistr); // } // foreach (Distribution distribution in DistrToAdd) // { // Returned.AddDistribution(mdpState.ID, distribution); // } //} public Dictionary<string, HashSet<MDPState>> SeperateGroup(List<HashSet<MDPState>> seperation, HashSet<MDPState> mdpStates, MDPState Initial, MDPState Target, MDPState Safe) { Dictionary<string, HashSet<MDPState>> record = new Dictionary<string, HashSet<MDPState>>(); foreach (MDPState State in mdpStates) { string disstring = ""; HashSet<Distribution> dis = new HashSet<Distribution>(); foreach (Distribution Distr in State.Distributions) { dis.Add(calcGroupedDistr(seperation, Distr, Initial, Target, Safe, this)); //disstring += calcGroupedDistr(seperation, Distr, Initial, Target, Safe, this).ToString(); //dis += State.ID; } foreach (var distribution in dis) { disstring += distribution.ToString(); } if (record.Count == 0) { HashSet<MDPState> states = new HashSet<MDPState>(); states.Add(State); record.Add(disstring, states); } else { if (record.ContainsKey(disstring)) { //todo: too slow here.. record[disstring].Add(State); continue; } HashSet<MDPState> states = new HashSet<MDPState>(); states.Add(State); record.Add(disstring, states); } } return record; }
public void AddZenoStates(MDPState zeno) { //TargetStates.Add(target); //target.Distributions.Clear(); zeno.CurrentProb = -1; }
public MDP ComputeGCPP(VerificationOutput VerificationOutput) { MDP toReturn = new MDP(Precision, MAX_DIFFERENCE); //add Initial MDPState Initial = new MDPState(InitState.ID); toReturn.AddState(Initial); toReturn.SetInit(Initial); //add target foreach (MDPState targetstate in this.TargetStates) { AddTargetStates(targetstate); } //note here remaining doesn't include the target states and initial states HashSet<MDPState> remaining = new HashSet<MDPState>(); foreach (MDPState mdpState in States.Values) { if (!TargetStates.Contains(mdpState) && InitState != mdpState) { remaining.Add(mdpState); } } //instantiate GCPP GCPP gcpp = new GCPP(); Dictionary<string, int> table = new Dictionary<string, int>(); foreach (MDPState mdpState in remaining) { gcpp.MDPTable.Add(mdpState.ID, mdpState); table.Add(mdpState.ID, 0); } int n = 0; foreach (MDPState mdpState1 in remaining) { foreach (MDPState mdpState2 in remaining) { List<MDPState> list = new List<MDPState>(); if (mdpState1 != mdpState2 && table[mdpState1.ID] == table[mdpState2.ID] && PropositionEquals(mdpState1, mdpState2)) { list.Add(mdpState1); list.Add(mdpState2); table[mdpState1.ID] = 1; table[mdpState2.ID] = 1; gcpp.PartOrder.Add(n, n); gcpp.Partition.Add(n, list); gcpp.PartitionGetKey.Add(list, n++); } } } gcpp.partition = null; gcpp.partorder = null; while (gcpp.Partition != gcpp.partition || gcpp.PartOrder != gcpp.partorder) { gcpp.partition = gcpp.Partition; gcpp.partorder = gcpp.PartOrder; foreach (List<MDPState> B in gcpp.partition.Values) { //GCPP item = new GCPP(); gcpp = Split(gcpp, B); //∑:=∑\{B}∪{∑B} gcpp.Partition.Remove(gcpp.PartitionGetKey[B]); foreach (KeyValuePair<int, List<MDPState>> pair in gcpp.partition) { gcpp.Partition.Add(n, pair.Value); gcpp.PartitionGetKey.Add(pair.Value, n); } //≤:=≤∪≤B // ∪{(B',X)|X∈∑:B'∈∑B:(B,X)∈≤} // ∪{(X,B')|X∈∑:B'∈∑B:(X,B)∈≤} // \{(B,X),(X,B)|X∈∑:(X,B),(B,X)∈≤} foreach (KeyValuePair<int, int> pair in gcpp.partorder) { gcpp.PartOrder.Add(pair.Key, pair.Value); } foreach (List<MDPState> X in gcpp.Partition.Values) { if (SamePartOrder(X, B, gcpp.PartOrder, gcpp.PartitionGetKey) && SamePartOrder(B, X, gcpp.PartOrder, gcpp.PartitionGetKey)) { var query1 = from p in gcpp.PartOrder where p.Key == gcpp.PartitionGetKey[B] && p.Value == gcpp.PartitionGetKey[X] select p.Key; gcpp.PartOrder.Remove(query1.FirstOrDefault()); var query2 = from p in gcpp.PartOrder where p.Key == gcpp.PartitionGetKey[X] && p.Value == gcpp.PartitionGetKey[B] select p.Key; gcpp.PartOrder.Remove(query2.FirstOrDefault()); } foreach (List<MDPState> B1 in gcpp.partition.Values) { if (SamePartOrder(B, X, gcpp.PartOrder, gcpp.PartitionGetKey)) { gcpp.PartOrder.Add(gcpp.PartitionGetKey[B1], gcpp.PartitionGetKey[X]); } if (SamePartOrder(X, B, gcpp.PartOrder, gcpp.PartitionGetKey)) { gcpp.PartOrder.Add(gcpp.PartitionGetKey[X], gcpp.PartitionGetKey[B1]); } } } } } return toReturn; }
public void AddState(MDPState state) { States.Add(state.ID, state); }
public void AddTargetStates(MDPState target) { TargetStates.Add(target); //target.Distributions.Clear(); target.ReachTarget = true; target.CurrentProb = 1; }
public MDP(MDPState init, int precision, double maxdiffer) { Precision = precision; MAX_DIFFERENCE = maxdiffer; States = new Dictionary<string, MDPState>(Ultility.Ultility.MC_INITIAL_SIZE); InitState = init; States.Add(init.ID, InitState); TargetStates = new List<MDPState>(); }
protected MDP BuildMDP_SCC_Cut_Mutlicores() { Stack<KeyValuePair<MDPConfiguration, MDPState>> working = new Stack<KeyValuePair<MDPConfiguration, MDPState>>(1024); string initID = InitialStep.GetID(); MDPState init = new MDPState(initID); working.Push(new KeyValuePair<MDPConfiguration, MDPState>(InitialStep as MDPConfiguration, init)); MDP mdp = new MDP(init, Ultility.Ultility.DEFAULT_PRECISION, Ultility.Ultility.MAX_DIFFERENCE); Stack<MDPState> stepStack = new Stack<MDPState>(1024); //MDPState2DRAStateMapping = new Dictionary<string, int>(Common.Classes.Ultility.Ultility.MC_INITIAL_SIZE); const int VISITED_NOPREORDER = -1; const int SCC_FOUND = -2; const int SCCBound = 20; //DFS data, which mapping each state to an int[] of size 3, first is the pre-order, second is the lowlink, last one is DRAState Dictionary<string, int[]> DFSData = new Dictionary<string, int[]>(Ultility.Ultility.MC_INITIAL_SIZE); DFSData.Add(initID, new int[] { VISITED_NOPREORDER, 0 }); //build the MDP while identifying the SCCs List<List<MDPState>> SCCs = new List<List<MDPState>>(64); Dictionary<int, List<MDPState>> scc2out = new Dictionary<int, List<MDPState>>(); Dictionary<int, HashSet<MDPState>> scc2input = new Dictionary<int, HashSet<MDPState>>(); //Dictionary<string, int> preorder = new Dictionary<string, int>(Common.Classes.Ultility.Ultility.MC_INITIAL_SIZE); //Dictionary<string, int> lowlink = new Dictionary<string, int>(Common.Classes.Ultility.Ultility.MC_INITIAL_SIZE); int preordercounter = 0; Dictionary<string, List<MDPConfiguration>> ExpendedNode = new Dictionary<string, List<MDPConfiguration>>(); bool reachTarget = true; do { if (CancelRequested) { this.VerificationOutput.NoOfStates = this.VerificationOutput.NoOfStates + mdp.States.Count; return mdp; } KeyValuePair<MDPConfiguration, MDPState> pair = working.Peek(); MDPConfiguration evt = pair.Key; //int DRAState = pair.Key.state; string currentID = pair.Key.GetID(); MDPState currentState = pair.Value; List<Distribution> outgoing = currentState.Distributions; //if (!preorder.ContainsKey(currentID)) //{ // preorder.Add(currentID, preorderCounter); // preorderCounter++; //} int[] nodeData = DFSData[currentID]; if (nodeData[0] == VISITED_NOPREORDER) { nodeData[0] = preordercounter; preordercounter++; } bool done = true; if (ExpendedNode.ContainsKey(currentID)) { if (reachTarget) { currentState.ReachTarget = reachTarget; } else { reachTarget = currentState.ReachTarget; } List<MDPConfiguration> list = ExpendedNode[currentID]; if (list.Count > 0) { for (int k = list.Count - 1; k >= 0; k--) { MDPConfiguration step = list[k]; string stepID = step.GetID(); //if (!preorder.ContainsKey(stepID)) if (DFSData[stepID][0] == VISITED_NOPREORDER) { if (done) { working.Push(new KeyValuePair<MDPConfiguration, MDPState>(step, mdp.States[stepID])); done = false; list.RemoveAt(k); } } else { MDPState s = mdp.States[stepID]; if (s.ReachTarget) { reachTarget = true; currentState.ReachTarget = reachTarget; if (s.SCCIndex >= 0) { scc2input[s.SCCIndex].Add(s); } } list.RemoveAt(k); } } } } else { reachTarget = false; int currentDistriIndex = -1; Distribution newDis = new Distribution(Constants.TAU); //MDPConfiguration[] steps = evt.MakeOneMoveLocal(); IEnumerable<MDPConfiguration> steps = evt.MakeOneMoveLocal(); //NOTE: here we play a trick for deadlock case: if a deadlock exist in the MDP, we will make a //self loop transition to remove the deadlock. Deadlock is meaningless in MDP. if (evt.IsDeadLock) { //List<MDPConfiguration> stepsList = new List<MDPConfiguration>(steps); working.Pop(); nodeData[0] = SCC_FOUND; continue; //stepsList.Add(CreateSelfLoopStep(evt)); //steps = stepsList.ToArray(); //HasDeadLock = true; } List<MDPConfiguration> stepsList = new List<MDPConfiguration>(steps); //List<PCSPEventDRAPair> product = Next(steps, DRAState); this.VerificationOutput.Transitions += stepsList.Count; for (int k = stepsList.Count - 1; k >= 0; k--) { MDPConfiguration step = stepsList[k]; string tmp = step.GetID(); bool target = false; ExpressionValue v = EvaluatorDenotational.Evaluate(ReachableStateCondition, step.GlobalEnv); MDPState nextState; if ((v as BoolConstant).Value) { target = true; if (!DFSData.Keys.Contains(tmp)) { DFSData.Add(tmp, new int[] { SCC_FOUND, SCC_FOUND }); // nextState = new MDPState(tmp); // mdp.States.Add(tmp, nextState); //preordercounter++; } //else if(DFSData[tmp][0] == VISITED_NOPREORDER) //{ // DFSData[tmp][0] = preordercounter; // preordercounter++; //} } //int nextIndex = VisitedWithID.Count; int[] data; if (mdp.States.TryGetValue(tmp, out nextState)) { DFSData.TryGetValue(tmp, out data); if (!target && data[0] == VISITED_NOPREORDER) { //if (mdp.States.TryGetValue(tmp, out nextState)) //{ // if (!preorder.ContainsKey(tmp)) // { if (done) { working.Push(new KeyValuePair<MDPConfiguration, MDPState>(step, nextState)); done = false; stepsList.RemoveAt(k); } else { stepsList[k] = step; } } else { stepsList.RemoveAt(k); MDPState s = mdp.States[tmp]; if (s.ReachTarget) { reachTarget = true; currentState.ReachTarget = reachTarget; if (s.SCCIndex >= 0) { scc2input[s.SCCIndex].Add(s); } } } } else { if (!target) { DFSData.Add(tmp, new int[] { VISITED_NOPREORDER, 0 }); } nextState = new MDPState(tmp); mdp.States.Add(tmp, nextState); if (done) { if (target) { mdp.AddTargetStates(nextState); reachTarget = true; } else { working.Push(new KeyValuePair<MDPConfiguration, MDPState>(step, nextState)); } done = false; stepsList.RemoveAt(k); } else { if (target) { stepsList.RemoveAt(k); mdp.AddTargetStates(nextState); reachTarget = true; } else { stepsList[k] = step; } } } MDPConfiguration pstep = step; if (pstep.DisIndex == -1) { if (currentDistriIndex >= 0) { //currentState.AddDistribution(newDis); //note here no pre is stored currentState.Distributions.Add(newDis); newDis = new Distribution(Constants.TAU); } Distribution newTrivialDis = new Distribution(pstep.Event, nextState); //currentState.AddDistribution(newTrivialDis); currentState.Distributions.Add(newTrivialDis); } else if (currentDistriIndex != -1 && pstep.DisIndex != currentDistriIndex) { //currentState.AddDistribution(newDis); currentState.Distributions.Add(newDis); newDis = new Distribution(Constants.TAU); newDis.AddProbStatePair(pstep.Probability, nextState); } else { newDis.AddProbStatePair(pstep.Probability, nextState); } currentDistriIndex = pstep.DisIndex; } if (currentDistriIndex >= 0) { //currentState.AddDistribution(newDis); currentState.Distributions.Add(newDis); } ExpendedNode.Add(currentID, stepsList); } if (done) { int lowlinkV = nodeData[0]; int preorderV = lowlinkV; bool selfLoop = false; foreach (Distribution list in outgoing) { foreach (KeyValuePair<double, MDPState> state in list.States) { string w = state.Value.ID; if (w == currentID) { selfLoop = true; } //if (!MDPState2DRAStateMapping.ContainsKey(w)) //{ // if (preorder[w] > preorderV) // { // lowlinkV = Math.Min(lowlinkV, lowlink[w]); // } // else // { // lowlinkV = Math.Min(lowlinkV, preorder[w]); // } //} int[] wdata = DFSData[w]; if (wdata[0] != SCC_FOUND) { if (wdata[0] > preorderV) { lowlinkV = Math.Min(lowlinkV, wdata[1]); } else { lowlinkV = Math.Min(lowlinkV, wdata[0]); } } } } nodeData[1] = lowlinkV; working.Pop(); if (lowlinkV == preorderV) { if (currentState.ReachTarget) { List<MDPState> SCC = new List<MDPState>(); //List<HashSet<MDPState>> Groupings = new List<HashSet<MDPState>>(); HashSet<MDPState> Grouping = new HashSet<MDPState>(); //bool reduceScc = false; Grouping.Add(currentState); SCC.Add(currentState); //int count = 1; //dtmcSCCstates.Add(currentID); nodeData[0] = SCC_FOUND; while (stepStack.Count > 0 && DFSData[stepStack.Peek().ID][0] > preorderV) { MDPState s = stepStack.Pop(); s.ReachTarget = true; string sID = s.ID; //Grouping.Add(s); SCC.Add(s); //dtmcSCCstates.Add(sID); DFSData[sID][0] = SCC_FOUND; //count++; } if (SCC.Count > 1 || selfLoop) { SCCs.Add(SCC); HashSet<MDPState> inputs = new HashSet<MDPState>(); inputs.Add(currentState); int Count = SCCs.Count; foreach (var state in SCC) { state.SCCIndex = Count - 1; } scc2input.Add(currentState.SCCIndex, inputs); HashSet<MDPState> outputs = new HashSet<MDPState>(); //input.Add(currentState); foreach (MDPState state in SCC) { foreach (var distr in state.Distributions) { foreach (var KVpair in distr.States) { if (!SCC.Contains(KVpair.Value)) { outputs.Add(KVpair.Value); } } } } List<MDPState> outofscc = new List<MDPState>(outputs); scc2out.Add(SCCs.IndexOf(SCC), outofscc); } //} } else { //dtmcSCCstates.Add(currentID); nodeData[0] = SCC_FOUND; while (stepStack.Count > 0 && DFSData[stepStack.Peek().ID][0] > preorderV) { string sID = stepStack.Pop().ID; DFSData[sID][0] = SCC_FOUND; } } } else { stepStack.Push(pair.Value); } } } while (working.Count > 0); //List<string> EndComponents = new List<string>(SCCs.Count); //foreach (List<MDPState> scc in SCCs) var localMapSCCsWithOutputSmallSCC = new Dictionary<List<MDPState>, List<MDPState>>(); while (SCCs.Count > 0) { for (int i = SCCs.Count - 1; i >= 0; i--) { List<MDPState> SCC = SCCs[i]; int index; //foreach(var state in SCC) //{ // index = state.SCCIndex; // break; //} //FindMECDistribution(SCC); if (SCC.Count <= SCCBound) { // SCCReductionGaussianSparseMatrix(new List<MDPState>(SCC), scc2out[index]); localMapSCCsWithOutputSmallSCC.Add(new List<MDPState>(SCC), scc2out[i]); SCCs.RemoveAt(i); } else { List<MDPState> SCCi = new List<MDPState>(SCCs[i]); int Counter = 0; var localMapSCCsWithOutputSubCutSCC = new Dictionary<List<MDPState>, List<MDPState>>(); while (Counter < SCCi.Count - SCCBound) { List<MDPState> group = SCCi.GetRange(Counter, SCCBound); HashSet<MDPState> outputs = new HashSet<MDPState>(); //input.Add(currentState); foreach (MDPState state in group) { foreach (var Distr in state.Distributions) { foreach (KeyValuePair<double, MDPState> KVpair in Distr.States) { MDPState nextState = KVpair.Value; if (!group.Contains(nextState)) { outputs.Add(nextState); } } } } // List<MDPState> output = new List<MDPState>(outputs); //SCCReductionGaussianSparseMatrix(group, output); localMapSCCsWithOutputSubCutSCC.Add(group, new List<MDPState>(outputs)); //SCCReduction(group, output); Counter += SCCBound; } Parallel.ForEach(localMapSCCsWithOutputSubCutSCC, subscc2Out => SCCReductionGaussianSparseMatrix(subscc2Out.Key, subscc2Out.Value, true)); List<MDPState> Group = SCCi.GetRange(Counter, SCCi.Count - Counter); HashSet<MDPState> Outputs = new HashSet<MDPState>(); //input.Add(currentState); foreach (MDPState state in Group) { foreach (var Distr in state.Distributions) { foreach (var KVpair in Distr.States) { MDPState nextState = KVpair.Value; if (!Group.Contains(nextState)) { Outputs.Add(nextState); } } } } List<MDPState> Output = new List<MDPState>(Outputs); //GL: TODO: this one is not in parallel SCCReductionGaussianSparseMatrix(Group, Output, true); //search for the useful subset of SCC that connecting to input states after reduction. HashSet<MDPState> Working = scc2input[i]; HashSet<MDPState> visited = new HashSet<MDPState>(); do { HashSet<MDPState> newWorking = new HashSet<MDPState>(); foreach (var state in Working) { visited.Add(state); foreach (var distr in state.Distributions) { foreach (var tran in distr.States) { MDPState tranV = tran.Value; if (!visited.Contains(tranV) && SCCs[i].Contains(tranV)) { newWorking.Add(tranV); } } } } Working = newWorking; } while (Working.Count > 0); if (visited.Count > SCCBound && visited.Count < SCCs[i].Count) { SCCs[i] = new List<MDPState>(visited); } else { //List<MDPState> scc = new List<MDPState>(SCCs[i]); // SCCReductionGaussianSparseMatrix(scc, scc2out[index]); //SCCReductionMatlab(scc, scc2out[i]); localMapSCCsWithOutputSmallSCC.Add(new List<MDPState>(visited), scc2out[i]); SCCs.RemoveAt(i); } } } } Parallel.ForEach(localMapSCCsWithOutputSmallSCC, subscc2Out => SCCReductionGaussianSparseMatrix(subscc2Out.Key, subscc2Out.Value, true)); VerificationOutput.NoOfStates = VerificationOutput.NoOfStates + mdp.States.Count; int counter = 0; BuildPRE(mdp, ref counter); return mdp; }
protected MDP BuildMDP_SCC_Cut() { Stack<KeyValuePair<MDPConfiguration, MDPState>> working = new Stack<KeyValuePair<MDPConfiguration, MDPState>>(1024); string initID = InitialStep.GetID(); MDPState init = new MDPState(initID); working.Push(new KeyValuePair<MDPConfiguration, MDPState>(InitialStep as MDPConfiguration, init)); MDP mdp = new MDP(init, Ultility.Ultility.DEFAULT_PRECISION, Ultility.Ultility.MAX_DIFFERENCE); Stack<MDPState> stepStack = new Stack<MDPState>(1024); //MDPState2DRAStateMapping = new Dictionary<string, int>(Common.Classes.Ultility.Ultility.MC_INITIAL_SIZE); const int VISITED_NOPREORDER = -1; const int SCC_FOUND = -2; //DFS data, which mapping each state to an int[] of size 3, first is the pre-order, second is the lowlink, last one is DRAState Dictionary<string, int[]> DFSData = new Dictionary<string, int[]>(Ultility.Ultility.MC_INITIAL_SIZE); DFSData.Add(initID, new int[] { VISITED_NOPREORDER, 0 }); //build the MDP while identifying the SCCs List<HashSet<MDPState>> SCCs = new List<HashSet<MDPState>>(); //Dictionary<int, List<MDPState>> scc2out = new Dictionary<int, List<MDPState>>(); List<HashSet<MDPState>> scc2out = new List<HashSet<MDPState>>(); List<HashSet<MDPState>> scc2input = new List<HashSet<MDPState>>(); //Dictionary<int, HashSet<MDPState>> scc2input = new Dictionary<int, HashSet<MDPState>>(); //Dictionary<string, int> preorder = new Dictionary<string, int>(Common.Classes.Ultility.Ultility.MC_INITIAL_SIZE); //Dictionary<string, int> lowlink = new Dictionary<string, int>(Common.Classes.Ultility.Ultility.MC_INITIAL_SIZE); int preordercounter = 0; Dictionary<string, List<MDPConfiguration>> ExpendedNode = new Dictionary<string, List<MDPConfiguration>>(); bool reachTarget = true; do { if (CancelRequested) { this.VerificationOutput.NoOfStates = this.VerificationOutput.NoOfStates + mdp.States.Count; return mdp; } KeyValuePair<MDPConfiguration, MDPState> pair = working.Peek(); MDPConfiguration evt = pair.Key; //int DRAState = pair.Key.state; string currentID = pair.Key.GetID(); MDPState currentState = pair.Value; List<Distribution> outgoing = currentState.Distributions; //if (!preorder.ContainsKey(currentID)) //{ // preorder.Add(currentID, preorderCounter); // preorderCounter++; //} int[] nodeData = DFSData[currentID]; if (nodeData[0] == VISITED_NOPREORDER) { nodeData[0] = preordercounter; preordercounter++; } bool done = true; if (ExpendedNode.ContainsKey(currentID)) { if (reachTarget) { currentState.ReachTarget = reachTarget; } else { reachTarget = currentState.ReachTarget; } List<MDPConfiguration> list = ExpendedNode[currentID]; if (list.Count > 0) { for (int k = list.Count - 1; k >= 0; k--) { MDPConfiguration step = list[k]; string stepID = step.GetID(); //if (!preorder.ContainsKey(stepID)) if (DFSData[stepID][0] == VISITED_NOPREORDER) { if (done) { working.Push(new KeyValuePair<MDPConfiguration, MDPState>(step, mdp.States[stepID])); done = false; list.RemoveAt(k); } } else { MDPState s = mdp.States[stepID]; if (s.ReachTarget) { reachTarget = true; currentState.ReachTarget = reachTarget; if (s.SCCIndex >= 0) { scc2input[s.SCCIndex].Add(s); } } list.RemoveAt(k); } } } } else { reachTarget = false; int currentDistriIndex = -1; Distribution newDis = new Distribution(Constants.TAU); //MDPConfiguration[] steps = evt.MakeOneMoveLocal(); IEnumerable<MDPConfiguration> steps = evt.MakeOneMoveLocal(); //NOTE: here we play a trick for deadlock case: if a deadlock exist in the MDP, we will make a //self loop transition to remove the deadlock. Deadlock is meaningless in MDP. if (evt.IsDeadLock) { //List<MDPConfiguration> stepsList = new List<MDPConfiguration>(steps); working.Pop(); nodeData[0] = SCC_FOUND; continue; //stepsList.Add(CreateSelfLoopStep(evt)); //steps = stepsList.ToArray(); //HasDeadLock = true; } List<MDPConfiguration> stepsList = new List<MDPConfiguration>(steps); //List<PCSPEventDRAPair> product = Next(steps, DRAState); this.VerificationOutput.Transitions += stepsList.Count; for (int k = stepsList.Count - 1; k >= 0; k--) { MDPConfiguration step = stepsList[k]; string tmp = step.GetID(); bool target = false; ExpressionValue v = EvaluatorDenotational.Evaluate(ReachableStateCondition, step.GlobalEnv); MDPState nextState; if ((v as BoolConstant).Value) { target = true; if (!DFSData.Keys.Contains(tmp)) { DFSData.Add(tmp, new int[] { SCC_FOUND, SCC_FOUND }); // nextState = new MDPState(tmp); // mdp.States.Add(tmp, nextState); //preordercounter++; } //else if(DFSData[tmp][0] == VISITED_NOPREORDER) //{ // DFSData[tmp][0] = preordercounter; // preordercounter++; //} } //int nextIndex = VisitedWithID.Count; int[] data; if (mdp.States.TryGetValue(tmp, out nextState)) { nextState.TrivialPre = false; DFSData.TryGetValue(tmp, out data); if (!target && data[0] == VISITED_NOPREORDER) { //if (mdp.States.TryGetValue(tmp, out nextState)) //{ // if (!preorder.ContainsKey(tmp)) // { if (done) { working.Push(new KeyValuePair<MDPConfiguration, MDPState>(step, nextState)); done = false; stepsList.RemoveAt(k); } else { stepsList[k] = step; } } else { stepsList.RemoveAt(k); MDPState s = mdp.States[tmp]; if (s.ReachTarget) { reachTarget = true; currentState.ReachTarget = reachTarget; if (s.SCCIndex >= 0 && !scc2input[s.SCCIndex].Contains(s)) { scc2input[s.SCCIndex].Add(s); } } } } else { if (!target) { DFSData.Add(tmp, new int[] { VISITED_NOPREORDER, 0 }); } nextState = new MDPState(tmp); mdp.States.Add(tmp, nextState); if (done) { if (target) { mdp.AddTargetStates(nextState); reachTarget = true; } else { working.Push(new KeyValuePair<MDPConfiguration, MDPState>(step, nextState)); } done = false; stepsList.RemoveAt(k); } else { if (target) { stepsList.RemoveAt(k); mdp.AddTargetStates(nextState); reachTarget = true; } else { stepsList[k] = step; } } } MDPConfiguration pstep = step; if (pstep.DisIndex == -1) { if (currentDistriIndex >= 0) { //note here no pre is stored currentState.Distributions.Add(newDis); newDis = new Distribution(Constants.TAU); } if (nextState.ID != currentID)//note here self loop distribution is removed; so just used for PMAX { Distribution newTrivialDis = new Distribution(pstep.Event, nextState); currentState.Distributions.Add(newTrivialDis); } } else if (currentDistriIndex != -1 && pstep.DisIndex != currentDistriIndex) { //note here no pre is stored currentState.Distributions.Add(newDis); newDis = new Distribution(Constants.TAU); newDis.AddProbStatePair(pstep.Probability, nextState); nextState.TrivialPre = false; } else { newDis.AddProbStatePair(pstep.Probability, nextState); nextState.TrivialPre = false; } currentDistriIndex = pstep.DisIndex; } if (currentDistriIndex >= 0) { currentState.Distributions.Add(newDis); } ExpendedNode.Add(currentID, stepsList); } if (done) { int lowlinkV = nodeData[0]; int preorderV = lowlinkV; bool selfLoop = false; foreach (Distribution list in outgoing) { foreach (KeyValuePair<double, MDPState> state in list.States) { string w = state.Value.ID; if (w == currentID) { selfLoop = true; } int[] wdata = DFSData[w]; if (wdata[0] != SCC_FOUND) { if (wdata[0] > preorderV) { lowlinkV = Math.Min(lowlinkV, wdata[1]); } else { lowlinkV = Math.Min(lowlinkV, wdata[0]); } } } } nodeData[1] = lowlinkV; working.Pop(); if (lowlinkV == preorderV) { if (currentState.ReachTarget) { HashSet<MDPState> SCC = new HashSet<MDPState>(); //List<HashSet<MDPState>> Groupings = new List<HashSet<MDPState>>(); //HashSet<MDPState> Grouping = new HashSet<MDPState>(); //bool reduceScc = false; //Grouping.Add(currentState); SCC.Add(currentState); //int count = 1; //dtmcSCCstates.Add(currentID); nodeData[0] = SCC_FOUND; while (stepStack.Count > 0 && DFSData[stepStack.Peek().ID][0] > preorderV) { MDPState s = stepStack.Pop(); s.ReachTarget = true; string sID = s.ID; //Grouping.Add(s); SCC.Add(s); //dtmcSCCstates.Add(sID); DFSData[sID][0] = SCC_FOUND; //count++; } if (SCC.Count > 1 || selfLoop) { SCCs.Add(SCC); HashSet<MDPState> inputs = new HashSet<MDPState>(); inputs.Add(currentState); int Count = SCCs.Count; foreach (MDPState state in SCC) { state.SCCIndex = Count - 1; } scc2input.Add(inputs); HashSet<MDPState> outputs = new HashSet<MDPState>(); //input.Add(currentState); foreach (MDPState state in SCC) { foreach (Distribution distr in state.Distributions) { foreach (KeyValuePair<double, MDPState> KVpair in distr.States) { if (!SCC.Contains(KVpair.Value)) { outputs.Add(KVpair.Value); } } } } //List<MDPState> outofscc = new List<MDPState>(outputs); scc2out.Add(outputs); } //} } else { //dtmcSCCstates.Add(currentID); nodeData[0] = SCC_FOUND; while (stepStack.Count > 0 && DFSData[stepStack.Peek().ID][0] > preorderV) { string sID = stepStack.Pop().ID; DFSData[sID][0] = SCC_FOUND; } } } else { stepStack.Push(pair.Value); } } } while (working.Count > 0); RemoveOneTran(SCCs, scc2input); for (int i = 0; i < SCCs.Count; i++) { FindMECDistribution(SCCs[i]); } if(BFS_CUT) { BFS_Cut(SCCs, scc2out, scc2input); } else { //DFS_CutAutoAdjustTreeLike(SCCs, scc2out, scc2input); DFS_CutAutoAdjust(SCCs, scc2out, scc2input); //DFS_Cut(SCCs, scc2out, scc2input); } VerificationOutput.NoOfStates = VerificationOutput.NoOfStates + mdp.States.Count; int counter = 0; BuildPRE(mdp, ref counter); return mdp; }
public Distribution calcGroupedDistr(List<HashSet<MDPState>> ListHashMDP, Distribution Distr, MDPState Initial, MDPState Target, MDPState Safe, MDP mdp) { Distribution toReturn = new Distribution(Distr.Event); double toInit = 0; double toTarget = 0; double[] combined = new double[ListHashMDP.Count]; //MDPState[] groupstates = new MDPState[seperation.Count]; foreach (KeyValuePair<double, MDPState> transition in Distr.States) { if (TargetStates.Contains(transition.Value)) { toTarget += transition.Key; } else if (InitState == transition.Value) { toInit += transition.Key; } else { for (int i = 0; i < ListHashMDP.Count; i++) { if (ListHashMDP[i].Contains(transition.Value)) { combined[i] += transition.Key; break; } } } } double toSafe = 1 - toTarget - toInit; for (int i = 0; i < ListHashMDP.Count; i++) { toSafe -= combined[i]; } if (toInit != 0) { toReturn.AddProbStatePair(Math.Round(toInit, 5), Initial); } if (toTarget != 0) { toReturn.AddProbStatePair(Math.Round(toTarget, 5), Target); } if (toSafe != 0) { toReturn.AddProbStatePair(Math.Round(toSafe, 5), Safe); } //toReturn.AddProbStatePair(toSafe, Safe); for (int j = 0; j < ListHashMDP.Count; j++) { if (combined[j] != 0) { MDPState state = mdp.States[StateFromHashset(ListHashMDP[j]).ID]; toReturn.AddProbStatePair(Math.Round(combined[j], 5), state); //toReturn.AddProbStatePair(Math.Round(combined[j], 5), StateFromHashset(ListHashMDP[j])); } } return toReturn; }
public MDP BuildQuotientMDP(VerificationOutput VerificationOutput) { //return this; MDP toReturn = new MDP(Precision, MAX_DIFFERENCE); //todo change to set List<KeyValuePair<string, string>> BoundaryOneTransition = new List<KeyValuePair<string, string>>(); //todo change to set List<Distribution> ProbTransitions = new List<Distribution>(); Dictionary<string, List<Distribution>> GlobalProbTransitions = new Dictionary<string, List<Distribution>>(); StringDictionary<bool> visited = new StringDictionary<bool>(States.Count); List<KeyValuePair<HashSet<string>, MDPState>> sccs = new List<KeyValuePair<HashSet<string>, MDPState>>(); Dictionary<string, int> preorder = new Dictionary<string, int>(); Dictionary<string, int> lowlink = new Dictionary<string, int>(); //HashSet<string> scc_found = new HashSet<string>(); Stack<MDPState> TaskStack = new Stack<MDPState>(); //Dictionary<string, List<string>> OutgoingTransitionTable = new Dictionary<string, List<string>>(); Stack<MDPState> stepStack = new Stack<MDPState>(1024); visited.Add(InitState.ID, false); TaskStack.Push(InitState); //# Preorder counter int preor = 0; do { while (TaskStack.Count > 0) { MDPState pair = TaskStack.Peek(); string v = pair.ID; if (visited.GetContainsKey(v) && visited.GetContainsKey(v)) { TaskStack.Pop(); continue; } if (!preorder.ContainsKey(v)) { preorder.Add(v, preor); preor++; } bool done = true; List<Distribution> list = pair.Distributions; List<MDPState> nonProbTrans = new List<MDPState>(); List<Distribution> ProbTrans = new List<Distribution>(); for (int i = 0; i < list.Count; i++) { if (list[i].IsTrivial()) { nonProbTrans.Add(list[i].States[0].Value); } else { ProbTrans.Add(list[i]); } } if (ProbTrans.Count > 0 && !GlobalProbTransitions.ContainsKey(v)) { GlobalProbTransitions.Add(v, ProbTrans); ProbTransitions.AddRange(ProbTrans); } for (int k = nonProbTrans.Count - 1; k >= 0; k--) { MDPState step = nonProbTrans[k]; string tmp = step.ID; if (visited.ContainsKey(tmp)) { //if this node is still not visited if (!preorder.ContainsKey(tmp)) { //only put the first one to the work list stack. //if there are more than one node to be visited, //simply ignore them and keep its event step in the list. if (done) { TaskStack.Push(step); done = false; } } } else { visited.Add(tmp, false); //OutgoingTransitionTable.Add(tmp, new List<string>(8)); //only put the first one into the stack. if (done) { TaskStack.Push(step); done = false; } } } if (done) { int lowlinkV = preorder[v]; int preorderV = preorder[v]; bool selfLoop = false; for (int j = 0; j < nonProbTrans.Count; j++) { string w = nonProbTrans[j].ID; if (w == v) { selfLoop = true; } if (!visited.GetContainsKey(w)) { if (preorder[w] > preorderV) { lowlinkV = Math.Min(lowlinkV, lowlink[w]); } else { lowlinkV = Math.Min(lowlinkV, preorder[w]); } } else //in this case, there is a tau transition leading to an SCC; must add the transition into the toReturn automaton { BoundaryOneTransition.Add(new KeyValuePair<string, string>(v, w)); } } lowlink[v] = lowlinkV; TaskStack.Pop(); HashSet<string> scc = new HashSet<string>(); if (lowlinkV == preorderV) { scc.Add(v); visited.SetValue(v, true); while (stepStack.Count > 0 && preorder[stepStack.Peek().ID] > preorderV) { string s = stepStack.Pop().ID; scc.Add(s); visited.SetValue(s, true); } MDPState newstate = new MDPState(toReturn.States.Count.ToString()); if (scc.Count > 1 || (scc.Count == 1 && selfLoop)) { newstate.AddDistribution(new Distribution(Constants.TAU, newstate)); //add self loop: sun jun } sccs.Add(new KeyValuePair<HashSet<string>, MDPState>(scc, newstate)); toReturn.AddState(newstate); if (scc.Contains(InitState.ID)) { toReturn.SetInit(newstate); } foreach (MDPState state in TargetStates) { if (scc.Contains(state.ID)) { toReturn.AddTargetStates(newstate); } } } else { stepStack.Push(pair); } } } if (ProbTransitions.Count > 0) { foreach (Distribution step in ProbTransitions) { foreach (KeyValuePair<double, MDPState> pair in step.States) { string stateID = pair.Value.ID; if (!visited.ContainsKey(stateID)) { TaskStack.Push(pair.Value); visited.Add(stateID, false); } } } ProbTransitions.Clear(); } } while (TaskStack.Count > 0); foreach (KeyValuePair<string, string> pair in BoundaryOneTransition) { MDPState source = null; MDPState target = null; foreach (KeyValuePair<HashSet<string>, MDPState> sccstate in sccs) { if (sccstate.Key.Contains(pair.Key)) { source = sccstate.Value; } if (sccstate.Key.Contains(pair.Value)) { target = sccstate.Value; } } toReturn.AddDistribution(source.ID, new Distribution(Constants.TAU, target)); VerificationOutput.ReducedMDPTransitions++; } foreach (KeyValuePair<string, List<Distribution>> pair in GlobalProbTransitions) { MDPState source = null; foreach (KeyValuePair<HashSet<string>, MDPState> sccstate in sccs) { if (sccstate.Key.Contains(pair.Key)) { source = sccstate.Value; break; } } foreach (Distribution distribution in pair.Value) { Distribution disNew = new Distribution(distribution.Event); foreach (KeyValuePair<double, MDPState> state in distribution.States) { foreach (KeyValuePair<HashSet<string>, MDPState> sccstate in sccs) { if (sccstate.Key.Contains(state.Value.ID)) { disNew.AddProbStatePair(state.Key, sccstate.Value); VerificationOutput.ReducedMDPTransitions++; break; } } } toReturn.AddDistribution(source.ID, disNew); } } VerificationOutput.ReducedMDPStates = toReturn.States.Count; return toReturn; }
public bool CanSim(GCPP GCPPobj, MDPState state1, MDPState state2) { if (!PropositionEquals(state1, state2)) { return false; } //else if () //{ //} return true; }
public bool PropositionEquals(MDPState state1, MDPState state2) { return true; }
//This method calculate the probability through each distribution; self-loop structure is removed to reduce iterations public double DistributionProbCalc(MDPState node, Distribution distr) { double result = 0; //bool hasNewValues = false; //check the self loop probability; If selfloop exists, e.g. s->s with 0.5, s->t with 0.5, can be transferred to //s->t with 1; this could reduce the iterations in some cases. //bool hasSelfLoop = false; //record the self-loop probability. //record the remaining transition probability double nonSelfLoopProb = 0.0; for (int i = 0; i < distr.States.Count; i++) { KeyValuePair<double, MDPState> pair = distr.States[i]; if (pair.Value == node) { //selfLoopProb += pair.Key; //hasSelfLoop = true; //the self loop is removed in this distribution distr.States.Remove(pair); //i-- is used to keep the loop correct after removing one element i--; } else { nonSelfLoopProb += pair.Key; } } if (distr.States.Count == 0) { result = node.CurrentProb; } else { foreach (KeyValuePair<double, MDPState> pair in distr.States) { //re-calculate the transition probability after removing self-loop(including the case that no self loop is removed; then nonSelfLoopProb=1) result += pair.Value.CurrentProb * (pair.Key / nonSelfLoopProb); } } return result; }
protected List<HashSet<MDPState>> TarjanSCC(MDPState initialState, HashSet<MDPState> OUTPUTS, HashSet<MDPState> visited, List<HashSet<MDPState>> scc2out, List<HashSet<MDPState>> scc2input) { const int VISITED_NOPREORDER = -1; const int SCC_FOUND = -2; int preordercounter = 0; Dictionary<string, List<MDPState>> ExpendedNode = new Dictionary<string, List<MDPState>>(); Stack<MDPState> working = new Stack<MDPState>(); working.Push(initialState); initialState.SCCIndex = -1; Stack<MDPState> stepStack = new Stack<MDPState>(1024); Dictionary<string, int[]> DFSData = new Dictionary<string, int[]>(Ultility.Ultility.MC_INITIAL_SIZE); DFSData.Add(initialState.ID, new int[] { VISITED_NOPREORDER, 0 }); HashSet<MDPState> newVisited = new HashSet<MDPState>(); newVisited.Add(initialState); List<HashSet<MDPState>> SCCs = new List<HashSet<MDPState>>(); do { MDPState currentState = working.Peek(); string currentID = currentState.ID; List<Distribution> outgoing = currentState.Distributions; int[] nodeData = DFSData[currentID]; if (nodeData[0] == VISITED_NOPREORDER) { nodeData[0] = preordercounter; preordercounter++; } bool done = true; if (ExpendedNode.ContainsKey(currentID)) { List<MDPState> list = ExpendedNode[currentID]; if (list.Count > 0) { for (int k = list.Count - 1; k >= 0; k--) { MDPState step = list[k]; if (OUTPUTS.Contains(step)) continue; string stepID = step.ID; //if (!preorder.ContainsKey(stepID)) if (DFSData[stepID][0] == VISITED_NOPREORDER) { if (done) { working.Push(step); done = false; list.RemoveAt(k); } } else { if (step.SCCIndex >= 0) { scc2input[step.SCCIndex].Add(step); } list.RemoveAt(k); } } } } else { List<MDPState> stepsList = new List<MDPState>(); foreach (Distribution distr in currentState.Distributions) { foreach (KeyValuePair<double, MDPState> kvPair in distr.States) { stepsList.Add(kvPair.Value); } } for (int k = stepsList.Count - 1; k >= 0; k--) { MDPState nextState = stepsList[k]; //string tmp = step.ID; if (OUTPUTS.Contains(nextState)) continue; int[] data; if (newVisited.Contains(nextState)) { DFSData.TryGetValue(nextState.ID, out data); if (data[0] == VISITED_NOPREORDER) { if (done) { working.Push(nextState); done = false; stepsList.RemoveAt(k); } else { stepsList[k] = nextState; } } else { if (nextState.SCCIndex >= 0) { scc2input[nextState.SCCIndex].Add(nextState); } stepsList.RemoveAt(k); } } else { DFSData.Add(nextState.ID, new int[] { VISITED_NOPREORDER, 0 }); newVisited.Add(nextState); nextState.SCCIndex = -1; if (done) { working.Push(nextState); done = false; stepsList.RemoveAt(k); } else { stepsList[k] = nextState; } } } ExpendedNode.Add(currentID, stepsList); } if (done) { int lowlinkV = nodeData[0]; int preorderV = lowlinkV; bool selfLoop = false; foreach (Distribution list in outgoing) { foreach (KeyValuePair<double, MDPState> state in list.States) { string w = state.Value.ID; if (OUTPUTS.Contains(state.Value)) continue; if (w == currentID) { selfLoop = true; } int[] wdata = DFSData[w]; if (wdata[0] != SCC_FOUND) { if (wdata[0] > preorderV) { lowlinkV = Math.Min(lowlinkV, wdata[1]); } else { lowlinkV = Math.Min(lowlinkV, wdata[0]); } } } } nodeData[1] = lowlinkV; working.Pop(); if (lowlinkV == preorderV) { HashSet<MDPState> scc = new HashSet<MDPState>(); scc.Add(currentState); nodeData[0] = SCC_FOUND; while (stepStack.Count > 0 && DFSData[stepStack.Peek().ID][0] > preorderV) { MDPState s = stepStack.Pop(); string sID = s.ID; scc.Add(s); DFSData[sID][0] = SCC_FOUND; } if (scc.Count > 1 || selfLoop) { SCCs.Add(scc); int Count = SCCs.Count; foreach (MDPState state in scc) { state.SCCIndex = Count - 1; } HashSet<MDPState> inputs = new HashSet<MDPState>(); inputs.Add(currentState); scc2input.Add(inputs); HashSet<MDPState> outputs = new HashSet<MDPState>(); //input.Add(currentState); foreach (MDPState state in scc) { foreach (Distribution distr in state.Distributions) { foreach (KeyValuePair<double, MDPState> KVpair in distr.States) { if (!scc.Contains(KVpair.Value)) { outputs.Add(KVpair.Value); } } } } //List<MDPState> outofscc = new List<MDPState>(outputs); scc2out.Add(outputs); } else { nodeData[0] = SCC_FOUND; while (stepStack.Count > 0 && DFSData[stepStack.Peek().ID][0] > preorderV) { string sID = stepStack.Pop().ID; DFSData[sID][0] = SCC_FOUND; } } } else { stepStack.Push(currentState); } } } while (working.Count > 0); visited.UnionWith(newVisited); return SCCs; }