/// Returns the ID of the neighbor that \c NId pushes to, -1 if no push was made. int PushRelabel (TPRManager &PRM, const int &NId, const TNEANet::TNodeI &NI) { int EdgeN = PRM.EdgeNum(NId); int EId = -1, NbrNId = -1, ResFlow = 0; int Cutoff = NI.GetInDeg(); if (EdgeN < Cutoff) { EId = NI.GetInEId(EdgeN); NbrNId = NI.GetInNId(EdgeN); ResFlow = PRM.Flow(EId); } else { EId = NI.GetOutEId(EdgeN - Cutoff); NbrNId = NI.GetOutNId(EdgeN - Cutoff); ResFlow = PRM.Capacity(EId) - PRM.Flow(EId); } if (ResFlow > 0 && PRM.Label(NId) - 1 == PRM.Label(NbrNId)) { if (EdgeN < Cutoff) { PushToInNbr(PRM, NId, NbrNId, EId); } else { PushToOutNbr(PRM, NId, NbrNId, EId); } return NbrNId; } if (EdgeN + 1 == NI.GetDeg()) { PRM.EdgeNum(NId) = 0; Relabel(PRM, NId, NI); } else { PRM.EdgeNum(NId)++; } return -1; }
/// Increases the label of a node \c NId to allow valid pushes to some neighbor. void Relabel (TPRManager &PRM, const int &NId, const TNEANet::TNodeI &NI) { int MaxLabel = PRM.GetMaxLabel(); int MinLabel = MaxLabel; for (int EdgeN = 0; EdgeN < NI.GetInDeg(); EdgeN++) { if (PRM.Flow(NI.GetInEId(EdgeN)) > 0) { int InLabel = PRM.Label(NI.GetInNId(EdgeN)); MinLabel = min(MinLabel, InLabel); } } for (int EdgeN = 0; EdgeN < NI.GetOutDeg(); EdgeN++) { if (PRM.Capacity(NI.GetOutEId(EdgeN)) > PRM.Flow(NI.GetOutEId(EdgeN))) { int OutLabel = PRM.Label(NI.GetOutNId(EdgeN)); MinLabel = min(MinLabel, OutLabel); } } if (MinLabel == MaxLabel) { PRM.SetLabel(NId, MaxLabel); } else { PRM.SetLabel(NId, MinLabel + 1); } }