コード例 #1
0
        private void getpath(string[] pieces)
        {
            if (pieces.Length < 3)
            {
                return;
            }

            uint as1, as2;

            if (!uint.TryParse(pieces[1], out as1) || !uint.TryParse(pieces[2], out as2))
            {
                return;
            }

            if (g.GetNode(as1) == null || g.GetNode(as2) == null)
            {
                return;
            }

            Destination as2_dst = new Destination(SimulatorLibrary.initMiniDestinationSP(g, as2, false));

            bool[] dummyS = new bool[Constants._numASNs];
            as2_dst.UpdatePaths(dummyS);
            Console.WriteLine("shortest path:");
            Console.WriteLine(as2_dst.GetPath(as1, g));
            Console.WriteLine("regular path:");
            as2_dst = new Destination(SimulatorLibrary.initMiniDestination(g, as2, false));
            as2_dst.UpdatePaths(dummyS);
            Console.WriteLine(as2_dst.GetPath(as1));
        }
コード例 #2
0
        public static void trafficThroughSecureProviders(resultObject results)
        {
            //get what the simulation state would look like.
            GlobalState GS = SimulatorLibrary.initGlobalState(results.g, results.earlyAdopters, results.weightedNodes, short.Parse(results.k));

            /** First, get a list of multihomed stubs as destinations **/
            var stubs = results.g.getStubs();
            List <Destination> multihomedStubs = new List <Destination>();

            foreach (UInt32 stubNum in stubs)
            {
                AsNode stub = results.g.GetNode(stubNum);
                if (stub.GetNeighborsByType(RelationshipType.CustomerOf).ToArray().Length > 1)
                {
                    multihomedStubs.Add(new Destination(SimulatorLibrary.initMiniDestination(results.g, stub.NodeNum, true)));
                }
            }
            Console.WriteLine(multihomedStubs.Count + " stubs out of " + stubs.Count + " are multihomed.");

            /** Second, go through each iteration... **/
            int iteration = 0;

            foreach (bool[] S in results.state)
            {
                DateTime IterationStart = DateTime.Now;
                Int32    finishedDests  = 0;
                foreach (Destination multihomedStub in multihomedStubs)
                {
                    /** for this multhomed stub, see how much traffic
                     * goes through secure providers **/
                    multihomedStub.UpdatePaths(S);
                    multihomedStub.ComputeU(GS.W);

                    var   Providers       = results.g.GetNode(multihomedStub.destination).GetNeighborsByType(RelationshipType.CustomerOf);
                    Int64 TotalU          = 0;
                    Int64 SecureProviderU = 0;
                    Int32 TotalProviders  = Providers.Count();
                    Int32 SecureProviders = 0;
                    foreach (var Provider in Providers)
                    {
                        if (S[Provider.NodeNum])
                        {
                            SecureProviderU += multihomedStub.U[Provider.NodeNum];
                            SecureProviders++;
                        }
                        TotalU += multihomedStub.U[Provider.NodeNum];
                    }
                    //     Console.WriteLine(iteration + " :: " + multihomedStub.destination + " " + SecureProviders + " " + TotalProviders + " " + SecureProviderU + " " + TotalU);
                    finishedDests++;
                    if ((finishedDests % 1000) == 0)
                    {
                        Console.WriteLine("Finished " + finishedDests + " at " + DateTime.Now + " iteration started at " + IterationStart);
                    }
                }
                Console.WriteLine(DateTime.Now + " done iteration " + iteration + " it started at " + IterationStart);

                iteration++;
            }
        }
コード例 #3
0
        public static void computeUtility(string[] commandPieces, resultObject Result)
        {
            //usage computeutility AS d iteration
            if (commandPieces.Length < 4)
            {
                Console.WriteLine("computeutility [ASN] [dest] [iteration]");
                return;
            }

            UInt32 ASN, dest;
            Int32  iter;

            if (!UInt32.TryParse(commandPieces[1], out ASN) || !UInt32.TryParse(commandPieces[2], out dest) || !Int32.TryParse(commandPieces[3], out iter))
            {
                Console.WriteLine("bad params");
                return;
            }
            if (iter > Result.state.Count)
            {
                Console.WriteLine("iteration too large.");
                return;
            }
            bool[] iterState = Result.state[iter];
            foreach (var stub in Result.g.getStubs())
            {
                iterState[stub] = true;//turn on the stubs as in the sim
            }
            SimulatorLibrary.setUtilityComputation(UtilityComputationType.outgoing);
            GlobalState initial = SimulatorLibrary.initGlobalState(Result.g, Result.earlyAdopters, Result.weightedNodes, short.Parse(Result.k));
            Destination d       = new Destination(SimulatorLibrary.initMiniDestination(Result.g, dest, false));

            d.UpdatePaths(iterState);
            d.ComputeU(initial.W);
            Console.WriteLine("Utility for " + ASN + " in iteration: " + iter + " is " + d.U[ASN]);
            Worker w         = new Worker();
            int    afterFlip = w.ComputeUtility(d.BucketTable, d.Best, d.ChosenParent, d.SecP, iterState, ASN, d.L[ASN], d.BestRelation[ASN], initial.W);

            Console.WriteLine("Utility for " + ASN + " in iteration: " + iter + " if they flip is " + afterFlip);
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: valkiria88/Astoria
        private static bool initDestination(ref NetworkGraph g, ref Destination d, string dest)
        {
            UInt32 destNum;

            if (!UInt32.TryParse(dest, out destNum))
            {
                /*
                 * Console.WriteLine("Invalid ASN!");
                 */
                return(false);
            }
            if (g.GetNode(destNum) == null)
            {
                /*
                 * Console.WriteLine("WARNING: Could not retrieve destination " + d + " from the graph.");
                 */
                return(false);
            }

            /*
             * Console.WriteLine("Initializing variables and running RTA");
             */
            MiniDestination miniDest = SimulatorLibrary.initMiniDestination(g, destNum, false);

            d = new Destination(miniDest);
            bool[] tempS = new bool[Constants._numASNs];
            for (int i = 0; i < tempS.Length; i++)
            {
                tempS[i] = false;
            }
            d.UpdatePaths(tempS);

            /*
             * Console.WriteLine("Done initializing. Current active destination is: " + destNum);
             */
            return(true);
        }
コード例 #5
0
        /// <summary>
        /// static constructor
        /// </summary>
        static ModifiedBfs()
        {
            if (File.Exists("paramsFile.txt"))
            {
                StreamReader input = new StreamReader("paramsFile.txt");

                while (!input.EndOfStream)
                {
                    string line = input.ReadLine().ToLower();
                    //hashing
                    if (line.IndexOf("sethash") == 0)
                    {
                        bool inputSetHash;
                        if (SimulatorLibrary.readParameter(line, out inputSetHash))
                        {
                            Hash = inputSetHash;
                        }
                    }//only nonstubs
                    else if (line.IndexOf("setonlynotstubs") == 0 || line.IndexOf("setonlynonstubs") == 0)
                    {
                        bool inputNonStubs;
                        if (SimulatorLibrary.readParameter(line, out inputNonStubs))
                        {
                            OnlyNonStubs = inputNonStubs;
                        }
                    }
                }
                input.Close();
                Console.WriteLine("*******************");
                Console.WriteLine("Done reading parameters for BFS.");
                Console.WriteLine("Hash is " + ModifiedBfs.Hash);

                Console.WriteLine("onlynonstubs is: " + ModifiedBfs.OnlyNonStubs);
                Console.WriteLine("*******************");
            }
        }
コード例 #6
0
ファイル: Destination.cs プロジェクト: valkiria88/Astoria
        /// <summary>
        /// returns current utility as determined by looking at the ChosenPath structure
        /// </summary>
        /// <returns>vector with 1 element per ASN with that ASNs utility.</returns>
        public void ComputeU(UInt16[] W)
        {
            //4 temporary utility types (customer sub tree size,
            //customer weighted subtree, peer weighted subtree and provider weighted subtree
            const Int32 CustomerTreeSize         = 0;
            const Int32 CustomerWeightedTreeSize = 1;
            const Int32 PeerWeightedTreeSize     = 2;
            const Int32 ProviderWeightedTreeSize = 3;

            Int32[][] tempU = new Int32[4][];
            for (int i = 0; i < tempU.Length; i++)
            {
                tempU[i] = new Int32[Constants._numASNs];
            }

            //reinitialize U
            for (int i = 0; i < U.Length; i++)
            {
                U[i] = 0;
            }

            for (int i = 0; i < ChosenPath.Length; i++)
            {
                if (ChosenPath[i] != null)
                {
                    /** first element of the path is non-transformed ASN of the
                     * node at the end of the path, skip it **/
                    for (int j = 1; j < ChosenPath[i].Count; j++)
                    {
                        UInt32 ASN;
                        Int32  col;
                        unjoin(ChosenPath[i][j], out ASN, out col);
                        if (ASN != destination)
                        {
                            if (col == _PROVIDERCOLUMN)
                            {
                                tempU[CustomerTreeSize][ASN]++;
                                tempU[CustomerWeightedTreeSize][ASN] += W[i];/*W[i] because i is the node routing through us
                                                                              * (whose path we are considering)
                                                                              * how much are they worth to us?*/
                            }
                            else if (col == _PEERCOLUMN)
                            {
                                tempU[PeerWeightedTreeSize][ASN] += W[i];
                            }
                            else if (col == _CUSTOMERCOLUMN)
                            {
                                tempU[ProviderWeightedTreeSize][ASN] += W[i];
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < U.Length; i++)
            {
                U[i] = SimulatorLibrary.utilityComputation(tempU[CustomerTreeSize][i],
                                                           tempU[CustomerWeightedTreeSize][i],
                                                           tempU[PeerWeightedTreeSize][i],
                                                           tempU[ProviderWeightedTreeSize][i],
                                                           BestRelation[i], W[destination]);
            }
        }
コード例 #7
0
        public static void trafficThroughSecureProviders(resultObject results)
        {
            //get what the simulation state would look like.
            GlobalState GS = SimulatorLibrary.initGlobalState(results.g, results.earlyAdopters, results.weightedNodes, short.Parse(results.k));

            /** First, get a list of multihomed stubs as destinations **/
            var           stubs           = results.g.getStubs();
            List <UInt32> multihomedStubs = new List <UInt32>();

            foreach (UInt32 stubNum in stubs)
            {
                AsNode stub = results.g.GetNode(stubNum);
                //if this stub is multihomed, init a destination. add it to the list.
                if (stub.GetNeighborsByType(RelationshipType.CustomerOf).ToArray().Length > 1)
                {
                    multihomedStubs.Add(stubNum);
                }
            }

            Console.WriteLine(multihomedStubs.Count + " stubs out of " + stubs.Count + " are multihomed.");

            StreamWriter output = new StreamWriter("trafficThroughSecureProvider.txt");

            /** Second, go through each iteration... **/
            int iteration = 0;

            foreach (bool[] S in results.state)
            {
                DateTime IterationStart = DateTime.Now;
                Int32    numDone        = 0;
                foreach (UInt32 multihomedStubNum in multihomedStubs)
                {
                    /** for this multhomed stub, see how much traffic
                     * goes through secure providers **/
                    AsNode      multihomedStub     = results.g.GetNode(multihomedStubNum);
                    Destination multihomedStubDest = new Destination(SimulatorLibrary.initMiniDestination(results.g, multihomedStubNum, false));

                    //computer the paths and utilities.
                    multihomedStubDest.UpdatePaths(S);
                    multihomedStubDest.ComputeU(GS.W);

                    //get the providers.
                    var Providers = multihomedStub.GetNeighborsByType(RelationshipType.CustomerOf);

                    //count traffic through secure providers (and number of secure providers).
                    Int64 TotalU          = 0;
                    Int64 SecureProviderU = 0;
                    Int32 TotalProviders  = Providers.Count();
                    Int32 SecureProviders = 0;
                    foreach (var Provider in Providers)
                    {
                        if (S[Provider.NodeNum])
                        {
                            SecureProviderU += multihomedStubDest.U[Provider.NodeNum];
                            SecureProviders++;
                        }
                        TotalU += multihomedStubDest.U[Provider.NodeNum];
                    }

                    /*write out summary of how much traffic went through secure providers. */
                    output.WriteLine(iteration + " :: " + multihomedStubNum + " " + SecureProviders + " " + TotalProviders + " " + SecureProviderU + " " + TotalU);
                    numDone++;
                    if ((numDone % 100) == 0)
                    {
                        Console.WriteLine("Done " + numDone + " at " + DateTime.Now);
                    }
                }
                //some benchmarking.
                Console.WriteLine(DateTime.Now + " done iteration " + iteration + " it started at " + IterationStart);

                iteration++;
            }

            output.Close();
        }
コード例 #8
0
        public void testSPInterface()
        {
            SimulatorLibrary.setHash(true);
            SimulatorLibrary.setUtilityComputation(UtilityComputationType.outgoing);
            Console.WriteLine("Welcome to the short paths testing interface: ");
            bool exitNow = false;


            while (!exitNow)
            {
                Console.Write(">>");
                string   command = Console.ReadLine().ToLower();
                string[] pieces  = command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                if (command.IndexOf("input") == 0)
                {
                    g = input(pieces);
                }
                else if (command.IndexOf("getpath") == 0)
                {
                    getpath(pieces);
                }
                else if (command.IndexOf("setstate") == 0)
                {
                    S = setstate(pieces);
                }
                else if (command.IndexOf("init") == 0)
                {
                    List <UInt32> ea = new List <uint>();
                    ea.Add(1239);
                    gs = SimulatorLibrary.initGlobalState(g, ea);
                }
                else if (command.IndexOf("iterate") == 0)
                {
                    List <MiniDestination> miniDs = new List <MiniDestination>();
                    foreach (var AS in g.GetAllNodes())
                    {
                        miniDs.Add(SimulatorLibrary.initMiniDestinationSP(g, AS.NodeNum, false));
                        Console.WriteLine("initialized AS " + AS.NodeNum);
                    }

                    List <Message> results = new List <Message>();
                    foreach (var mD in miniDs)
                    {
                        results.Add(SimulatorLibrary.ComputeOnDestination(mD, gs));
                        Console.WriteLine("computed on: " + mD.destination);
                    }
                    Console.WriteLine("updating global state.");
                    Int64[] Before = new Int64[Constants._numASNs];
                    Int64[] After  = new Int64[Constants._numASNs];


                    SimulatorLibrary.updateGlobalState(ref gs, results, (float)0, ref Before, ref After);
                    for (int i = 0; i < gs.S.Length; i++)
                    {
                        if (gs.S[i])
                        {
                            Console.WriteLine("AS " + i + " is on.");
                        }
                    }
                }
            }
        }
コード例 #9
0
ファイル: ObjectToText.cs プロジェクト: valkiria88/Astoria
        public static string writeIterationToBlob(string containerName, Int32 t, ref Int64[] Before, ref Int64[] After, ref bool[] State)
        {
            string baseUri         = "";
            string paddedContainer = "";

            SimulatorLibrary.generateDirectoryName(containerName, ref paddedContainer);

            CloudBlobContainer blobContainer = BlobLibrary.initContainer(paddedContainer, ref baseUri);

            int    tries   = 0;
            bool   success = false;
            string errors  = "";

            do
            {
                try
                {
                    blobContainer.CreateIfNotExist();
                    success = true;
                }
                catch (Exception e)
                {
                    BlobLibrary.logToBlog("error when creating iteration result blob. " + e.Message + " retrying...", AccountInfo.masterLog);
                    Console.WriteLine("error when creating iteration result blob. " + e.Message + " retrying...");
                    errors = errors + e.Message + "\n";
                    Thread.Sleep(3000);
                    tries++;
                }
            } while (tries < 5 && !success);
            if (!success)
            {
                return(errors);
            }
            var perms = new BlobContainerPermissions
            {
                PublicAccess = BlobContainerPublicAccessType.Container // Blob (see files if you know the name) or Container (enumerate like a directory)
            };

            blobContainer.SetPermissions(perms); // This line makes the blob public so it is available from a web browser (no magic needed to read it)

            StreamWriter BeforeOutput = new StreamWriter(BlobLibrary.getBlobWriteStream(paddedContainer, paddedContainer + "." + Constants._UBeforeFileName + "." + t));
            StreamWriter AfterOutput  = new StreamWriter(BlobLibrary.getBlobWriteStream(paddedContainer, paddedContainer + "." + Constants._UAfterFileName + "." + t));
            StreamWriter StateOutput  = new StreamWriter(BlobLibrary.getBlobWriteStream(paddedContainer, paddedContainer + "." + Constants._SFileName + "." + t));

            for (int i = 0; i < Before.Length; i++)
            {
                BeforeOutput.Write(Before[i] + ",");
            }
            for (int i = 0; i < After.Length; i++)
            {
                AfterOutput.Write(After[i] + ",");
            }
            for (int i = 0; i < State.Length; i++)
            {
                if (State[i])
                {
                    StateOutput.Write("1,");
                }
                else
                {
                    StateOutput.Write("0,");
                }
            }

            BeforeOutput.Write("\n");
            AfterOutput.Write("\n");
            StateOutput.Write("\n");

            BeforeOutput.Close();
            AfterOutput.Close();
            StateOutput.Close();

            return("");
        }
コード例 #10
0
        private static List <UInt32> stubsThroughMeIncrease(List <UInt32> sourceNodes, UInt32 ASN, List <bool[]> state, NetworkGraph g, StreamWriter output)
        {
            var stubs = g.getStubs();

            var ASNode = g.GetNode(ASN);

            //this node flipped,figure out which iteration.
            int flippedIter = -1;

            for (int i = 0; flippedIter < 0 && i < state.Count; i++)
            {
                if (state[i][ASN])
                {
                    flippedIter = i;
                }
            }

            if (flippedIter == 0)
            {
                Console.WriteLine("ASN: " + ASN + " was on to begin with.");
                return(new List <UInt32>());
            }

            //one variable per source node counting how many stubs of mine
            //route through me from this source now.
            List <UInt32> newCustomerPathsPerSourceNode = new List <UInt32>();

            for (int i = 0; i < sourceNodes.Count; i++)
            {
                newCustomerPathsPerSourceNode.Add(0);
            }


            foreach (var customer in ASNode.GetNeighborsByType(RelationshipType.ProviderTo))
            {
                List <UInt32[]> pathsBefore        = new List <uint[]>();
                List <UInt32[]> pathsAfter         = new List <uint[]>();
                List <string>   pathsBeforeStrings = new List <string>();
                List <string>   pathsAfterStrings  = new List <string>();

                Destination d = new Destination(SimulatorLibrary.initMiniDestination(g, customer.NodeNum, false));
                //paths before the AS flipped (from early adopters to this stub.)
                d.UpdatePaths(state[flippedIter - 1]);

                foreach (var bigASN in sourceNodes)
                {
                    if (bigASN != d.destination)
                    {
                        pathsBefore.Add(d.GetPathList(bigASN));//path from bigASN to the stub.
                        pathsBeforeStrings.Add(d.GetPath(bigASN, state[flippedIter - 1]));
                    }
                    else
                    {//dummy vals. this source is the destination.
                        pathsBefore.Add(new UInt32[0]);
                        pathsBeforeStrings.Add("");
                    }
                }
                //paths after AS flipped.
                d.UpdatePaths(state[flippedIter]);
                foreach (var bigASN in sourceNodes)
                {
                    if (bigASN != d.destination)
                    {
                        pathsAfter.Add(d.GetPathList(bigASN));
                        pathsAfterStrings.Add(d.GetPath(bigASN, state[flippedIter]));
                    }
                    else
                    {
                        //dummy vals. this source is the destination.
                        pathsAfter.Add(new UInt32[0]);
                        pathsAfterStrings.Add("");
                    }
                }

                for (int i = 0; i < sourceNodes.Count; i++)
                {
                    var bigASN = sourceNodes[i];
                    if (bigASN != d.destination)
                    {
                        var  pathBefore  = pathsBefore[i];
                        var  pathAfter   = pathsAfter[i];
                        bool pathChanged = false;
                        for (int j = 0; j < pathBefore.Length; j++)
                        {
                            if (pathBefore[j] != pathAfter[j])
                            {
                                pathChanged = true;
                            }
                        }

                        if (pathChanged)
                        {
                            if (pathsBeforeStrings[i].IndexOf(ASN.ToString()) >= 0 || pathsAfterStrings[i].IndexOf(ASN.ToString()) >= 0)
                            {
                                //the path after must have been fully secure save for the guy who flipped. and the path before cannot contain the guy who flipped.
                                if (ResultsExplorer.fullySecure(pathsAfter[i], ASNode.NodeNum, state[flippedIter - 1], stubs) && !pathsBefore[i].Contains(ASNode.NodeNum))
                                {
                                    /** Console.WriteLine("---");
                                     * Console.WriteLine("Path from: " + bigASN + " to " + customer.NodeNum + " changed from: ");
                                     * Console.WriteLine(pathsBeforeStrings[i]);
                                     * Console.WriteLine("to: ");
                                     * Console.WriteLine(pathsAfterStrings[i]);
                                     * Console.WriteLine("---");
                                     **///don't be verbose.

                                    newCustomerPathsPerSourceNode[i]++;
                                }
                            }
                        }
                    }
                }
                //put progress meter here
            }

            return(newCustomerPathsPerSourceNode);
        }
コード例 #11
0
        /// <summary>
        /// implements the recomputing utility function. figures out what the utility for n would be if n flipped its state
        /// from its present state in S.
        /// </summary>
        /// <param name="BucketTable"></param>
        /// <param name="Best"></param>
        /// <param name="ChosenParent"></param>
        /// <param name="SecP"></param>
        /// <param name="S"></param>
        /// <param name="n"></param>
        /// <param name="L"></param>
        /// <param name="BestRelation"></param>
        /// <param name="W"></param>
        /// <returns></returns>
        public int ComputeUtility(List <UInt32>[][] BucketTable, List <UInt32>[] Best, UInt32[] param_ChosenParent, bool[] param_SecP, bool[] S, UInt32 n, int L, byte BestRelation, UInt16[] W)
        {
            if (L == 0)
            {
                return(0);   //no utility for routing to itself
            }
            int UNTilda = 0; //utility for S with n's state flipped

            Int32 CustomerTreeSize         = 0;
            Int32 CustomerWeightedTreeSize = 0;
            Int32 PeerWeightedTreeSize     = 0;
            Int32 ProviderWeightedTreeSize = 0;

            //DON'T LET US OVERWRITE THINGS; we can overwrite S and flip it back at the end.
            ChosenParent = (UInt32[])param_ChosenParent.Clone();
            SecP         = (bool[])param_SecP.Clone();

            S[n] = !S[n]; //reverse n's state (we revert this before we return).

            //update n's path. if it has options
            if (Best[n].Count > 1)
            {
                if (S[n])                                                               //n became secure it cares about security in picking its path
                {
                    updateParentWorker(n, ref Best, ref S, ref SecP, ref ChosenParent); //, ref tieBreakSet);
                }
                else
                {
                    //n became insecure; re-evaluate its path options from the set of all paths.
                    UInt32 newParent = Best[n][0];
                    ChosenParent[n] = newParent;
                }
            }
            //   if (S[n])//can only have secP if n is secure. (using an and so we revoke SecP for n flipping back.
            SecP[n] = S[n] & SecP[ChosenParent[n]];

            byte[] throughN = new byte[Constants._numASNs];

            for (int i = 0; i < Constants._numASNs; i++)
            {
                throughN[i] = 0; //empty value.
            }
            for (int row = L + 1; row < BucketTable.GetLength(0); row++)
            {
                foreach (int col in columns)
                {
                    if (BucketTable[row][col] == null)
                    {
                        continue;
                    }
                    foreach (UInt32 i in BucketTable[row][col])
                    {
                        /*only secure nodes will change their parents based on security. We still need to update
                         * whether or not they gothrough n though because someone before them may have changed to go
                         * through n*/
                        if (Best[i].Count > 1)                                                  //update path *only* if you have options.
                        {
                            updateParentWorker(i, ref Best, ref S, ref SecP, ref ChosenParent); //, ref tieBreakSet);
                        }
                        if (S[i])                                                               //only say your path is secure if you are secure
                        {
                            SecP[i] = SecP[ChosenParent[i]];
                        }

                        /* done updating our parents need to update whether we go through n or not */

                        if (row == L + 1 && ChosenParent[i] == n && col == Destination._PROVIDERCOLUMN)
                        {
                            throughN[i] = CustomerOf; //i is a customer of N
                        }
                        else if (row == L + 1 && ChosenParent[i] == n && col == Destination._PEERCOLUMN)
                        {
                            throughN[i] = PeerOf;
                        }
                        else if (row == L + 1 && ChosenParent[i] == n && col == Destination._CUSTOMERCOLUMN)
                        {
                            throughN[i] = ProviderTo; //i is a provider to N
                        }
                        else if (row > (L + 1))
                        {
                            throughN[i] = throughN[ChosenParent[i]];
                        }

                        //update utility values on how we pass through n
                        switch (throughN[i])
                        {
                        case CustomerOf:
                            CustomerTreeSize++;
                            CustomerWeightedTreeSize += W[i];
                            break;

                        case PeerOf:
                            PeerWeightedTreeSize += W[i];
                            break;

                        case ProviderTo:
                            ProviderWeightedTreeSize += W[i];
                            break;
                        }
                    }
                }
            }

            S[n] = !S[n]; //flip n back
            UInt16 dWeight = W[BucketTable[0][0][0]];

            UNTilda = SimulatorLibrary.utilityComputation(CustomerTreeSize,
                                                          CustomerWeightedTreeSize,
                                                          PeerWeightedTreeSize,
                                                          ProviderWeightedTreeSize,
                                                          BestRelation, dWeight);

            return(UNTilda);
        }