From e705305836980e906f7efeb0212053638310d6ce Mon Sep 17 00:00:00 2001 From: oursimon Date: Tue, 6 Jan 2026 11:00:34 +0100 Subject: [PATCH 1/2] deleted function for incomming flow and som renameing --- README.md | 13 ++++----- examples/main.go | 13 ++------- flowmo.go | 26 ++---------------- flowmo_test.go | 31 ++++----------------- internal/network/network.go | 27 +----------------- internal/network/network_test.go | 47 ++++---------------------------- 6 files changed, 24 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index 62a0ded..2f8f916 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ func main() { fmt.Printf("Maximum flow: %d\n", maxFlow) - // Query node capacities - incoming, _ := f.IncomingCapacityByNode("sink") - fmt.Printf("Incoming capacity to sink: %d\n", incoming) + // Query node flow + flow, _ := f.FlowByNode("a") + fmt.Printf("Outgoing flow from a: %d\n", flow) } ``` @@ -54,11 +54,8 @@ Adds a directed edge from `from` to `to` with the specified capacity. Nodes are ### `MaxFlow(source, sink Node) (int, error)` Computes the maximum flow from the source node to the sink node using Dinic's algorithm. -### `IncomingCapacityByNode(node Node) (int, error)` -Returns the total incoming flow capacity for the specified node. - -### `OutgoingCapacityByNode(node Node) (int, error)` -Returns the total outgoing flow capacity for the specified node. +### `FlowByNode(node Node) (int, error)` +Returns the total outgoing flow (used capacity) from the specified node. This method should be called after MaxFlow has been computed. ## License diff --git a/examples/main.go b/examples/main.go index b053a13..b8c973f 100644 --- a/examples/main.go +++ b/examples/main.go @@ -25,18 +25,11 @@ func main() { fmt.Printf("Max flow from 'a' to 'b': %d\n", flow) - // Query incoming and outgoing capacities for specific nodes. - incoming, err := f.IncomingCapacityByNode("b") + // Query the outgoing flow for specific nodes. + outgoing, err := f.FlowByNode("c") if err != nil { panic(err) } - fmt.Printf("Incoming capacity to 'b': %d\n", incoming) - - outgoing, err := f.OutgoingCapacityByNode("c") - if err != nil { - panic(err) - } - - fmt.Printf("Outgoing capacity from 'c': %d\n", outgoing) + fmt.Printf("Outgoing flow from 'c': %d\n", outgoing) } diff --git a/flowmo.go b/flowmo.go index d69854b..a57d622 100644 --- a/flowmo.go +++ b/flowmo.go @@ -75,27 +75,7 @@ func (f *Flowmo) MaxFlow(source, sink Node) (int, error) { return f.network.MaxFlow(sourceIndex, sinkIndex) } -// IncomingCapacityByNode returns the total incoming flow (used capacity) to the specified node. -// This represents the sum of all flow that has been pushed into the node across all incoming edges. -// This method should be called after MaxFlow has been computed. -// -// Returns the total incoming flow and nil error on success. -// Returns -1 and an error if: -// - Node does not exist (ErrNotFound) -func (f *Flowmo) IncomingCapacityByNode(node Node) (int, error) { - idx, exists := f.indexByNode[node] - if !exists { - return -1, fmt.Errorf( - "node %q: %w", - node, - flowmoerrors.ErrNotFound, - ) - } - - return f.network.IncomingFlowByNode(idx) -} - -// OutgoingCapacityByNode returns the total outgoing flow +// FlowByNode returns the total outgoing flow // (used capacity) from the specified node. // This represents the sum of all flow that has been pushed out of // the node across all outgoing edges. @@ -104,7 +84,7 @@ func (f *Flowmo) IncomingCapacityByNode(node Node) (int, error) { // Returns the total outgoing flow and nil error on success. // Returns -1 and an error if: // - Node does not exist (ErrNotFound) -func (f *Flowmo) OutgoingCapacityByNode(node Node) (int, error) { +func (f *Flowmo) FlowByNode(node Node) (int, error) { idx, exists := f.indexByNode[node] if !exists { return -1, fmt.Errorf( @@ -114,7 +94,7 @@ func (f *Flowmo) OutgoingCapacityByNode(node Node) (int, error) { ) } - return f.network.OutgoingFlowByNode(idx) + return f.network.FlowByNode(idx) } func (f *Flowmo) addNode(node Node) (int, error) { diff --git a/flowmo_test.go b/flowmo_test.go index 1ac917a..ebe35ce 100644 --- a/flowmo_test.go +++ b/flowmo_test.go @@ -106,21 +106,12 @@ func Test_MaxFlow_sinkNotFound(t *testing.T) { assert.ErrorIs(t, err, flowmoerrors.ErrNotFound) } -func Test_IncomingCapacityByNode_nodeNotFound(t *testing.T) { +func Test_OutgoingFlowByNode_nodeNotFound(t *testing.T) { f := New() _ = f.AddEdge("a", "b", 10) - _, err := f.IncomingCapacityByNode("x") - assert.ErrorIs(t, err, flowmoerrors.ErrNotFound) -} - -func Test_OutgoingCapacityByNode_nodeNotFound(t *testing.T) { - f := New() - - _ = f.AddEdge("a", "b", 10) - - _, err := f.OutgoingCapacityByNode("x") + _, err := f.FlowByNode("x") assert.ErrorIs(t, err, flowmoerrors.ErrNotFound) } @@ -144,23 +135,13 @@ func Test_CompleteWorkflow(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 25, maxFlow) - // Verify incoming capacities - incomingB, _ := f.IncomingCapacityByNode("b") - assert.Equal(t, 15, incomingB) - - incomingC, _ := f.IncomingCapacityByNode("c") - assert.Equal(t, 15, incomingC) - - incomingD, _ := f.IncomingCapacityByNode("d") - assert.Equal(t, 25, incomingD) - - // Verify outgoing capacities - outgoingA, _ := f.OutgoingCapacityByNode("a") + // Verify flow + outgoingA, _ := f.FlowByNode("a") assert.Equal(t, 25, outgoingA) - outgoingB, _ := f.OutgoingCapacityByNode("b") + outgoingB, _ := f.FlowByNode("b") assert.Equal(t, 15, outgoingB) - outgoingC, _ := f.OutgoingCapacityByNode("c") + outgoingC, _ := f.FlowByNode("c") assert.Equal(t, 15, outgoingC) } diff --git a/internal/network/network.go b/internal/network/network.go index f44ca94..64c1f71 100644 --- a/internal/network/network.go +++ b/internal/network/network.go @@ -58,32 +58,7 @@ func (net *Network) MaxFlow(source, sink int) (int, error) { return maxFlow(net, source, sink) } -// nolint:gocyclo -func (net *Network) IncomingFlowByNode(node int) (int, error) { - invalidNode := node < 0 || node >= len(net.adj) - if invalidNode { - return -1, fmt.Errorf( - "node %d: %w", - node, - flowmoerrors.ErrInvalidArgument, - ) - } - - in := 0 - for _, edges := range net.adj { - for _, e := range edges { - if e.to != node || e.isResidual() { - continue - } - - in += e.initialCapacity - e.capacity - } - } - - return in, nil -} - -func (net *Network) OutgoingFlowByNode(node int) (int, error) { +func (net *Network) FlowByNode(node int) (int, error) { invalidNode := node < 0 || node >= len(net.adj) if invalidNode { return -1, fmt.Errorf( diff --git a/internal/network/network_test.go b/internal/network/network_test.go index 4055da1..82f1715 100644 --- a/internal/network/network_test.go +++ b/internal/network/network_test.go @@ -66,7 +66,7 @@ func Test_AddEdge_happyCase(t *testing.T) { assert.Equal(t, 0, residualEdge.initialCapacity) } -func Test_IncomingFlowByNode_beforeMaxFlow_shouldReturnZero(t *testing.T) { +func Test_FlowByNode_beforeMaxFlow_shouldReturnZero(t *testing.T) { net := New() from := net.AddNode() to := net.AddNode() @@ -74,37 +74,11 @@ func Test_IncomingFlowByNode_beforeMaxFlow_shouldReturnZero(t *testing.T) { _ = net.AddEdge(from, to, capacity) - incoming, _ := net.IncomingFlowByNode(to) - assert.Equal(t, 0, incoming) -} - -func Test_IncomingFlowByNode_afterMaxFlow_shouldReturnFlow(t *testing.T) { - net := New() - from := net.AddNode() - to := net.AddNode() - capacity := 10 - - _ = net.AddEdge(from, to, capacity) - - _, _ = net.MaxFlow(from, to) - - incoming, _ := net.IncomingFlowByNode(to) - assert.Equal(t, capacity, incoming) -} - -func Test_OutgoingFlowByNode_beforeMaxFlow_shouldReturnZero(t *testing.T) { - net := New() - from := net.AddNode() - to := net.AddNode() - capacity := 10 - - _ = net.AddEdge(from, to, capacity) - - outgoing, _ := net.OutgoingFlowByNode(from) + outgoing, _ := net.FlowByNode(from) assert.Equal(t, 0, outgoing) } -func Test_OutgoingFlowByNode_afterMaxFlow_shouldReturnFlow(t *testing.T) { +func Test_FlowByNode_afterMaxFlow_shouldReturnFlow(t *testing.T) { net := New() from := net.AddNode() to := net.AddNode() @@ -114,7 +88,7 @@ func Test_OutgoingFlowByNode_afterMaxFlow_shouldReturnFlow(t *testing.T) { _, _ = net.MaxFlow(from, to) - outgoing, _ := net.OutgoingFlowByNode(from) + outgoing, _ := net.FlowByNode(from) assert.Equal(t, capacity, outgoing) } @@ -132,20 +106,11 @@ func Test_AddEdge_selfLoop_shouldWork(t *testing.T) { assert.Equal(t, 0, flow) } -func Test_IncomingFlowByNode_invalidNode_shouldReturnError(t *testing.T) { - net := New() - _ = net.AddNode() - - incoming, err := net.IncomingFlowByNode(5) - assert.ErrorIs(t, err, flowmoerrors.ErrInvalidArgument) - assert.Equal(t, -1, incoming) -} - -func Test_OutgoingFlowByNode_invalidNode_shouldReturnError(t *testing.T) { +func Test_FlowByNode_invalidNode_shouldReturnError(t *testing.T) { net := New() _ = net.AddNode() - outgoing, err := net.OutgoingFlowByNode(5) + outgoing, err := net.FlowByNode(5) assert.ErrorIs(t, err, flowmoerrors.ErrInvalidArgument) assert.Equal(t, -1, outgoing) } From f2dd1894f03eb3539290d106ca4047fa6918afec Mon Sep 17 00:00:00 2001 From: oursimon Date: Tue, 6 Jan 2026 11:04:21 +0100 Subject: [PATCH 2/2] resolved self-review comments --- flowmo_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flowmo_test.go b/flowmo_test.go index ebe35ce..955ce0b 100644 --- a/flowmo_test.go +++ b/flowmo_test.go @@ -106,7 +106,7 @@ func Test_MaxFlow_sinkNotFound(t *testing.T) { assert.ErrorIs(t, err, flowmoerrors.ErrNotFound) } -func Test_OutgoingFlowByNode_nodeNotFound(t *testing.T) { +func Test_FlowByNode_nodeNotFound(t *testing.T) { f := New() _ = f.AddEdge("a", "b", 10)