Exemplo n.º 1
0
/// 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;
}
Exemplo n.º 2
0
/// 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);
  }
}
Exemplo n.º 3
0
int GetMaxFlowIntPR (PNEANet &Net, const int& SrcNId, const int& SnkNId) {
  IAssert(Net->IsNode(SrcNId));
  IAssert(Net->IsNode(SnkNId));
  if (SrcNId == SnkNId) { return 0; }

  TPRManager PRM(Net);
  int MaxLabel = PRM.GetMaxLabel();

  TNEANet::TNodeI SrcNI = Net->GetNI(SrcNId);
  for (int EdgeN = 0; EdgeN < SrcNI.GetOutDeg(); EdgeN++) {
    int EId = SrcNI.GetOutEId(EdgeN);
    int OutNId = SrcNI.GetOutNId(EdgeN);
    if (OutNId != SrcNId) {
      int Capacity = PRM.Capacity(EId);
      PRM.Flow(EId) = Capacity;
      PRM.Excess(OutNId) = Capacity;
    }
  }
  GlobalRelabel(Net, PRM, SrcNId, SnkNId);
  PRM.SetLabel(SrcNId, MaxLabel);
  int RelabelCount = 1;
  int GRRate = Net->GetNodes();
  while (PRM.HasActive()) {
    int NId = PRM.PopActive();
    const TNEANet::TNodeI &NI = Net->GetNI(NId);
    int PrevLabel = MaxLabel;
    while (PRM.Excess(NId) > 0 && PRM.Label(NId) <= PrevLabel) {
      PrevLabel = PRM.Label(NId);
      int NbrNId = PushRelabel(PRM, NId, NI);
      if (NbrNId != -1 && NbrNId != SnkNId && PRM.Excess(NbrNId) > 0 && !PRM.IsActive(NbrNId)) {
        PRM.PushActive(NbrNId);
      }
    }
    if (PRM.Excess(NId) > 0 && PRM.Label(NId) < MaxLabel) {
      PRM.PushActive(NId);
    }
    if (RelabelCount % GRRate == 0) { GlobalRelabel(Net, PRM, SrcNId, SnkNId); }
  }
  return PRM.Excess(SnkNId);
}