6 PredEdgeH.
AddDat(SrcNId, -1);
8 SuccEdgeH.
AddDat(SnkNId, -1);
9 while (!FwdNodeQ.
Empty() && !BwdNodeQ.
Empty()) {
13 for (
int EdgeN = 0; EdgeN < FwdNI.
GetInDeg(); EdgeN++) {
16 if (!PredEdgeH.
IsKey(NextNId) && Flow[NextEId] > 0) {
17 PredEdgeH.
AddDat(NextNId, NextEId);
18 if (SuccEdgeH.
IsKey(NextNId)) {
21 FwdNodeQ.
Push(NextNId);
25 for (
int EdgeN = 0; EdgeN < FwdNI.
GetOutDeg(); EdgeN++) {
28 if (!PredEdgeH.
IsKey(NextNId) && Net->GetIntAttrIndDatE(NextEId, CapIndex) > Flow[NextEId]) {
29 PredEdgeH.
AddDat(NextNId, NextEId);
30 if (SuccEdgeH.
IsKey(NextNId)) {
33 FwdNodeQ.
Push(NextNId);
39 for (
int EdgeN = 0; EdgeN < BwdNI.
GetOutDeg(); EdgeN++) {
42 if (!SuccEdgeH.
IsKey(PrevNId) && Flow[PrevEId] > 0) {
43 SuccEdgeH.
AddDat(PrevNId, PrevEId);
44 if (PredEdgeH.
IsKey(PrevNId)) {
47 BwdNodeQ.
Push(PrevNId);
51 for (
int EdgeN = 0; EdgeN < BwdNI.
GetInDeg(); EdgeN++) {
54 if (!SuccEdgeH.
IsKey(PrevNId) && Net->GetIntAttrIndDatE(PrevEId, CapIndex) > Flow[PrevEId]) {
55 SuccEdgeH.
AddDat(PrevNId, PrevEId);
56 if (PredEdgeH.
IsKey(PrevNId)) {
59 BwdNodeQ.
Push(PrevNId);
71 int FindAugV (
const PNEANet &Net,
const int& CapIndex,
TIntV &Flow,
TIntQ &FwdNodeQ,
TIntH &PredEdgeH,
TIntQ &BwdNodeQ,
TIntH &SuccEdgeH,
TIntV &MidToSrcAugV,
TIntV &MidToSnkAugV,
const int& SrcNId,
const int& SnkNId) {
72 int MidPtNId =
IntFlowBiDBFS(Net, CapIndex, Flow, FwdNodeQ, PredEdgeH, BwdNodeQ, SuccEdgeH, SrcNId, SnkNId);
73 if (MidPtNId == -1) {
return 0; }
74 int MinAug =
TInt::Mx, NId = MidPtNId, AugFlow = 0;
76 for (
int EId = PredEdgeH.
GetDat(NId); NId != SrcNId; EId = PredEdgeH.
GetDat(NId)) {
77 MidToSrcAugV.
Add(EId);
84 AugFlow = Net->GetIntAttrIndDatE(EId, CapIndex) - Flow[EId];
86 if (AugFlow < MinAug) { MinAug = AugFlow; }
90 for (
int EId = SuccEdgeH.
GetDat(NId); NId != SnkNId; EId = SuccEdgeH.
GetDat(NId)) {
91 MidToSnkAugV.
Add(EId);
98 AugFlow = Net->GetIntAttrIndDatE(EId, CapIndex) - Flow[EId];
100 if (AugFlow < MinAug) { MinAug = AugFlow; }
108 if (SrcNId == SnkNId) {
return 0; }
110 TIntV Flow(Net->GetMxEId());
113 IAssert(Net->GetIntAttrIndDatE(EI, CapIndex) >= 0);
114 Flow[EI.GetId()] = 0;
117 if (SrcNId == SnkNId) {
return 0; }
118 int MaxFlow = 0, MinAug, CurNId;
123 MinAug =
FindAugV(Net, CapIndex, Flow, FwdNodeQ, PredEdgeH, BwdNodeQ, SuccEdgeH, MidToSrcAugV, MidToSnkAugV, SrcNId, SnkNId);
124 if (MinAug == 0) {
break; }
127 for (
int i = MidToSrcAugV.
Len() - 1; i >= 0; i--) {
128 int NextEId = MidToSrcAugV[i];
131 Flow[NextEId] += MinAug;
134 Flow[NextEId] -= MinAug;
138 for (
int i = 0; i < MidToSnkAugV.
Len(); i++) {
139 int NextEId = MidToSnkAugV[i];
142 Flow[NextEId] += MinAug;
145 Flow[NextEId] -= MinAug;
169 TPRManager(
PNEANet &
Net) : Net(Net),
CapIndex(0),
FlowV(Net->GetMxEId()),
ExcessV(Net->GetMxNId()),
EdgeNumsV(Net->GetMxNId()),
LabelsV(Net->GetMxNId()),
LabelCounts(Net->GetNodes() + 1),
LabelLimit(0),
MaxLabel(Net->GetNodes()),
ActiveNodeSet(Net->GetMxNId()),
ActiveCount(0) {
171 for (
int i = 0; i <= Net->GetNodes(); i++) {
LabelCounts[i] = 0; }
173 int EId = EI.GetId();
178 int NId = NI.GetId();
191 return FlowV[EId].Val;
223 int NId = NI.GetId();
225 if (OldLabel > GapLabel && OldLabel <=
LabelLimit) {
291 PRM.
Flow(EId) += MinPush;
292 PRM.
Excess(NId) -= MinPush;
293 PRM.
Excess(OutNId) += MinPush;
299 PRM.
Flow(EId) -= MinPush;
300 PRM.
Excess(NId) -= MinPush;
301 PRM.
Excess(InNId) += MinPush;
307 int MinLabel = MaxLabel;
308 for (
int EdgeN = 0; EdgeN < NI.
GetInDeg(); EdgeN++) {
311 MinLabel =
MIN(MinLabel, InLabel);
314 for (
int EdgeN = 0; EdgeN < NI.
GetOutDeg(); EdgeN++) {
317 MinLabel =
MIN(MinLabel, OutLabel);
320 if (MinLabel == MaxLabel) {
330 int EId = -1, NbrNId = -1, ResFlow = 0;
332 if (EdgeN < Cutoff) {
335 ResFlow = PRM.
Flow(EId);
341 if (ResFlow > 0 && PRM.
Label(NId) - 1 == PRM.
Label(NbrNId)) {
342 if (EdgeN < Cutoff) {
349 if (EdgeN + 1 == NI.
GetDeg()) {
365 int size = Net->GetMxNId();
367 for (
int i = 0; i < size; i++) { NodeV[i] = 0; }
371 while (!NodeQ.
Empty()) {
373 int NId = NodeQ.
Top(); NodeQ.
Pop();
376 for (
int EdgeN = 0; EdgeN < NI.
GetOutDeg(); EdgeN++) {
379 if (!NodeV[OutNId] && PRM.
Flow(EId) > 0) {
386 for (
int EdgeN = 0; EdgeN < NI.
GetInDeg(); EdgeN++) {
389 if (!NodeV[InNId] && PRM.
Capacity(EId) > PRM.
Flow(EId)) {
398 int NId = NI.GetId();
400 if (PRM.
Excess(NId) > 0 && PRM.
Label(NId) < MaxLabel && NId != SnkNId) {
413 if (SrcNId == SnkNId) {
return 0; }
419 for (
int EdgeN = 0; EdgeN < SrcNI.
GetOutDeg(); EdgeN++) {
422 if (OutNId != SrcNId) {
424 PRM.
Flow(EId) = Capacity;
425 PRM.
Excess(OutNId) = Capacity;
430 int RelabelCount = 1;
431 int GRRate = Net->GetNodes();
435 int PrevLabel = MaxLabel;
436 while (PRM.
Excess(NId) > 0 && PRM.
Label(NId) <= PrevLabel) {
437 PrevLabel = PRM.
Label(NId);
439 if (NbrNId != -1 && NbrNId != SnkNId && PRM.
Excess(NbrNId) > 0 && !PRM.
IsActive(NbrNId)) {
443 if (PRM.
Excess(NId) > 0 && PRM.
Label(NId) < MaxLabel) {
446 if (RelabelCount % GRRate == 0) {
GlobalRelabel(Net, PRM, SrcNId, SnkNId); }
448 return PRM.
Excess(SnkNId);
void PushToOutNbr(TPRManager &PRM, const int &NId, const int &OutNId, const int &EId)
Pushes flow from a node NId to a neighbor OutNId over edge EId.
int PushRelabel(TPRManager &PRM, const int &NId, const TNEANet::TNodeI &NI)
Returns the ID of the neighbor that NId pushes to, -1 if no push was made.
int GetOutNId(const int &EdgeN) const
Returns ID of EdgeN-th out-node (the node the current node points to).
int GetOutDeg() const
Returns out-degree of the current node.
int GetInNId(const int &EdgeN) const
Returns ID of EdgeN-th in-node (the node pointing to the current node).
TSizeTy Len() const
Returns the number of elements in the vector.
void Relabel(TPRManager &PRM, const int &NId, const TNEANet::TNodeI &NI)
Increases the label of a node NId to allow valid pushes to some neighbor.
int GetOutEId(const int &EdgeN) const
Returns ID of EdgeN-th out-edge.
const TDat & GetDat(const TKey &Key) const
Node iterator. Only forward iteration (operator++) is supported.
int GetDeg() const
Returns degree of the current node, the sum of in-degree and out-degree.
int GetInEId(const int &EdgeN) const
Returns ID of EdgeN-th in-edge.
int FindAugV(const PNEANet &Net, const int &CapIndex, TIntV &Flow, TIntQ &FwdNodeQ, TIntH &PredEdgeH, TIntQ &BwdNodeQ, TIntH &SuccEdgeH, TIntV &MidToSrcAugV, TIntV &MidToSnkAugV, const int &SrcNId, const int &SnkNId)
Returns the amount the flow can be augmented over the paths, 0 if no path can be found.
int GetDstNId() const
Returns the destination of the edge.
void GlobalRelabel(PNEANet &Net, TPRManager &PRM, const int &SrcNId, const int &SnkNId)
Implements the Global Relabeling heuristic.
void SetLabel(int NId, int Label)
void CheckGap(int GapLabel)
Removes any gaps in node labels.
int GetInDeg() const
Returns in-degree of the current node.
int GetMaxFlowIntEK(PNEANet &Net, const int &SrcNId, const int &SnkNId)
Returns the maximum integer valued flow in the network Net from source SrcNId to sink SnkNId...
int GetSrcNId() const
Returns the source of the edge.
void RemoveActive(int NId)
int GetMaxFlowIntPR(PNEANet &Net, const int &SrcNId, const int &SnkNId)
Returns the maximum integer valued flow in the network Net from source SrcNId to sink SnkNId...
int IntFlowBiDBFS(const PNEANet &Net, const int &CapIndex, TIntV &Flow, TIntQ &FwdNodeQ, TIntH &PredEdgeH, TIntQ &BwdNodeQ, TIntH &SuccEdgeH, const int &SrcNId, const int &SnkNId)
Edge iterator. Only forward iteration (operator++) is supported.
void Push(const TVal &Val)
Push relabel attr manager.
void PushToInNbr(TPRManager &PRM, const int &NId, const int &InNId, const int &EId)
Returns flow from a node NId to a neighbor InNId over edge EId.
bool IsKey(const TKey &Key) const
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
TDat & AddDat(const TKey &Key)
Vector is a sequence TVal objects representing an array that can change in size.