Skip to content
Snippets Groups Projects
Commit e73b37a6 authored by Timon Römer's avatar Timon Römer
Browse files

Adds Logo and DFS

parent c98dcd4a
No related branches found
No related tags found
No related merge requests found
FlowForge
\ No newline at end of file
......@@ -13,7 +13,7 @@ public class FlowEdge : Edge<FlowNode>
{
IsBackwards = false;
MaxFlow = maxFlow;
Residual = 0;
Residual = maxFlow;
}
public override string ToString()
......
......@@ -5,6 +5,7 @@
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ApplicationIcon>./icons/logo.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
......
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABidirectionalGraph_002Ecs_002Fl_003AC_0021_003FUsers_003Fmp455017_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fa8e81c4118651b5932b855cf99986877c2c24685d864158c9053e4f62e213fce_003FBidirectionalGraph_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDictionary_00602_002Ecs_002Fl_003AC_0021_003FUsers_003Fmp455017_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb756d57b94fb4ab9aa95a9b2a97fce1fa24ea0_003Fa1_003F8276683c_003FIDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
namespace FlowForge;
......@@ -31,20 +32,31 @@ public class FordFulkersonAlgorithm
edge.Residual = edge.MaxFlow;
}
Console.WriteLine("Start of Ford-Fulkerson Algorithm...");
// execute as long as there is an augmenting path
while (FindAugmentingPath(source, target, pathFlow))
while (FindAugmentingPathBfs(source, target, pathFlow))
{
Console.WriteLine("Augmenting Path found:");
foreach (var edge in pathFlow.Keys)
{
Console.WriteLine($"{edge.Source.Id} -> {edge.Target.Id}, Residual Capacity: {pathFlow[edge]}");
}
// calculate bottleneck in augmenting path
double pathMinFlow = double.MaxValue;
foreach (var edge in pathFlow.Keys)
{
pathMinFlow = Math.Min(pathMinFlow, pathFlow[edge]);
}
Console.WriteLine($"Bottleneck (minimum flow in path): {pathMinFlow}");
// add flow along the augmenting path
foreach (var edge in pathFlow.Keys)
{
edge.Residual -= pathMinFlow;
Console.WriteLine($"Updating forward edge {edge.Source.Id} -> {edge.Target.Id}, New Residual: {edge.Residual}");
// check if backwards edge exists
FlowEdge? reverseEdge;
......@@ -57,21 +69,32 @@ public class FordFulkersonAlgorithm
reverseEdge.IsBackwards = true;
_flowGraph.Graph.AddEdge(reverseEdge);
Console.WriteLine($"Creating reverse edge {reverseEdge.Source.Id} -> {reverseEdge.Target.Id}");
}
if (reverseEdge != null) reverseEdge.Residual += pathMinFlow;
if (reverseEdge != null)
{
reverseEdge.Residual += pathMinFlow;
Console.WriteLine($"Updating reverse edge {reverseEdge.Source.Id} -> {reverseEdge.Target.Id}, New Residual: {reverseEdge.Residual}");
}
}
// add to total flow
maxFlow += pathMinFlow;
Console.WriteLine($"Current max flow: {maxFlow}\n");
}
Console.WriteLine("No Augmenting Path found anymore!\n");
Console.WriteLine($"Max flow found: {maxFlow}\n");
// return maximum flow after no augmenting paths were found anymore
return maxFlow;
}
public bool FindAugmentingPath(FlowNode source, FlowNode target, Dictionary<FlowEdge, double> pathFlow)
public bool FindAugmentingPathBfs(FlowNode source, FlowNode target, Dictionary<FlowEdge, double> pathFlow)
{
// parent map to walk back path
var parentMap = new Dictionary<FlowNode, FlowEdge>();
......@@ -87,10 +110,12 @@ public class FordFulkersonAlgorithm
{
FlowNode current = queue.Dequeue();
var outEdges = _flowGraph.Graph.OutEdges(current);
var outEdges = _flowGraph.Graph.OutEdges(current).ToList();
var sortedOutEdges = outEdges.OrderBy(edge => edge.Target.Id);
// go through all outgoing edges
foreach (FlowEdge currentEdge in outEdges)
foreach (FlowEdge currentEdge in sortedOutEdges)
{
if (currentEdge.Residual <= 0 || visited.Contains(currentEdge.Target)) continue;
......@@ -121,5 +146,58 @@ public class FordFulkersonAlgorithm
return false;
}
public bool FindAugmentingPathDfs(FlowNode source, FlowNode target, Dictionary<FlowEdge, double> pathFlow)
{
// parent map to walk back path
var parentMap = new Dictionary<FlowNode, FlowEdge>();
// queue for breath first search
var stack = new Stack<FlowNode>();
stack.Push(source);
// map to store visited nodes
var visited = new HashSet<FlowNode> { source };
while (stack.Count > 0)
{
FlowNode current = stack.Pop();
var outEdges = _flowGraph.Graph.OutEdges(current).ToList();
var sortedOutEdges = outEdges.OrderBy(edge => edge.Target.Id);
// go through all outgoing edges
foreach (FlowEdge currentEdge in sortedOutEdges)
{
if (currentEdge.Residual <= 0 || visited.Contains(currentEdge.Target)) continue;
visited.Add(currentEdge.Target);
parentMap.Add(currentEdge.Target, currentEdge);
// if we reached the target node
if (currentEdge.Target.Equals(target))
{
FlowNode currentNode = target;
pathFlow.Clear();
while (currentNode != source)
{
FlowEdge pathEdge = parentMap[currentNode];
pathFlow.Add(pathEdge, pathEdge.Residual);
currentNode = pathEdge.Source;
}
// return the augmenting path found
return true;
}
// search further
stack.Push(currentEdge.Target);
}
}
return false;
}
}
<Window x:Class="FlowForge.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FlowForge" Height="600" Width="800">
Title="Flow-Forge" Height="600" Width="800">
<Grid x:Name="MainGrid">
<!-- Define two rows: one fixed height for the button and one for the graph viewer -->
<Grid.RowDefinitions>
......@@ -22,12 +22,23 @@
Click="InitializeGraphButton_Click"/>
<!-- Second Button in the first row -->
<Button x:Name="RunAlgorithmButton"
<Button x:Name="RunFordFulkersonButton"
Content="Run Ford-Fulkerson"
Width="150"
Height="40"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="350,10,0,10"
Grid.Row="0"
Click="RunAlgorithmButton_Click"/>
<!-- Second Button in the first row -->
<Button x:Name="RunEdmondsKarpButton"
Content="Run Edmonds–Karp"
Width="150"
Height="40"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="180,10,0,10"
Grid.Row="0"
Click="RunAlgorithmButton_Click"/>
......
......@@ -129,7 +129,6 @@ namespace FlowForge
double maxFlow = _fordFulkerson.Run("1", "4");
Console.WriteLine($"Maximaler Fluss von Quelle zu Senke: {maxFlow}");
MessageBox.Show($"Maximaler Fluss von Quelle zu Senke: {maxFlow}");
......
icons/logo.ico

27.2 KiB

icons/logo.png

45.5 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment