Esempio n. 1
0
        /// <summary>
        /// Adds a neighbor to the node.
        /// </summary>
        /// <param name="neighborToAdd"></param>
        /// <param name="connectionWeight"></param>
        public void AddNeighbor(WeightedUndirectedGraphNode <T> neighborToAdd, int connectionWeight)
        {
            //First check if the connection doesn't already exist.
            if (!m_Neighbors.ContainsValue(neighborToAdd.Data))
            {
                //Create a new connection object. This is used for the weighted graph.
                WeightedGraphConnection <T> newConnection = new WeightedGraphConnection <T>(neighborToAdd, connectionWeight);

                //Add the new connection to the list of connections.
                m_Neighbors.Add(newConnection, neighborToAdd.Data);

                //Tell the neighbor to add this connection to it's list of connections.
                //This is done because the graph is undirected.
                neighborToAdd.AddNeighbor(this, connectionWeight);
            }
            else
            {
                var myKey = m_Neighbors.FirstOrDefault(x => x.Value.Equals(neighborToAdd.Data)).Key;
                if (connectionWeight != myKey.ConnectionWeight)
                {
                    WeightedGraphConnection <T> newConnection = new WeightedGraphConnection <T>(neighborToAdd, connectionWeight);

                    m_Neighbors.Add(newConnection, neighborToAdd.Data);
                    neighborToAdd.OneWayAdd(this, connectionWeight);
                }
            }
        }
Esempio n. 2
0
        public WeightedUndirectedGraph(T initialNodeData)
        {
            Nodes = new Dictionary <T, WeightedUndirectedGraphNode <T> >();
            WeightedUndirectedGraphNode <T> initialNode = new WeightedUndirectedGraphNode <T>(initialNodeData);

            Nodes.Add(initialNodeData, initialNode);
            NumberOfComponents = 0;
        }
Esempio n. 3
0
        public void OneWayAdd(WeightedUndirectedGraphNode <T> neighborToAdd, int connectionWeight)
        {
            var myKey = m_Neighbors.FirstOrDefault(x => x.Value.Equals(neighborToAdd.Data)).Key;

            if (connectionWeight != myKey.ConnectionWeight)
            {
                //Create a new connection object. This is used for the weighted graph.
                WeightedGraphConnection <T> newConnection = new WeightedGraphConnection <T>(neighborToAdd, connectionWeight);

                //Add the new connection to the list of connections.
                m_Neighbors.Add(newConnection, neighborToAdd.Data);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Function for adding an edge.
        /// </summary>
        /// <param name="vertexOne"></param>
        /// <param name="vertexTwo"></param>
        /// <param name="connectionWeight"></param>
        public void AddEdge(T vertexOne, T vertexTwo, int connectionWeight)
        {
            //Check if vertex one and two are null.
            if (vertexOne == null)
            {
                throw new ArgumentNullException(nameof(vertexOne));
            }
            if (vertexTwo == null)
            {
                throw new ArgumentNullException(nameof(vertexTwo));
            }

            //Check if the nodes aren't already in the graph.
            bool v2Index = Nodes.ContainsKey(vertexTwo);
            bool v1Index = Nodes.ContainsKey(vertexOne);


            //The following segment guarantees that the two nodes are in the graph before making a connection between them.

            //Case: First node isn't in the graph.
            if (!v1Index)
            {
                //Create a new node that has the value of vertex one.
                WeightedUndirectedGraphNode <T> nodeOne = new WeightedUndirectedGraphNode <T>(vertexOne);

                //Add the node to the dictionary of the graph.
                Nodes.Add(vertexOne, nodeOne);
            }

            //Case: Second node isn't in the graph.
            if (!v2Index)
            {
                //Create a new node that has the value of vertex two.
                WeightedUndirectedGraphNode <T> nodeTwo = new WeightedUndirectedGraphNode <T>(vertexTwo);

                //Add the node to the dictionary of the graph.
                Nodes.Add(vertexTwo, nodeTwo);
            }

            //Finally establish the connection between the two nodes.
            Nodes[vertexTwo].AddNeighbor(Nodes[vertexOne], connectionWeight);
        }
Esempio n. 5
0
        //Algorithm for finding the shortest paths to all nodes from a given source node.
        public Dictionary <WeightedUndirectedGraphNode <T>, int> FindPath(T source)
        {
            //Get the source node.
            WeightedUndirectedGraphNode <T> sourceNode = Nodes[source];

            //Create dictionary that will hold the distances to all nodes from source node.
            //This dictionary also contains the distance to the source itself.
            Dictionary <WeightedUndirectedGraphNode <T>, int> distances = new Dictionary <WeightedUndirectedGraphNode <T>, int>();

            //Create priority queue that will always have the next smallest distance to at the front.
            PriorityQueue <WeightedUndirectedGraphNode <T> > distQueue = new PriorityQueue <WeightedUndirectedGraphNode <T> >(Nodes.Count);

            //As the previous loop set the distance from source to source to infinity
            //it now has to be changed to 0 as it should be

            //Set in the distance dictionary the distance to source as zero.
            distances[sourceNode] = 0;

            //Set the property Distance to this of the node itself as 0.
            //This will also reset any previous values of DistanceToThis.
            sourceNode.DistanceToThis = 0;

            //Add source to to priority queue.
            distQueue.Enqueue(sourceNode);

            //Initialize the the distances to nodes.
            foreach (var node in Nodes)
            {
                if (node.Value != sourceNode)
                {
                    //Set the DistanceToThis property of the current node to infinity.
                    node.Value.DistanceToThis = int.MaxValue;

                    //Set the value in the distances dictionary.
                    distances[node.Value] = int.MaxValue;

                    //Enqueue the current node in the priority queue.
                    distQueue.Enqueue(node.Value);
                }
            }

            //Finding the shortest distances can now begin.

            //The following while loop runs while the priority queue has element.
            //Once it is empty that means we have found the shortest path to all nodes.
            while (distQueue.Count() > 0)
            {
                //Get the value of the path to the node to which the distance is the shortest.
                int currentMin = distQueue.Front().DistanceToThis;

                //The the actual node.
                WeightedUndirectedGraphNode <T> currentVertex = distQueue.Front();

                //Remove that node from the priority queue as it has now been visited.
                distQueue.Dequeue();

                //Now each neighbor of the current node is visited.
                foreach (var neighbor in currentVertex.GetNeighbors())
                {
                    //Calculate an alternative distance to current neighbor.
                    //The formula is as follows:
                    //altDistance = (cost of the path to the current node) + (cost of the path to neighbor node);
                    int alternativeDist = currentMin + neighbor.Key.ConnectionWeight;

                    //Now a check must be performed to determine if a better route to current neighbor has been found.
                    //That is why we check the value in the distances dictionary.
                    if (alternativeDist < distances[neighbor.Key.ConnectionNeighbor])
                    {
                        //First change the value in the distances dictionary.
                        distances[neighbor.Key.ConnectionNeighbor] = alternativeDist;

                        //Change the value of DistanceToThis of the neighbor node.
                        neighbor.Key.ConnectionNeighbor.DistanceToThis = alternativeDist;

                        //Resort the distance queue,
                        //as the values have now changed and a smaller value is in the queue.
                        distQueue.Sort();
                    }

                    //Repeat the steps above for each neighbor
                }

                //Repeat the steps above for each element in the priority queue.
            }

            //Return the final dictionary of distances.
            return(distances);
        }
Esempio n. 6
0
 public WeightedGraphConnection(WeightedUndirectedGraphNode <T> connectionNeighbor, int weight)
 {
     ConnectionNeighbor = connectionNeighbor;
     ConnectionWeight   = weight;
 }