// Test node, edge attribute functionality TEST(TNEANet, AddEdgeNodeAfterAttrAdded) { PNEANet Graph; Graph = TNEANet::New(); TStr StrAttr("name"); TStr EIntAttr("weight"); TStr NIntAttr("test"); Graph->AddStrAttrN(StrAttr); Graph->AddIntAttrN(NIntAttr); Graph->AddIntAttrE(EIntAttr); Graph->AddNode(0); Graph->AddNode(1); Graph->AddNode(2); Graph->AddStrAttrDatN(0, "zero", StrAttr); Graph->AddStrAttrDatN(1, "one", StrAttr); Graph->AddStrAttrDatN(2, "two", StrAttr); Graph->AddEdge(0, 1); Graph->AddEdge(1, 2); Graph->AddEdge(2, 0); for (TNEANet::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { Graph->AddIntAttrDatE(EI.GetId(), EI.GetId()*3+1, EIntAttr); } for (TNEANet::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { TInt AttrVal = Graph->GetIntAttrDatE(EI.GetId(), EIntAttr); ASSERT_EQ(EI.GetId()*3+1, AttrVal); } }
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) { CapIndex = Net->GetIntAttrIndE(CapAttrName); for (int i = 0; i <= Net->GetNodes(); i++) { LabelCounts[i] = 0; } for (TNEANet::TEdgeI EI = Net->BegEI(); EI != Net->EndEI(); EI++) { int EId = EI.GetId(); IAssert(Capacity(EId) >= 0); FlowV[EId] = 0; } for (TNEANet::TNodeI NI = Net->BegNI(); NI != Net->EndNI(); NI++) { int NId = NI.GetId(); ExcessV[NId] = 0; EdgeNumsV[NId] = 0; ActiveNodeSet[NId] = 0; } LabelCounts[0] = Net->GetNodes(); }
int GetMaxFlowIntEK (PNEANet &Net, const int &SrcNId, const int &SnkNId) { IAssert(Net->IsNode(SrcNId)); IAssert(Net->IsNode(SnkNId)); if (SrcNId == SnkNId) { return 0; } int CapIndex = Net->GetIntAttrIndE(CapAttrName); TIntV Flow(Net->GetMxEId()); // Initialize flow values to 0, and make sure capacities are nonnegative for (TNEANet::TEdgeI EI = Net->BegEI(); EI != Net->EndEI(); EI++) { IAssert(Net->GetIntAttrIndDatE(EI, CapIndex) >= 0); Flow[EI.GetId()] = 0; } // Return 0 if user attempts to flow from a node to itself. if (SrcNId == SnkNId) { return 0; } int MaxFlow = 0, MinAug, CurNId; while (true) { TIntV MidToSrcAugV; TIntV MidToSnkAugV; TIntQ FwdNodeQ; TIntQ BwdNodeQ; TIntH PredEdgeH; TIntH SuccEdgeH; MinAug = FindAugV(Net, CapIndex, Flow, FwdNodeQ, PredEdgeH, BwdNodeQ, SuccEdgeH, MidToSrcAugV, MidToSnkAugV, SrcNId, SnkNId); if (MinAug == 0) { break; } MaxFlow += MinAug; CurNId = SrcNId; for (int i = MidToSrcAugV.Len() - 1; i >= 0; i--) { int NextEId = MidToSrcAugV[i]; const TNEANet::TEdgeI &EI = Net->GetEI(NextEId); if (EI.GetSrcNId() == CurNId) { Flow[NextEId] += MinAug; CurNId = EI.GetDstNId(); } else { Flow[NextEId] -= MinAug; CurNId = EI.GetSrcNId(); } } for (int i = 0; i < MidToSnkAugV.Len(); i++) { int NextEId = MidToSnkAugV[i]; const TNEANet::TEdgeI &EI = Net->GetEI(NextEId); if (EI.GetSrcNId() == CurNId) { Flow[NextEId] += MinAug; CurNId = EI.GetDstNId(); } else { Flow[NextEId] -= MinAug; CurNId = EI.GetSrcNId(); } } } return MaxFlow; }