/// <summary> /// Prints this stack with the specified writer /// </summary> /// <param name="writer">A text writer</param> public void PrintTo(TextWriter writer) { // list of all nodes having at least one child List <int> linked = new List <int>(); for (int i = generation; i != -1; i--) { writer.WriteLine("--- generation {0} ---", i); // Retrieve the edges in this generation Dictionary <int, List <int> > myedges = new Dictionary <int, List <int> >(); GSSGeneration cedges = edgeGenerations[i]; for (int j = 0; j != cedges.Count; j++) { GSSEdge edge = edges[cedges.Start + j]; if (!myedges.ContainsKey(edge.From)) { myedges.Add(edge.From, new List <int>()); } myedges[edge.From].Add(edge.To); if (!linked.Contains(edge.To)) { linked.Add(edge.To); } } // Retrieve the nodes in this generation and reverse their order GSSGeneration cnodes = nodeGenerations[i]; List <int> mynodes = new List <int>(); for (int j = 0; j != cnodes.Count; j++) { mynodes.Add(cnodes.Start + j); } mynodes.Reverse(); // print this generation foreach (int node in mynodes) { string mark = linked.Contains(node) ? "node" : "head"; if (myedges.ContainsKey(node)) { foreach (int to in myedges[node]) { int gen = GetGenerationOf(to); if (gen == i) { writer.WriteLine("\t{0} {1} to {2}", mark, nodeLabels[node], nodeLabels[to]); } else { writer.WriteLine("\t{0} {1} to {2} in gen {3}", mark, nodeLabels[node], nodeLabels[to], gen); } } } else { writer.WriteLine("\t{0} {1}", mark, nodeLabels[node]); } } } }
/// <summary> /// Determines whether this instance has the required edge /// </summary> /// <param name="generation">The generation of the edge's start node</param> /// <param name="from">The edge's start node</param> /// <param name="to">The edge's target node</param> /// <returns><c>true</c> if this instance has the required edge; otherwise, <c>false</c></returns> public bool HasEdge(int generation, int from, int to) { GSSGeneration data = edgeGenerations[generation]; for (int i = data.Start; i != data.Start + data.Count; i++) { GSSEdge edge = edges[i]; if (edge.From == from && edge.To == to) { return(true); } } return(false); }
/// <summary> /// Gets all paths in the GSS starting at the given node and with the given length /// </summary> /// <param name="from">The starting node</param> /// <param name="length">The length of the requested paths</param> /// <param name="count">The number of paths</param> /// <returns>A collection of paths in this GSS</returns> public GSSPath[] GetPaths(int from, int length, out int count) { if (length == 0) { // use the common 0-length GSS path to avoid new memory allocation path0.Last = from; count = 1; return(paths0); } // Initializes the first path SetupPath(0, from, length); // The number of paths in the list int total = 1; // For the remaining hops for (int i = 0; i != length; i++) { int m = 0; // Insertion index for the compaction process int next = total; // Insertion index for new paths for (int p = 0; p != total; p++) { int last = paths[p].Last; int genIndex = paths[p].Generation; // Look for new additional paths from last GSSGeneration gen = edgeGenerations[genIndex]; int firstEdgeTarget = -1; int firstEdgeLabel = -1; for (int e = gen.Start; e != gen.Start + gen.Count; e++) { GSSEdge edge = edges[e]; if (edge.From == last) { if (firstEdgeTarget == -1) { // This is the first edge firstEdgeTarget = edge.To; firstEdgeLabel = edge.Label; } else { // Not the first edge // Clone and extend the new path SetupPath(next, edge.To, length); paths[next].CopyLabelsFrom(paths[p], i); paths[next][i] = edge.Label; // Go to next insert next++; } } } // Check whether there was at least one edge if (firstEdgeTarget != -1) { // Continue the current path if (m != p) { GSSPath t = paths[m]; paths[m] = paths[p]; paths[p] = t; } paths[m].Last = firstEdgeTarget; paths[m].Generation = GetGenerationOf(firstEdgeTarget); paths[m][i] = firstEdgeLabel; // goto next m++; } } if (m != total) { // if some previous paths have been removed // => compact the list if needed for (int p = total; p != next; p++) { GSSPath t = paths[m]; paths[m] = paths[p]; paths[p] = t; m++; } // m is now the exact number of paths total = m; } else if (next != total) { // no path has been removed, but some have been added // => next is the exact number of paths total = next; } } count = total; return(paths); }