private HexagonRemoveModel RemoveIterative(HexagonRemoveModel returnModel, long levelUpperBound) { int address = 10; // Entry point for each each "call" HexagonRemoveModel tempModel = returnModel; Stack stack = new Stack(); stack.Push(30); //initial return address stack.Push(tempModel); while (stack.Count > 0) { switch (address) { case 10: { // Do something returnModel = (HexagonRemoveModel)stack.Pop(); int id = returnModel.ID; ArrayList[] btg = returnModel.Btg; int[] next = returnModel.Next; int[] prev = returnModel.Prev; int[] level = returnModel.Level; int[] weight = returnModel.Weight; //check if the node has already been removed if (prev[id] == -1) { //go to next address address = (int)stack.Pop(); stack.Push(returnModel); break; } if (next[prev[id]] != id) { //go to next address address = (int)stack.Pop(); stack.Push(returnModel); break; } else { //remove the node from next/prev relation next[prev[id]] = next[id]; if (next[id] != -1) { prev[next[id]] = prev[id]; } //remove tuples in node btg[id] = null; } //remove followers // follow the edge for preference i (only if not already on last level) //if (id + weight[0] <= level.GetUpperBound(0) && level[id + weight[0]] == level[id] + 1) //TODO: Profiling separate long variable instead of GetUpperBound(0) --> No significant effect (14% from the function instead of 15%) if (id + weight[0] <= levelUpperBound && level[id + weight[0]] == level[id] + 1) { //Push current object to stack returnModel.Loopindex = 1; //important: raise loop Index!! new position in position loop!! returnModel.Next = next; returnModel.Prev = prev; returnModel.Btg = btg; stack.Push(returnModel); stack.Push(20); //Push new object to stack HexagonRemoveModel nMinus1 = new HexagonRemoveModel(id + weight[0], 0, btg, next, prev, level, weight, 0); stack.Push(nMinus1); address = 10; // Make another "call" break; } //Contains no childs --> goto next address //The base case address = (int)stack.Pop(); returnModel.Next = next; returnModel.Prev = prev; returnModel.Btg = btg; stack.Push(returnModel); break; } case 20: { // Compute and return tempModel = (HexagonRemoveModel)stack.Pop(); returnModel = (HexagonRemoveModel)stack.Pop(); //Read int id = returnModel.ID; int index = returnModel.Index; ArrayList[] btg = returnModel.Btg; int[] next = returnModel.Next; int[] prev = returnModel.Prev; int[] level = returnModel.Level; int[] weight = returnModel.Weight; int iLoopIndex = returnModel.Loopindex; bool isEndOfLoop = true; //remove followers for (int i = iLoopIndex; i <= index; i++) { // follow the edge for preference i (only if not already on last level) if (id + weight[i] <= level.GetUpperBound(0) && level[id + weight[i]] == level[id] + 1) { //Push current object to stack //important: raise loop Index!! new position in position loop!! --> The next time i will be initialized by this index returnModel.Loopindex = i + 1; stack.Push(returnModel); stack.Push(20); //Push new object to stack HexagonRemoveModel deeperNode = new HexagonRemoveModel(id + weight[i], i, btg, next, prev, level, weight, 0); stack.Push(deeperNode); address = 10; // Make another "call" isEndOfLoop = false; break; } } if (isEndOfLoop) { //Read next address and push current object to stack address = (int)stack.Pop(); stack.Push(returnModel); } break; } case 30: { // The final return value tempModel = (HexagonRemoveModel)stack.Pop(); break; } } } return tempModel; }
//Find BestMatchesOnly private void FindBmo(int amountPreferences, ref ArrayList[] btg, ref int[] next, ref int[] prev, ref int[] level, ref int[] weight) { int last = 0; long levelUpperBound = level.GetUpperBound(0); // special case: top node is not empty if (btg[0] != null) { //Top node contains a tuple --> This is the perfect tuple. Set next to -1, next[0] = -1; } else { //follow the breadth-first walk int cur = 1; //while (cur != -1) while (cur != -1 && next[cur] != -1) //<= btg.GetUpperBound(0) { if (btg[cur] != null) { // non-empty node belonging to BMO set int nextCur = next[cur]; last = cur; // remove all nodes dominated by current for (int i = 0; i < amountPreferences; i++) { // check if there is an edge for Pi if (cur + weight[i] <= level.GetUpperBound(0)) { if (level[cur + weight[i]] == level[cur] + 1) { HexagonRemoveModel modelIn = new HexagonRemoveModel(cur + weight[i], i, btg, next, prev, level, weight, 0); //removeRecursive(cur + weight[i], i, ref btg, ref next, ref prev, ref level, ref weight, 0); HexagonRemoveModel modelOut = RemoveIterative(modelIn, levelUpperBound); btg = modelOut.Btg; next = modelOut.Next; prev = modelOut.Prev; } } } cur = nextCur; } else { // node is empty: remove from next/prev int nextCur = next[cur]; next[last] = next[cur]; prev[next[cur]] = last; next[cur] = -1; //gibt es nicht mehr dieses node prev[cur] = -1; cur = nextCur; //Damit Breadt-First Walk } } } }