/// <summary> /// // FORWARD PROCESSING: Calculate the minimum cumulative cost for each object in each world state /// </summary> /// <param name="objectsByWorldState">"Matrix" of objects by world state</param> private void calculateMinimumCumulativeCost(List <List <TrackedObject> > objectsByWorldState) { int iWorldState = 0; foreach (List <TrackedObject> objectsAtWorldState in objectsByWorldState) { // we start ecalculating costs from the second world stat if (iWorldState == 0) { iWorldState++; continue; } int iDestinyObject = 0; foreach (TrackedObject destinyObject in objectsAtWorldState) { //destinyObject.cost = minCost(objectsByWorldState[iWorldState - 1], iWorldState, iDestinyObject); ObjectAndCost minSourceObject = minCost(objectsByWorldState[iWorldState - 1], iWorldState, iDestinyObject); destinyObject.cost = minSourceObject.cost; // set the object as a "tentative" closest source. It may be used in the path of another object having // a total smaller path than this destinyObject.closestSource = minSourceObject.sourceObject; iDestinyObject++; } iWorldState++; } }
/// <summary> /// Return the dependent shortest path for each object (as a string) /// </summary> /// <param name="objectsByWorldState">"Matrix" of objects by worldstate</param> /// <returns>Paths (as string)</returns> public string getPaths(List <List <TrackedObject> > objectsByWorldState) { string output = ""; // sort the elments by ascending cost objectsByWorldState[objectsByWorldState.Count - 1].Sort(delegate(TrackedObject c1, TrackedObject c2) { return(c1.cost.CompareTo(c2.cost)); }); foreach (TrackedObject objectAtWorldState in objectsByWorldState[objectsByWorldState.Count - 1]) { int iWorldState = objectsByWorldState.Count; // temporary object to iterate through the linked list TrackedObject thisObject = objectAtWorldState; do { iWorldState--; output += "(" + thisObject.x + "," + thisObject.y + ") [" + thisObject.cost + "]"; // if there is no closest point from previous world state, then we have reached the end if (thisObject.closestSource == null) { break; } // make sure to not using source objects already used by other shorter paths if (thisObject.closestSource.taken) { // if so, find the next one that is closer ObjectAndCost closestSource = minCost(objectsByWorldState[iWorldState - 1], iWorldState, thisObject.ith); thisObject.closestSource = closestSource.sourceObject; // if there is no closest point from previous world state, then we have reached the end if (thisObject == null) { break; } } // now we move in our liked list, to the previous object (a.k.a. the closest one from previous world state) thisObject = thisObject.closestSource; if (thisObject != null) { // mark the object as taken, so it is used only once. thisObject.taken = true; output += " -> "; } } while (thisObject != null); output += Environment.NewLine; } return(output); }