public static void AddNodes(this Graph graph, State currentState) { while (currentState.Next != null) { if (graph.FindEdge(currentState, currentState.Next) != null) { currentState = currentState.Next; continue; } var edge = graph.AddEdge(currentState.GetHashCode().ToString(), currentState.Next.GetHashCode().ToString()); edge.Attr.LineWidth = 2; var currentNode = graph.FindNode(currentState.GetHashCode().ToString()); currentNode.LabelText = currentState.ToString(); if (currentState.Alternative != null) { var altEdge = graph.AddEdge(currentState.GetHashCode().ToString(), currentState.Alternative.First.GetHashCode().ToString()); altEdge.Attr.Color = Color.Gray; altEdge.Attr.LineWidth = 2; graph.AddNodes(currentState.Alternative.First); } currentNode.Attr.Shape = Shape.Box; currentState = currentState.Next; } var lastNode = graph.FindNode(currentState.GetHashCode().ToString()); lastNode.LabelText = currentState.ToString(); }
/// <summary> /// Adds new connections for the specified node for the parent and child nodes. /// </summary> /// <param name="network">Current network.</param> /// <param name="node">Neuron being added.</param> /// <param name="parentNodes">Parent nodes that this neuron is connected with.</param> /// <param name="childNodes">Child nodes that this neuron is connected to.</param> /// <param name="epsilon">Weight initialization parameter.</param> /// <returns></returns> public static Network AddConnections(this Network network, Neuron node, IEnumerable<Neuron> parentNodes, IEnumerable<Neuron> childNodes, double epsilon = double.NaN) { if (epsilon == double.NaN) epsilon = Edge.GetEpsilon(node.ActivationFunction.Minimum, node.ActivationFunction.Maximum, parentNodes.Count(), childNodes.Count()); if (parentNodes != null) { for (int i = 0; i < parentNodes.Count(); i++) network.AddEdge(Edge.Create(parentNodes.ElementAt(i), node, epsilon: epsilon)); } if (childNodes != null) { for (int j = 0; j < childNodes.Count(); j++) network.AddEdge(Edge.Create(node, childNodes.ElementAt(j), epsilon: epsilon)); } return network; }
/// <summary> /// Links a Network from nodes and edges. /// </summary> /// <param name="nodes">An array of nodes in the network</param> /// <param name="edges">An array of edges between the nodes in the network.</param> public static Network LinkNodes(this Network network, IEnumerable<Neuron> nodes, IEnumerable<Edge> edges) { int inputLayerId = nodes.Min(m => m.LayerId); int outputLayerId = nodes.Max(m => m.LayerId); network.In = nodes.Where(w => w.LayerId == inputLayerId).ToArray(); foreach (var node in network.In) network.AddNode(node); int hiddenLayer = inputLayerId + 1; // relink nodes Neuron[] last = null; for (int layerIdx = hiddenLayer; layerIdx < outputLayerId; layerIdx++) { Neuron[] layer = nodes.Where(w => w.LayerId == layerIdx).ToArray(); foreach (var node in layer) network.AddNode(node); if (layerIdx > hiddenLayer) { // create hidden to hidden (full) for (int i = 0; i < last.Length; i++) for (int x = 1; x < layer.Length; x++) network.AddEdge(Edge.Create(last[i], layer[x], weight: edges.First(f => f.ParentId == last[i].Id && f.ChildId == layer[x].Id).Weight)); } else if (layerIdx == hiddenLayer) { // create input to hidden (full) for (int i = 0; i < network.In.Length; i++) for (int j = 1; j < layer.Length; j++) network.AddEdge(Edge.Create(network.In[i], layer[j], weight: edges.First(f => f.ParentId == network.In[i].Id && f.ChildId == layer[j].Id).Weight)); } last = layer; } network.Out = nodes.Where(w => w.LayerId == outputLayerId).ToArray(); foreach (var node in network.Out) network.AddNode(node); for (int i = 0; i < network.Out.Length; i++) for (int j = 0; j < last.Length; j++) network.AddEdge(Edge.Create(last[j], network.Out[i], weight: edges.First(f => f.ParentId == last[j].Id && f.ChildId == network.Out[i].Id).Weight)); return network; }
/// <summary> /// Creates a new fully connected deep neural network based on the supplied size and depth parameters. /// </summary> /// <param name="inputLayer">Neurons in the input layer.</param> /// <param name="outputLayer">Neurons in the output layer.</param> /// <param name="activationFunction">Activation function for the hidden and output layers.</param> /// <param name="outputFunction">(Optional) Output function of the the Nodes in the output layer (overrides the Activation function).</param> /// <param name="fnNodeInitializer">(Optional) Function to call for initializing new Nodes - supplying parameters for the layer and node index.</param> /// <param name="fnWeightInitializer">(Optional) Function to call for initializing the weights of each connection (including bias nodes). /// <para>Where int1 = Source layer (0 is input layer), int2 = Source Node, int3 = Target node in the next layer.</para></param> /// <param name="epsilon">Weight initialization parameter for random weight selection. Weight will be in the range of: -epsilon to +epsilon.</param> /// <param name="hiddenLayers">An array of hidden neuron dimensions, where each element is the size of each layer (excluding bias nodes).</param> /// <returns>Returns an untrained neural network model.</returns> public static Network Create(this Network network, int inputLayer, int outputLayer, IFunction activationFunction, IFunction outputFunction = null, Func<int, int, Neuron> fnNodeInitializer = null, Func<int, int, int, double> fnWeightInitializer = null, double epsilon = double.NaN, params int[] hiddenLayers) { IFunction ident = new Ident(); if (hiddenLayers == null || hiddenLayers.Length == 0) hiddenLayers = new int[] { (int) System.Math.Ceiling((inputLayer + outputLayer + 1) * (2.0 / 3.0)) }; List<double> layers = new List<double>(); layers.Add(inputLayer); foreach (int l in hiddenLayers) layers.Add(l + 1); layers.Add(outputLayer); if (fnNodeInitializer == null) fnNodeInitializer = new Func<int, int, Neuron>((i, j) => new Neuron()); if (fnWeightInitializer == null) fnWeightInitializer = new Func<int, int, int, double>((l, i, j) => { double inputs = (l > 0 ? layers[l - 1] : 0); double outputs = (l < layers.Count - 1 ? layers[l + 1] : 0); double eps = (double.IsNaN(epsilon) ? Edge.GetEpsilon(activationFunction.Minimum, activationFunction.Maximum, inputs, outputs) : epsilon); return Edge.GetWeight(eps); }); // creating input nodes network.In = new Neuron[inputLayer + 1]; network.In[0] = network.AddNode(new Neuron(true) { Label = "B0", ActivationFunction = ident, NodeId = 0, LayerId = 0 }); for (int i = 1; i < inputLayer + 1; i++) { network.In[i] = fnNodeInitializer(0, i); network.In[i].Label = (network.In[i].Label ?? string.Format("I{0}", i)); network.In[i].ActivationFunction = (network.In[i].ActivationFunction ?? ident); network.In[i].LayerId = 0; network.In[i].NodeId = i; network.AddNode(network.In[i]); } Neuron[] last = null; for (int layerIdx = 0; layerIdx < hiddenLayers.Length; layerIdx++) { // creating hidden nodes Neuron[] layer = new Neuron[hiddenLayers[layerIdx] + 1]; layer[0] = network.AddNode(new Neuron(true) { Label = $"B{layerIdx + 1}", ActivationFunction = ident, LayerId = layerIdx + 1, NodeId = 0 }); for (int i = 1; i < layer.Length; i++) { layer[i] = fnNodeInitializer(layerIdx + 1, i); layer[i].Label = (layer[i].Label ?? String.Format("H{0}.{1}", layerIdx + 1, i)); layer[i].ActivationFunction = (layer[i].ActivationFunction ?? activationFunction); layer[i].OutputFunction = layer[i].OutputFunction; layer[i].LayerId = layerIdx + 1; layer[i].NodeId = i; network.AddNode(layer[i]); } if (layerIdx > 0 && layerIdx < hiddenLayers.Length) { // create hidden to hidden (full) for (int i = 0; i < last.Length; i++) for (int x = 1; x < layer.Length; x++) network.AddEdge(Edge.Create(last[i], layer[x], weight: fnWeightInitializer(layerIdx, i, x), epsilon: epsilon)); } else if (layerIdx == 0) { // create input to hidden (full) for (int i = 0; i < network.In.Length; i++) for (int j = 1; j < layer.Length; j++) network.AddEdge(Edge.Create(network.In[i], layer[j], weight: fnWeightInitializer(layerIdx, i, j), epsilon: epsilon)); } last = layer; } // creating output nodes network.Out = new Neuron[outputLayer]; for (int i = 0; i < outputLayer; i++) { network.Out[i] = fnNodeInitializer(hiddenLayers.Length + 1, i); network.Out[i].Label = (network.Out[i].Label ?? String.Format("O{0}", i)); network.Out[i].ActivationFunction = (network.Out[i].ActivationFunction ?? activationFunction); network.Out[i].OutputFunction = (network.Out[i].OutputFunction ?? outputFunction); network.Out[i].LayerId = hiddenLayers.Length + 1; network.Out[i].NodeId = i; network.AddNode(network.Out[i]); } // link from (last) hidden to output (full) for (int i = 0; i < network.Out.Length; i++) for (int j = 0; j < last.Length; j++) network.AddEdge(Edge.Create(last[j], network.Out[i], weight: fnWeightInitializer(hiddenLayers.Length, j, i), epsilon: epsilon)); return network; }
/// <summary> /// Add an undirected edge from a node with the given <paramref name="fromIdentifier"/> to a node /// with the given <paramref name="toIdentifier"/>. /// </summary> /// <param name="writer">The writer to which the edge is added.</param> /// <param name="fromIdentifier">The identifier of the first node of the edge.</param> /// <param name="toIdentifier">The identifier of the second node of the edge.</param> /// <param name="dotAttributes">An array of <see cref="T:IEdgeDotAttribute"/> instances /// that alter the way the edge is displayed.</param> /// <remarks> /// <para>If one of the identifiers (<paramref name="fromIdentifier"/> or <paramref name="toIdentifier"/>), the edge is not added.</para> /// <para>If there are no nodes defined with the given identifier, additional nodes will be added to the graph, /// this is the behavior of GraphViz DOT graphs.</para> /// <para>If the given list of attributes is not effective, no attributes are added to the node.</para> /// <para>If the given <paramref name="writer"/> is not effective, nothing happens.</para> /// </remarks> public static void AddEdge(this IDotTextWriter writer, string fromIdentifier, string toIdentifier, params IEdgeDotAttribute[] dotAttributes) { if (writer != null) { writer.AddEdge (fromIdentifier, toIdentifier, (IEnumerable<IEdgeDotAttribute>)dotAttributes); } }
/// <summary> /// Aktualizacja grafu - dodawanie krawedzi /// Metoda rozszerzająca /// </summary> /// <param name="g">graf</param> /// <param name="x1">Punkt x1 (startowy)</param> /// <param name="y1">Punkt y1 (startowy)</param> /// <param name="x2">Punkt x2</param> /// <param name="y2">Punkt y2</param> /// <param name="startGraph">Gdzie na mapie zaczyna się graf</param> /// <param name="size">Rozmiar grafu (w ilości punktów oddalonych od siebie o VerticesDensity)</param> /// <param name="VerticesDensity">Oddalenie punktów od siebie nawzajem</param> /// <param name="gameMap">mapa</param> /// <param name="b">ograniczenie dla tych dwóch konkretnych punktów</param> private static void UpdateGraph(this IGraph g, int x1, int y1, int x2, int y2, Vector2 startGraph, Point size, float VerticesDensity, GameMap gameMap, Boundaries b) { Vector2 mapPosition1 = new Vector2(startGraph.X + x1 * VerticesDensity, startGraph.Y + y1 * VerticesDensity); Vector2 mapPosition2 = new Vector2(startGraph.X + x2 * VerticesDensity, startGraph.Y + y2 * VerticesDensity); Point mapPoint1 = mapPosition1.GetMapPosition(gameMap); Point mapPoint2 = mapPosition2.GetMapPosition(gameMap); Boundaries shift = b.Clone(); shift += mapPosition1; bool intersects = false; foreach (MapObject mo in gameMap[mapPoint1.X, mapPoint1.Y].mapObjects) if (shift.Intersects(mo.boundaries)) intersects = true; foreach (MapObject mo in gameMap[mapPoint2.X, mapPoint2.Y].mapObjects) if (shift.Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(x1 + y1 * (size.X - 1), x2 + y2 * (size.X - 1)); else g.DelEdge(x1 + y1 * (size.X - 1), x2 + y2 * (size.X - 1)); }