/// <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]); } }
/// <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); }