Exemplo n.º 1
0
    Frustrum GetFrustrum(Vector2 highStart, Vector2 lowStart, NodeEdge nextDoor)
    {
        Vector2 lowEnd;
        Vector2 highEnd;
        var     requiredIndent = DoorWidthRequiredToPassFromPoint(lowStart, nextDoor); //it's ok to calculate just for 1 point with simplified function..for now

        if (requiredIndent > (nextDoor.P1 - nextDoor.P2).magnitude / 2)
        {
            return(null);
        }

        if (nextDoor.P1.x == nextDoor.P2.x)
        {
            lowEnd  = nextDoor.P1.y > nextDoor.P2.y ? nextDoor.P2 + Vector2.up * requiredIndent : nextDoor.P1 + Vector2.up * requiredIndent;
            highEnd = nextDoor.P1.y > nextDoor.P2.y ? nextDoor.P1 - Vector2.up * requiredIndent : nextDoor.P2 - Vector2.up * requiredIndent;
            return(new Frustrum {
                highEnd = highEnd, lowEnd = lowEnd, highStart = highStart, lowStart = lowStart
            });
        }
        else if (nextDoor.P1.y == nextDoor.P2.y)
        {
            lowEnd  = nextDoor.P1.x > nextDoor.P2.x ? nextDoor.P2 + Vector2.right * requiredIndent : nextDoor.P1 + Vector2.right * requiredIndent;
            highEnd = nextDoor.P1.x > nextDoor.P2.x ? nextDoor.P1 - Vector2.right * requiredIndent : nextDoor.P2 - Vector2.right * requiredIndent;
            return(new Frustrum {
                highEnd = highEnd, lowEnd = lowEnd, highStart = highStart, lowStart = lowStart
            });
        }
        else
        {
            Debug.LogError("Inconsistent door: " + nextDoor);
            return(null);
        }
    }
Exemplo n.º 2
0
    private Vector2 ChooseCorner(Vector2 start, NodeEdge nodeEdge, float unitRadius, Vector2 end)
    {
        Vector2 corner;
        var     nextNodeEdge    = _nodeEdges[_nodeEdges.IndexOf(nodeEdge) + 1];
        var     middleEdgePoint = new Vector2((nextNodeEdge.P1.x + nextNodeEdge.P2.x) / 2,
                                              (nextNodeEdge.P1.y + nextNodeEdge.P2.y) / 2);
        var firstSectorSide    = nodeEdge.P1 + ConstructNormalVector(nodeEdge.P1 - start, unitRadius);
        var secondSectorSide   = nodeEdge.P2 + ConstructNormalVector(nodeEdge.P2 - start, unitRadius);
        var sectorDot          = Vector2.Dot((firstSectorSide - start).normalized, (secondSectorSide - start).normalized);
        var secondSidePointDot =
            Vector2.Dot((secondSectorSide - start).normalized, (middleEdgePoint - start).normalized);

        if (secondSidePointDot < sectorDot)
        {
            corner = nodeEdge.P1 + ConstructNormalVector(nodeEdge.P1 - start, unitRadius);
        }
        else
        {
            corner = nodeEdge.P2 - ConstructNormalVector(nodeEdge.P2 - start, unitRadius);
        }
        if (TryFindStraightPathToEnd(corner, end, nodeEdge, unitRadius, out Vector2 betterCorner))
        {
            return(betterCorner);
        }
        return(corner);
    }
Exemplo n.º 3
0
    /*
     */
    private void RemoveEdgeNode(NodeGraph node, int v)
    {
        NodeEdge aux = node.edge;

        if (aux != null)
        {
            if (aux.nodeDestination.nodeValue == v)
            {
                node.edge = aux.nextEdge;
            }

            else
            {
                if (aux.nextEdge != null && aux.nextEdge.nodeDestination.nodeValue != v)
                {
                    aux = aux.nextEdge;
                }

                if (aux.nextEdge != null)
                {
                    aux.nextEdge = aux.nextEdge.nextEdge;
                }
            }
        }
    }
Exemplo n.º 4
0
        private bool BellmanFordIteration()
        {
            var hCostsImproved = false;

            // Für alle Kanten( Für jeden Knoten -> Alle möglichen Kanten des Knotens)
            // Für jeden vorhandenen Knoten..
            foreach (var hCurrentNode in FNodeDictionary.Values)
            {
                // Für jede ausgehende Kante..
                foreach (var hCurrentNodeEdge in hCurrentNode.NeighbourEdges)
                {
                    var hNeighborNode      = hCurrentNodeEdge.Node;
                    var hEdgeToNeighorNode = hCurrentNodeEdge.Edge;
                    var hCostToNeighbor    = FCostDictionary[hCurrentNode] + hEdgeToNeighorNode.GetWeightValue();

                    // Prüfen ob ich den Nachbarn jetzt günstiger erreichen kann
                    if (hCostToNeighbor < FCostDictionary[hNeighborNode])
                    {
                        FCostDictionary[hNeighborNode] = hCostToNeighbor;
                        FParentNodeEdge[hNeighborNode] = new NodeEdge(hCurrentNode, hEdgeToNeighorNode);
                        hCostsImproved = true;
                    }
                }
            }

            return(hCostsImproved);
        }
        public Renderer(IForceDirected iForceDirected) : base(iForceDirected)
        {
            Transform  graphHolder = GameObject.FindWithTag("Graph").transform;
            GameObject nodePrefab  = Resources.Load("Node") as GameObject;
            GameObject edgePrefab  = Resources.Load("Edge") as GameObject;

            foreach (Node n in iForceDirected.graph.nodes)
            {
                //GameObject nodeObj = Instantiate(Resources.Load("Node") as GameObject, new Vector3(n.Data.initialPostion.x, n.Data.initialPostion.y, n.Data.initialPostion.z), Quaternion.identity, graphHolder);
                GameObject nodeObj = Instantiate(nodePrefab, graphHolder);
                nodeObj.name = n.Data.label;

                // Passing the value of the underlying node to the 'Interface' between the GameObject and the actual FDG object

                var na = nodeObj.GetComponent <NodeAssociation>();
                na._associatedNode     = n;
                n.associatedNodeObject = na;
                n.Data.gameObject      = nodeObj;
                gameObjects.Add(nodeObj);
            }

            foreach (Edge e in iForceDirected.graph.edges)
            {
                GameObject edgeObj = Instantiate(edgePrefab, graphHolder);
                edgeObj.name = e.Data.label;
                NodeEdge nodeEdge = edgeObj.GetComponent <NodeEdge>();
                nodeEdge.node1 = e.Source.Data.gameObject;
                nodeEdge.node2 = e.Target.Data.gameObject;
                gameObjects.Add(edgeObj);
            }
        }
        // ----------------------------------------------------------------------
        // Returns true if the distance to parent is less then twice the port size.
        public bool IsNearParentEdge(iCS_EditorObject port, NodeEdge edge = NodeEdge.None)
        {
            var parent = port.ParentNode;
            var pos    = port.GlobalPosition;

            return(parent.IsPositionOnEdge(pos, (edge != NodeEdge.None ? edge : port.Edge)));
        }
        // ----------------------------------------------------------------------
        public static bool IsPositionOnRectEdge(Vector2 pos, Rect r, NodeEdge edge)
        {
            float maxDistance = iCS_EditorConfig.PortDiameter;
            float distance    = 2f * maxDistance;
            float leftX       = r.xMin;
            float rightX      = r.xMax;
            float topY        = r.yMin;
            float bottomY     = r.yMax;

            switch (edge)
            {
            case NodeEdge.Top:
                distance = Math3D.DistanceFromHorizontalLineSegment(pos, leftX, rightX, topY);
                break;

            case NodeEdge.Bottom:
                distance = Math3D.DistanceFromHorizontalLineSegment(pos, leftX, rightX, bottomY);
                break;

            case NodeEdge.Left:
                distance = Math3D.DistanceFromVerticalLineSegment(pos, topY, bottomY, leftX);
                break;

            case NodeEdge.Right:
                distance = Math3D.DistanceFromVerticalLineSegment(pos, topY, bottomY, rightX);
                break;
            }
            return(distance <= maxDistance);
        }
    // Create an edge and returns the length
    private float CreateEdge(Vertex <Node> node1, Vertex <Node> node2)
    {
        NodeEdge edge   = Instantiate(_NodeEdgePrefab);
        float    length = edge.Init(node1, node2);

        _edges.Add(edge);

        _graph.CreateDirectedEdge(node1, node2, length);

        return(length);
    }
Exemplo n.º 9
0
    private bool CanStraightToEnd(Vector3 start, Vector2 end, NodeEdge edge, float unitRadius)
    {
        for (int i = _nodeEdges.Count - 1; i >= _nodeEdges.IndexOf(edge); i--)
        {
            if (!IsInSector(end, _nodeEdges[i], start, unitRadius))
            {
                return(false);
            }
        }

        return(true);
    }
Exemplo n.º 10
0
    /*
     */
    public bool HasEdge(int v1, int v2)
    {
        NodeGraph n1  = VertexToNode(v1);
        NodeEdge  aux = n1.edge;

        if (aux != null && aux.nodeDestination.nodeValue != v2)
        {
            aux = aux.nextEdge;
        }

        return(aux != null);
    }
Exemplo n.º 11
0
    /*
     */
    public int WeightEdge(int v1, int v2)
    {
        NodeGraph n1  = VertexToNode(v1);
        NodeEdge  aux = n1.edge;

        if (aux.nodeDestination.nodeValue != v2)
        {
            aux = aux.nextEdge;
        }

        return(aux.edgeWeight);
    }
Exemplo n.º 12
0
    /*
     */
    public void AddEdge(int id, int v1, int v2, int weight)
    {
        NodeGraph n1 = VertexToNode(v1);
        NodeGraph n2 = VertexToNode(v2);

        NodeEdge aux = new NodeEdge();

        aux.id              = id;
        aux.edgeWeight      = weight;
        aux.nodeDestination = n2;
        aux.nextEdge        = n1.edge;
        n1.edge             = aux;
    }
Exemplo n.º 13
0
        public void CreateEdge(IGraphicsCompositorLinkViewModel link)
        {
            var sourceVertex = GetVertex(link.SourceSlot.Block);
            var targetVertex = GetVertex(link.TargetSlot.Block);
            var nodeEdge     = new NodeEdge(sourceVertex, targetVertex)
            {
                SourceSlot = link.SourceSlot,
                TargetSlot = link.TargetSlot
            };

            edgeMapping.Add(link, nodeEdge);
            linkMapping.Add(nodeEdge, link);
            edges.Add(nodeEdge);
        }
Exemplo n.º 14
0
    float DoorWidthRequiredToPassFromPoint(Vector2 v, NodeEdge door)
    {
        float ratio = 1;

        if (door.P1.y == door.P2.y)
        {
            ratio = Mathf.Tan(Mathf.Deg2Rad * Vector2.Angle(Vector2.up, (door.P1 + door.P2) / 2 - v));
        }
        else if (door.P1.x == door.P2.x)
        {
            ratio = Mathf.Tan(Mathf.Deg2Rad * Vector2.Angle(Vector2.right, (door.P1 + door.P2) / 2 - v));
        }
        return(radius * Mathf.Abs(ratio) + radius);
    }
Exemplo n.º 15
0
    private bool IsInSector(Vector2 start, NodeEdge nodeEdge, Vector2 point, float unitRadius)
    {
        var firstSectorSide    = nodeEdge.P1 - start + ConstructNormalVector(nodeEdge.P1 - start, unitRadius);
        var secondSectorSide   = nodeEdge.P2 - start + ConstructNormalVector(nodeEdge.P2 - start, unitRadius);
        var sectorDot          = Vector2.Dot((firstSectorSide).normalized, (secondSectorSide).normalized);
        var firstSidePointDot  = Vector2.Dot((firstSectorSide).normalized, (point - start).normalized);
        var secondSidePointDot = Vector2.Dot((secondSectorSide).normalized, (point - start).normalized);

        if (firstSidePointDot < sectorDot || secondSidePointDot < sectorDot)
        {
            return(false);
        }
        return(true);
    }
Exemplo n.º 16
0
    public void SetEdges(GraphView view)
    {
        Edges = view.edges.ToList().Where(x => {
            return(x.input.node != null && x.output.node != null);
        }).Select(x => {
            var inGuid  = x.input.node.viewDataKey;
            var outGuid = x.output.node.viewDataKey;
            var edge    = new NodeEdge {
                fromGuid     = outGuid,
                fromPortName = x.output.portName,
                toGuid       = inGuid,
                toPortName   = x.input.portName
            };

            return(edge);
        }).ToList();
    }
Exemplo n.º 17
0
        private DialogueNode GetNodeAndEdgeNearPoint(Vector2 point)
        {
            _resizeEdge = NodeEdge.None;
            point      += _selectedDialogue.EditorScrollPosition;
            foreach (DialogueNode node in _selectedDialogue.DialogueNodes)
            {
                if (Mathf.Abs(node.PositionRect.yMin - point.y) <= _allowedResizeDistance)
                {
                    if (point.x > node.PositionRect.xMin && point.x < node.PositionRect.xMax)
                    {
                        _resizeEdge = NodeEdge.Top;
                        return(node);
                    }
                }

                if (Mathf.Abs(node.PositionRect.xMax - point.x) <= _allowedResizeDistance)
                {
                    if (point.y > node.PositionRect.yMin && point.y < node.PositionRect.yMax)
                    {
                        _resizeEdge = NodeEdge.Right;
                        return(node);
                    }
                }

                if (Mathf.Abs(node.PositionRect.yMax - point.y) <= _allowedResizeDistance)
                {
                    if (point.x > node.PositionRect.xMin && point.x < node.PositionRect.xMax)
                    {
                        _resizeEdge = NodeEdge.Bottom;
                        return(node);
                    }
                }

                if (Mathf.Abs(node.PositionRect.xMin - point.x) <= _allowedResizeDistance)
                {
                    if (point.y > node.PositionRect.yMin && point.y < node.PositionRect.yMax)
                    {
                        _resizeEdge = NodeEdge.Left;
                        return(node);
                    }
                }
            }

            return(null);
        }
Exemplo n.º 18
0
    private bool TryFindStraightPathToEnd(Vector2 corner, Vector2 end, NodeEdge edge, float unitRadius,
                                          out Vector2 betterCorner)
    {
        betterCorner = Vector2.zero;
        var   minLength = corner.magnitude;
        float accuracy  = unitRadius;

        corner.Normalize();
        for (int i = 0; edge.Node2.Rect.Contains(corner * (minLength + i * accuracy)); i++)
        {
            Vector2 nextCorner = corner * (minLength + i * accuracy);
            if (CanStraightToEnd(nextCorner, end, _nodeEdges[_nodeEdges.IndexOf(edge) + 1], unitRadius))
            {
                betterCorner = nextCorner;
                return(true);
            }
        }

        return(false);
    }
Exemplo n.º 19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        protected void OnLinkSelected(object sender, LinkSelectedEventArgs args)
        {
            // Travel up the visual tree to find the edge
            FrameworkElement       element = args.Link;
            NodeEdgeControl        control = element.FindVisualParentOfType <NodeEdgeControl>();
            NodeEdge               edge    = control.Edge as NodeEdge;
            Tuple <object, object> link    = element.DataContext as Tuple <object, object>;

            LinkInfo info = selected_links_.FirstOrDefault(x => (x.Link == link) && (x.Edge == edge));

            if (info == null)
            {
                ClearSelection();
                info = new LinkInfo()
                {
                    Edge = edge, Link = link
                };
                SelectLink(control, info, false);
            }
        }
Exemplo n.º 20
0
    private void Awake()
    {
        var n1 = new NodeRect {
            Rect = new Rect(0, 0, 2, 2)
        };
        var n2 = new NodeRect {
            Rect = new Rect(1, 2, 2, 2)
        };
        var n3 = new NodeRect {
            Rect = new Rect(3, 1, 1, 2)
        };
        var n4 = new NodeRect {
            Rect = new Rect(4, 1, 2, 2)
        };

        _rects = new List <NodeRect> {
            n1, n2, n3, n4
        };

        var e1 = new NodeEdge {
            Node1 = n1, Node2 = n2, P1 = new Vector2(1, 2), P2 = new Vector2(2, 2)
        };
        var e2 = new NodeEdge {
            Node1 = n2, Node2 = n3, P1 = new Vector2(3, 2), P2 = new Vector2(3, 3)
        };
        var e3 = new NodeEdge {
            Node1 = n3, Node2 = n4, P1 = new Vector2(4, 1), P2 = new Vector2(4, 3)
        };

        var p1 = new Vector2(0, 0);
        var p2 = new Vector2(6, 2);

        _nodeEdges = new List <NodeEdge> {
            e1, e2, e3
        };
        _path = CreatePath(p1, p2, _nodeEdges, 0.1f);
    }
Exemplo n.º 21
0
        /// <summary>
        /// Calculate the adjusted walking time for this route, taking congestion into account.
        /// </summary>
        /// <param name="allStudentRoutes">A collection of all student routes today.</param>
        /// <param name="startingTime">The starting time of this route.</param>
        /// <exception cref="InvalidOperationException"></exception>
        /// <exception cref="AggregateException"></exception>
        public void CalculateAdjustedWalkingTime(StudentRoute[] allStudentRoutes, TimeSpan startingTime)
        {
            double distanceSoFar            = 0;
            double totalAdjustedWalkingTime = 0;

            List <Dictionary <(string entryId, string exitId), int> > allCongestionValues = new List <Dictionary <(string entryId, string exitId), int> >(RouteNodes.Count);

            for (int i = 0; i < RouteNodes.Count - 1; i++)
            {
                // Increment the distance walked so far.
                if (RouteNodes[i].Type == NodeType.Corridor && RouteNodes[i + 1].Type == NodeType.Corridor)
                {
                    distanceSoFar += RouteNodes[i].DistanceInMetersTo(RouteNodes[i + 1]);
                }
                else
                {
                    distanceSoFar += SharedFunctions.NonCorridorDistance;
                }

                // Calculate the time spent getting to this point and get the current time of day from that.
                TimeSpan currentTime = startingTime.Add(TimeSpan.FromSeconds(SharedFunctions.CalculateWalkingTimeNoRounding(distanceSoFar)));

                // Calculate the occupancies at this point.
                Dictionary <(string entryId, string exitId), int> edgeOccupancies = CongestionHelper.CalculateEdgeOccupanciesAtTime(allStudentRoutes, currentTime);

                if (edgeOccupancies.Count > 0)
                {
                    // Add to running count for heatmap congestion calculation later.
                    allCongestionValues.Add(edgeOccupancies);
                }

                // Get the edge object.
                NodeEdge edge = RouteNodes[i].OutgoingEdges.Find(e => e.Node2.NodeId == RouteNodes[i + 1].NodeId);
                if (edge != default)
                {
                    // Increment the actual walking time.
                    totalAdjustedWalkingTime += Pathfinder.CalculateWalkingTimeWithCongestion(edge, edgeOccupancies).timeWithCongestion;
                }
            }

            // Congestion for heatmap display.
            Congestion = new Dictionary <string, float>();
            if (allCongestionValues.Count > 0)
            {
                foreach (Dictionary <(string entryId, string exitId), int> entry in allCongestionValues)
                {
                    foreach (KeyValuePair <(string entryId, string exitId), int> congestedEdge in entry)
                    {
                        string newKey = $"{congestedEdge.Key.entryId},{congestedEdge.Key.exitId}";

                        if (!Congestion.TryAdd(newKey, congestedEdge.Value))
                        {
                            // Already exists, add to it
                            Congestion[newKey] += congestedEdge.Value;
                        }
                    }
                }

                if (Congestion.Count > 0)
                {
                    MaxCongestion = Congestion.Values.Max();
                }
            }

            WalkingTimeSeconds = Convert.ToInt32(Math.Round(totalAdjustedWalkingTime));
        }
 // ----------------------------------------------------------------------
 public bool IsPortOnNodeEdge(iCS_EditorObject node, NodeEdge edge)
 {
     return(IsPortOnRectEdge(node.GlobalRect, edge));
 }
Exemplo n.º 23
0
 private IGraphicsCompositorLinkViewModel GetLink(NodeEdge edge)
 {
     return(linkMapping[edge]);
 }
 // ----------------------------------------------------------------------
 public bool IsPortOnRectEdge(Rect r, NodeEdge edge)
 {
     return(IsPositionOnRectEdge(GlobalPosition, r, edge));
 }
Exemplo n.º 25
0
        /// <summary>
        /// Verify Node edges on this single floor.
        /// </summary>
        /// <param name="nodes">Nodes on this floor</param>
        /// <param name="edges">Corresponding edges on this floor</param>
        /// <returns>A list of broken connection errors, if any</returns>
        public static List <string> VerifyNodeEdgesSingleFloor(List <Node> nodes, List <NodeEdge> edges)
        {
            List <string> brokenConnections = new List <string>();

            // Iterate through all nodes.
            foreach (Node node in nodes)
            {
                // Ensure this node has connections.
                NodeEdge[] connections = edges.Where(e => e.Node1Id == node.NodeId || e.Node2Id == node.NodeId).ToArray();

                // Iterate through its connections.
                foreach (NodeEdge connection in connections)
                {
                    // Skip connections between stairs and lifts because they require more than one floor to verify.
                    if ((connection.Node1Id.StartsWith("s", StringComparison.OrdinalIgnoreCase) && connection.Node2Id.StartsWith("s", StringComparison.OrdinalIgnoreCase)) ||
                        (connection.Node1Id.StartsWith("l", StringComparison.OrdinalIgnoreCase) && connection.Node2Id.StartsWith("l", StringComparison.OrdinalIgnoreCase)))
                    {
                        continue;
                    }

                    string node1BC    = SharedFunctions.GetBuildingCodeFromId(connection.Node1Id);
                    string node2BC    = SharedFunctions.GetBuildingCodeFromId(connection.Node2Id);
                    sbyte  node1Floor = -1;
                    try
                    {
                        node1Floor = SharedFunctions.GetLevelFromId(connection.Node1Id);
                        if (node1Floor < 0)
                        {
                            throw new InvalidOperationException("No Level!");
                        }
                    }
                    catch
                    {
                        brokenConnections.Add($"{connection.Node1Id} is missing a level number in the connection to {connection.Node2Id}");
                        continue;
                    }
                    sbyte node2Floor = -1;
                    try
                    {
                        node2Floor = SharedFunctions.GetLevelFromId(connection.Node2Id);
                        if (node2Floor < 0)
                        {
                            throw new InvalidOperationException("No Level!");
                        }
                    }
                    catch
                    {
                        brokenConnections.Add($"{connection.Node2Id} is missing a level number in the connection to {connection.Node1Id}");
                        continue;
                    }

                    if (string.IsNullOrWhiteSpace(node1BC))
                    {
                        brokenConnections.Add($"{connection.Node1Id} is missing a building code in its connection to {connection.Node2Id}");
                        continue;
                    }

                    if (string.IsNullOrWhiteSpace(node2BC))
                    {
                        brokenConnections.Add($"{connection.Node2Id} is missing a building code in its connection to {connection.Node1Id}");
                        continue;
                    }

                    // Skip connections between outdoors and indoors - different building, or different floors - codes as they require more than on json file to verify.
                    if (node1BC != node2BC || node1Floor != node2Floor)
                    {
                        continue;
                    }

                    Node node1 = nodes.Find(n => n.NodeId == connection.Node1Id);
                    Node node2 = nodes.Find(n => n.NodeId == connection.Node2Id);

                    // Check both nodes exist.
                    if (node1 == default)
                    {
                        brokenConnections.Add($"Cannot find node: {connection.Node1Id}");
                        continue;
                    }

                    if (node2 == default)
                    {
                        brokenConnections.Add($"Cannot find node: {connection.Node2Id}");
                        continue;
                    }

                    NodeEdge result = Array.Find(connections, c => c.Node1Id == node2.NodeId && c.Node2Id == node1.NodeId);

                    // Check a connection exists both ways.
                    if (result == null)
                    {
                        // Connection does not exist.
                        brokenConnections.Add($"Broken Connection: {node1.NodeId} is only connected to {node2.NodeId} one way");
                    }
                }
            }

            return(brokenConnections);
        }
Exemplo n.º 26
0
        public IGraph Execute(INode _StartNode)
        {
            var hStopwatch = new Stopwatch();

            Console.WriteLine("Start Nearest Neigbor Algorithmus");
            hStopwatch.Start();

            var hNodeInGraphCount = FUsedGraph.GetNodeDictionary().Count;
            var hTourCosts        = 0.0;
            var hVisitedNodes     = new HashSet <INode>();

            var hNearestNeighborGraph = new Graph();
            var hCurrentNode          = _StartNode; // Auswahl Startknoten.

            hVisitedNodes.Add(hCurrentNode);
            hNearestNeighborGraph.CreateNewNode(hCurrentNode.Id);
            Console.WriteLine("Start bei Knoten ID: " + hCurrentNode.Id);

            // Solange es noch unbesuchte Knoten gibt
            while (hVisitedNodes.Count < hNodeInGraphCount)
            {
                double   hMinimumEdgeWeight = Double.MaxValue;
                NodeEdge hMinimumNodeEdge   = null;

                // Guck dir alle Nachbarn vom aktuellen Knoten an und wähle die niedrigste Kante zu einem unbesuchten Knoten
                foreach (var hEdgeToNeighbor in hCurrentNode.NeighbourEdges)
                {
                    var hEdgeToNeighborWeight = hEdgeToNeighbor.Edge.GetWeightValue();
                    if (!hVisitedNodes.Contains(hEdgeToNeighbor.Node) && hEdgeToNeighborWeight < hMinimumEdgeWeight)
                    {
                        hMinimumEdgeWeight = hEdgeToNeighborWeight;
                        hMinimumNodeEdge   = hEdgeToNeighbor;
                    }
                }

                hTourCosts  += hMinimumEdgeWeight;
                hCurrentNode = hMinimumNodeEdge?.Node;
                hVisitedNodes.Add(hCurrentNode);

                // Knoten und Kante in neuen Graph einfügen
                hNearestNeighborGraph.CreateNewNode(hCurrentNode.Id);
                hNearestNeighborGraph.CreateUndirectedEdge(hMinimumNodeEdge.Edge.GetPossibleEnpoints()[0],
                                                           hMinimumNodeEdge.Edge.GetPossibleEnpoints()[1],
                                                           new CostWeighted(hMinimumEdgeWeight));

                Console.WriteLine("Zu Knoten-ID: " + hCurrentNode?.Id + "\tKosten: " + hMinimumEdgeWeight);
            }

            // Kreis schließen
            foreach (var hEdgeToNeighbor in hCurrentNode.NeighbourEdges)
            {
                if (hEdgeToNeighbor.Node == _StartNode)
                {
                    hTourCosts += hEdgeToNeighbor.Edge.GetWeightValue();
                    hNearestNeighborGraph.CreateUndirectedEdge(hEdgeToNeighbor.Edge.GetPossibleEnpoints()[0],
                                                               hEdgeToNeighbor.Edge.GetPossibleEnpoints()[1],
                                                               new CostWeighted(hEdgeToNeighbor.Edge.GetWeightValue()));
                    Console.WriteLine("Tour beenden zu ID: " + _StartNode?.Id + "\tKosten: " + hEdgeToNeighbor.Edge.GetWeightValue());
                    break;
                }
            }

            hStopwatch.Stop();
            Console.WriteLine("Gesamtkosten:\t" + hTourCosts);
            Console.WriteLine("Dauer:\t" + hStopwatch.ElapsedMilliseconds + " ms");

            return(hNearestNeighborGraph);
        }
Exemplo n.º 27
0
 /// <summary>
 /// Calculate the congestion multiplier for use in increasing the cost of an edge proportional to the congestion on that edge.
 /// </summary>
 /// <param name="edge">Edge to consider.</param>
 /// <param name="edgeOccupancies">The dictionary of edges and their occupancies at the current time.</param>
 /// <returns>A decimal multiplier.</returns>
 public static float CalculateCongestionMultiplier(NodeEdge edge, Dictionary <(string entryId, string exitId), int> edgeOccupancies)
Exemplo n.º 28
0
        /// <summary>
        /// Ermittelt den Minimalen Spannbaum mit dem Prim Algorithmus
        /// </summary>
        /// <returns>Neuer Graf der den MST repräsentiert</returns>

        public IGraph Execute()
        {
            // Umsetzung des Algorithmus:
            // hInMst: Liste über alle KnotenIds und speichert ob die jeweilige KnotenId schon im MST drin ist.
            // hNodeCosts : Liste über KnotenIds und speichert die minimalsten Kosten zu einem Knoten (dient als schneller Vergleich ob es eine günstigere Kante gibt)
            // hSmallestEdgePq : PriorityQueue, wobei die Priority die Kantenkosten sind und als Value ein NodeEdge Objekt dient

            FStopwatch.Start();

            var    hMinimalSpanningTree = new Graph();
            double hCosts = 0.0;

            var hNodeIndex  = FUsedGraph.GetNodeDictionary();
            var hEdgeIndex  = FUsedGraph.GetEdgeIndices();
            var hNodesAdded = 0;

            var hInMst          = new List <bool>();
            var hNodeCosts      = new List <double>(); // Sichert die minimalen Kosten mit denen ein Knoten erreicht werden kann
            var hSmallestEdgePq = new SimplePriorityQueue <NodeEdge, double>();

            // ToDo Bei der Deklaration schon initialisieren
            for (var i = 0; i < hNodeIndex.Count; i++)
            {
                hInMst.Add(false);
                hNodeCosts.Add(double.MaxValue);
            }

            var hStartNodeIndex = 0;
            var hStartNode      = hNodeIndex[hStartNodeIndex];
            // ToDo Vorher initialisieren
            var hStartFakeEdge = new UndirectedEdge(hStartNode, hStartNode, new CostWeighted(0.0));
            var hStartNodeEdge = new NodeEdge(hStartNode, hStartFakeEdge); // Fake-Edge für den Startknoten.

            // Startknoten hinzufügen
            hSmallestEdgePq.Enqueue(hStartNodeEdge, 0.0);
            hNodeCosts[hStartNodeIndex] = 0.0;

            while (hNodesAdded < hNodeIndex.Count)
            {
                var hSmallestNodeEdge    = hSmallestEdgePq.Dequeue();
                var hSmallestEdgesNodeId = hSmallestNodeEdge.Node.Id;

                if (hInMst[hSmallestEdgesNodeId])
                {
                    continue;                                // Der Zielknoten der kleinsten Kante wurde bereits besucht. Also nächste Iteration durchlaufen (=nächste Kante nehmen)
                }
                hInMst[hSmallestEdgesNodeId] = true;
                hNodesAdded++;
                // Create MST Graph
                var hNewNode = new Node(hSmallestEdgesNodeId);
                hMinimalSpanningTree.CreateNewNode(hSmallestEdgesNodeId);
                var hFromNodeId = hSmallestNodeEdge.Edge.GetOtherEndpoint(hSmallestNodeEdge.Node).Id;
                var hFromNode   = hMinimalSpanningTree.GetNodeById(hFromNodeId);
                hMinimalSpanningTree.CreateUndirectedEdge(hNewNode, hFromNode, new CostWeighted(hSmallestNodeEdge.Edge.GetWeightValue()));

                hCosts += hSmallestNodeEdge.Edge.GetWeightValue();

                foreach (var hNeighbourNodeEdges in hSmallestNodeEdge.Node.NeighbourEdges)
                {
                    var hNeighbourId     = hNeighbourNodeEdges.Node.Id;
                    var hNeighbourWeight = hNeighbourNodeEdges.Edge.GetWeightValue();

                    if (hInMst[hNeighbourId] == false && hNodeCosts[hNeighbourId] > hNeighbourWeight)
                    {
                        hNodeCosts[hNeighbourId] = hNeighbourWeight;
                        hSmallestEdgePq.Enqueue(hNeighbourNodeEdges, hNeighbourWeight);
                    }
                }
            }

            // Die Fake-Edge des Startknotens wieder aus dem MST-Graf rausnehmen. (Es ist die erste Kante des Startknotens)
            hMinimalSpanningTree.RemoveEdge(hMinimalSpanningTree.GetNodeDictionary()[hStartNodeIndex].NeighbourEdges[0].Edge);

            FStopwatch.Stop();
            Console.WriteLine("--- Prim ---");
            Console.WriteLine("Prim-Zeit:\t" + FStopwatch.ElapsedMilliseconds.ToString() + " ms");
            Console.WriteLine("Prim-Kosten:\t " + hCosts.ToString());

            return(hMinimalSpanningTree);
        }
 // ----------------------------------------------------------------------
 // Updates the port edge information from the port type.
 public void UpdatePortEdge(Vector2 localPosition)
 {
     Edge = GetClosestEdge(localPosition);
 }
Exemplo n.º 30
0
    private Frustrum FrustrumHitsDoor(Frustrum frustrum, NodeEdge nextDoor)
    {
        if (frustrum == null)
        {
            return(null);
        }
        float highAngle = Vector2.SignedAngle(Vector2.up, frustrum.highEnd - frustrum.highStart);
        float lowAngle  = Vector2.SignedAngle(Vector2.up, frustrum.lowEnd - frustrum.lowStart);

        Vector2 lowEnd;
        Vector2 highEnd;

        var nextFrustrum = GetFrustrum(frustrum.highStart, frustrum.lowStart, nextDoor);

        if (nextFrustrum == null)
        {
            return(null);
        }

        if (Vector2.SignedAngle(Vector2.up, nextFrustrum.lowEnd - frustrum.lowEnd) > Vector2.SignedAngle(Vector2.up, nextFrustrum.highEnd - frustrum.highEnd))
        {
            lowEnd  = nextFrustrum.highEnd;
            highEnd = nextFrustrum.lowEnd;
        }
        else
        {
            highEnd = nextFrustrum.highEnd;
            lowEnd  = nextFrustrum.lowEnd;
        }

        float highAngleNext = Vector2.SignedAngle(Vector2.up, highEnd - frustrum.highStart);
        float lowAngleNext  = Vector2.SignedAngle(Vector2.up, lowEnd - frustrum.lowStart);;

        bool hits = (highAngleNext >= lowAngle && highAngleNext <= highAngle) || (lowAngleNext >= lowAngle && lowAngleNext <= highAngle) || (highAngleNext >= highAngle && lowAngleNext <= lowAngle);

        Vector2 lowEndNew  = lowEnd;
        Vector2 highEndNew = highEnd;

        if (highAngleNext < lowAngle || lowAngleNext > highAngle)
        {
            return(null);
        }

        if (highAngleNext >= lowAngle && highAngleNext <= highAngle)
        {
            frustrum.highEnd = GetFrustrum(frustrum.highStart, frustrum.lowStart, nextDoor).highEnd;
        }
        else
        {
            frustrum.highEnd = highEnd;
        }
        if (lowAngleNext >= lowAngle && lowAngleNext <= highAngle)
        {
            frustrum.lowEnd = GetFrustrum(frustrum.highStart, frustrum.lowStart, nextDoor).lowEnd;
        }
        else
        {
            frustrum.lowEnd = lowEnd;
        }


        return(frustrum);
    }