Giter Site home page Giter Site logo

simphotonics / directed_graph Goto Github PK

View Code? Open in Web Editor NEW
54.0 4.0 4.0 1.89 MB

Dart implementation of a directed graph. Provides algorithms for sorting vertices, retrieving a topological ordering or detecting cycles.

Home Page: https://pub.dev/packages/directed_graph

License: BSD 3-Clause "New" or "Revised" License

Dart 98.51% Shell 1.49%
dart graph directed-graph directed-acyclic-graph vertex vertices topological-sort sorting graph-theory shortest-paths

directed_graph's Introduction

Directed Graph

Dart

Introduction

An integral part of storing, manipulating, and retrieving numerical data are data structures or as they are called in Dart: collections. Arguably the most common data structure is the list. It enables efficient storage and retrieval of sequential data that can be associated with an index.

A more general (non-linear) data structure where an element may be connected to one, several, or none of the other elements is called a graph.

Graphs are useful when keeping track of elements that are linked to or are dependent on other elements. Examples include: network connections, links in a document pointing to other paragraphs or documents, foreign keys in a relational database, file dependencies in a build system, etc.

The package directed_graph contains an implementation of a Dart graph that follows the recommendations found in graphs-examples and is compatible with the algorithms provided by graphs. It includes methods that enable:

  • adding/removing vertices and edges,
  • sorting of vertices.

The library provides access to algorithms for finding:

  • the shortest path between vertices,
  • the path with the lowest/highest weight (for weighted directed graphs),
  • all paths connecting two vertices,
  • the shortest paths from a vertice to all connected vertices,
  • cycles,
  • a topological ordering of the graph vertices.

The class GraphCrawler can be used to retrieve paths or walks connecting two vertices.

Terminology

Elements of a graph are called vertices (or nodes) and neighbouring vertices are connected by edges. The figure below shows a directed graph with unidirectional edges depicted as arrows. Graph edges are emanating from a vertex and ending at a vertex. In a weighted directed graph each edge is assigned a weight.

Directed Graph Image

  • In-degree of a vertex: Number of edges ending at this vertex. For example, vertex H has in-degree 3.
  • Out-degree of a vertex: Number of edges starting at this vertex. For example, vertex F has out-degree 1.
  • Source: A vertex with in-degree zero is called (local) source. Vertices A and D in the graph above are local sources.
  • Directed Edge: An ordered pair of connected vertices (vi, vj). For example, the edge (A, C) starts at vertex A and ends at vertex C.
  • Path: A path [vi, ..., vn] is an ordered list of at least two connected vertices where each inner vertex is distinct. The path [A, E, G] starts at vertex A and ends at vertex G.
  • Cycle: A cycle is an ordered list of connected vertices where each inner vertex is distinct and the first and last vertices are identical. The sequence [F, I, K, F] completes a cycle.
  • Walk: A walk is an ordered list of at least two connected vertices. [D, F, I, K, F] is a walk but not a path since the vertex F is listed twice.
  • DAG: An acronym for Directed Acyclic Graph, a directed graph without cycles.
  • Topological ordering: An ordered set of all vertices in a graph such that vi occurs before vj if there is a directed edge (vi, vj). A topological ordering of the graph above is: {A, D, B, C, E, K, F, G, H, I, L}. Hereby, dashed edges were disregarded since a cyclic graph does not have a topological ordering.

Note: In the context of this package the definition of edge might be more lax compared to a rigorous mathematical definition. For example, self-loops, that is edges connecting a vertex to itself are explicitly allowed.

Usage

To use this library include directed_graph as a dependency in your pubspec.yaml file. The example below shows how to construct an object of type DirectedGraph.

The graph classes provided by this library are generic with type argument T extends Object, that is vertice must be non-nullable. Graph vertices can be sorted if T is Comparable or if a custom comparator function is provided. In the example below, a custom comparator is used to sort vertices in inverse lexicographical order.

import 'package:directed_graph/directed_graph.dart';
// To run this program navigate to
// the folder 'directed_graph/example'
// in your terminal and type:
//
// # dart bin/directed_graph_example.dart
//
// followed by enter.
void main() {

  int comparator(String s1, String s2) => s1.compareTo(s2);
  int inverseComparator(String s1, String s2) => -comparator(s1, s2);

  // Constructing a graph from vertices.
  final graph = DirectedGraph<String>(
    {
      'a': {'b', 'h', 'c', 'e'},
      'b': {'h'},
      'c': {'h', 'g'},
      'd': {'e', 'f'},
      'e': {'g'},
      'f': {'i'},
      'i': {'l'},
      'k': {'g', 'f'}
    },
    // Custom comparators can be specified here:
    // comparator: comparator,
  );

  print('Example Directed Graph...');
  print('graph.toString():');
  print(graph);

  print('\nIs Acylic:');
  print(graph.isAcyclic);

  print('\nStrongly connected components:');
  print(graph.stronglyConnectedComponents);

  print('\nShortestPath(d, l):');
  print(graph.shortestPath('d', 'l');

  print('\nInDegree(C):');
  print(graph.inDegree('c'));

  print('\nOutDegree(C)');
  print(graph.outDegree('c'));

  print('\nVertices sorted in lexicographical order:');
  print(graph.sortedVertices);

  print('\nVertices sorted in inverse lexicographical order:');
  graph.comparator = inverseComparator;
  print(graph.sortedVertices);
  graph.comparator = comparator;

  print('\nInDegreeMap:');
  print(graph.inDegreeMap);

  print('\nSorted Topological Ordering:');
  print(graph.sortedTopologicalOrdering);

  print('\nTopological Ordering:');
  print(graph.topologicalOrdering);

  print('\nLocal Sources:');
  print(graph.localSources);

  // Add edge to render the graph cyclic
  graph.addEdges('i', {'k'});
  graph.addEdges('l', {'l'});
  graph.addEdges('i', {'d'});

  print('\nCycle:');
  print(graph.cycle);

  print('\nShortest Paths:');
  print(graph.shortestPaths('a'));

  print('\nEdge exists: a->b');
  print(graph.edgeExists('a', 'b'));
}
Click to show the console output.
$ dart example/bin/directed_graph_example.dart
Example Directed Graph...
graph.toString():
{
 'a': {'b', 'h', 'c', 'e'},
 'b': {'h'},
 'c': {'h', 'g'},
 'd': {'e', 'f'},
 'e': {'g'},
 'f': {'i'},
 'g': {},
 'h': {},
 'i': {'l'},
 'k': {'g', 'f'},
 'l': {},
}

Is Acylic:
true

Strongly connected components:
[[h], [b], [g], [c], [e], [a], [l], [i], [f], [d], [k]]

ShortestPath(d, l):
[d, f, i, l]

InDegree(C):
1

OutDegree(C)
2

Vertices sorted in lexicographical order:
[a, b, c, d, e, f, g, h, i, k, l]

Vertices sorted in inverse lexicographical order:
[l, k, i, h, g, f, e, d, c, b, a]

InDegreeMap:
{a: 0, b: 1, h: 3, c: 1, e: 2, g: 3, d: 0, f: 2, i: 1, l: 1, k: 0}

Sorted Topological Ordering:
{a, b, c, d, e, h, k, f, g, i, l}

Topological Ordering:
{a, b, c, d, e, h, k, f, i, g, l}

Local Sources:
[[a, d, k], [b, c, e, f], [g, h, i], [l]]

Cycle:
[l, l]

Shortest Paths:
{e: (e), c: (c), h: (h), a: (), g: (c, g), b: (b)}

Edge exists: a->b
true

Weighted Directed Graphs

The example below shows how to construct an object of type WeightedDirectedGraph. Initial graph edges are specified in the form of map of type Map<T, Map<T, W>>. The vertex type T extends Object and therefore must be a non-nullable. The type associated with the edge weight W extends Comparable to enable sorting of vertices by their edge weight.

The constructor takes an optional comparator function as parameter. Vertices may be sorted if a comparator function is provided or if T implements Comparator.

import 'package:directed_graph/directed_graph.dart';

void main(List<String> args) {
  int comparator(
    String s1,
    String s2,
  ) {
    return s1.compareTo(s2);
  }

  final a = 'a';
  final b = 'b';
  final c = 'c';
  final d = 'd';
  final e = 'e';
  final f = 'f';
  final g = 'g';
  final h = 'h';
  final i = 'i';
  final k = 'k';
  final l = 'l';

  int sum(int left, int right) => left + right;

  var graph = WeightedDirectedGraph<String, int>(
    {
      a: {b: 1, h: 7, c: 2, e: 40, g:7},
      b: {h: 6},
      c: {h: 5, g: 4},
      d: {e: 1, f: 2},
      e: {g: 2},
      f: {i: 3},
      i: {l: 3, k: 2},
      k: {g: 4, f: 5},
      l: {l: 0}
    },
    summation: sum,
    zero: 0,
    comparator: comparator,
  );

  print('Weighted Graph:');
  print(graph);

  print('\nNeighbouring vertices sorted by weight:');
  print(graph..sortEdgesByWeight());

  final lightestPath = graph.lightestPath(a, g);
  print('\nLightest path a -> g');
  print('$lightestPath weight: ${graph.weightAlong(lightestPath)}');

  final heaviestPath = graph.heaviestPath(a, g);
  print('\nHeaviest path a -> g');
  print('$heaviestPath weigth: ${graph.weightAlong(heaviestPath)}');

  final shortestPath = graph.shortestPath(a, g);
  print('\nShortest path a -> g');
  print('$shortestPath weight: ${graph.weightAlong(shortestPath)}');
}
Click to show the console output.
$ dart example/bin/weighted_graph_example.dart
Weighted Graph:
{
 'a': {'b': 1, 'h': 7, 'c': 2, 'e': 40, 'g': 7},
 'b': {'h': 6},
 'c': {'h': 5, 'g': 4},
 'd': {'e': 1, 'f': 2},
 'e': {'g': 2},
 'f': {'i': 3},
 'g': {},
 'h': {},
 'i': {'l': 3, 'k': 2},
 'k': {'g': 4, 'f': 5},
 'l': {'l': 0},
}

Neighbouring vertices sorted by weight
{
 'a': {'b': 1, 'c': 2, 'h': 7, 'g': 7, 'e': 40},
 'b': {'h': 6},
 'c': {'g': 4, 'h': 5},
 'd': {'e': 1, 'f': 2},
 'e': {'g': 2},
 'f': {'i': 3},
 'g': {},
 'h': {},
 'i': {'k': 2, 'l': 3},
 'k': {'g': 4, 'f': 5},
 'l': {'l': 0},
}

Lightest path a -> g
[a, c, g] weight: 6

Heaviest path a -> g
[a, e, g] weigth: 42

Shortest path a -> g
[a, g] weight: 7

Examples

For further information on how to generate a topological sorting of vertices see example.

Features and bugs

Please file feature requests and bugs at the issue tracker.

directed_graph's People

Contributors

simphotonics avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

directed_graph's Issues

Topological ordering strongly connected components

I was expecting topological sorting to return a List<List<T>> instead of a Set<T>.

Current API:

abstract class DirectedGraphBase<T extends Object> extends Iterable<T> {
  Set<T>? get sortedTopologicalOrdering {

For reference:

https://github.com/dart-lang/sdk/blob/main/pkg/kernel/lib/util/graph.dart#L48

List<List<T>> computeStrongComponents<T>(Graph<T> graph) {

Maybe I am misunderstanding how to use this package.

If I have a graph:

  • a -> b
  • b -> c
  • c -> b
  • c -> d

I would expect the topological sorting to be: [[a], [b, c], [d]].

cycle and findCycle() throw a Stack Overflow exception on certain graphs

Hello and thank you for creating the directed_graph library!

I wanted to bring to your attention that cycle (and findCycle()) throws a Stack Overflow exception on certain graphs. I've pasted two specific graphs below in JSON format where the cycle function fails. Hopefully, you can load these graphs and reproduce the behavior on your end.

My Specs:
Windows 10 Pro
16GB RAM
Dart: 2.9.1
directed_graph: 0.1.8

Please let me know if you need more information.

Thank you!

{
  "/benchmark/benchmark.dart": [
    "/lib/path.dart"
  ],
  "/example/example.dart": [
    "/lib/path.dart"
  ],
  "/lib/path.dart": [
    "/lib/src/context.dart",
    "/lib/src/style.dart",
    "/lib/src/context.dart",
    "/lib/src/path_exception.dart",
    "/lib/src/path_map.dart",
    "/lib/src/path_set.dart",
    "/lib/src/style.dart"
  ],
  "/lib/src/characters.dart": [],
  "/lib/src/context.dart": [
    "/lib/path.dart",
    "/lib/src/characters.dart",
    "/lib/src/internal_style.dart",
    "/lib/src/parsed_path.dart",
    "/lib/src/path_exception.dart",
    "/lib/src/style.dart"
  ],
  "/lib/src/internal_style.dart": [
    "/lib/src/context.dart",
    "/lib/src/style.dart"
  ],
  "/lib/src/parsed_path.dart": [
    "/lib/src/internal_style.dart",
    "/lib/src/style.dart"
  ],
  "/lib/src/path_exception.dart": [],
  "/lib/src/path_map.dart": [
    "/lib/path.dart"
  ],
  "/lib/src/path_set.dart": [
    "/lib/path.dart"
  ],
  "/lib/src/style/posix.dart": [
    "/lib/src/characters.dart",
    "/lib/src/internal_style.dart",
    "/lib/src/parsed_path.dart"
  ],
  "/lib/src/style/url.dart": [
    "/lib/src/characters.dart",
    "/lib/src/internal_style.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/style/windows.dart": [
    "/lib/src/characters.dart",
    "/lib/src/internal_style.dart",
    "/lib/src/parsed_path.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/style.dart": [
    "/lib/src/context.dart",
    "/lib/src/style/posix.dart",
    "/lib/src/style/url.dart",
    "/lib/src/style/windows.dart"
  ],
  "/lib/src/utils.dart": [
    "/lib/src/characters.dart"
  ],
  "/test/browser_test.dart": [
    "/lib/path.dart"
  ],
  "/test/io_test.dart": [
    "/lib/path.dart"
  ],
  "/test/path_map_test.dart": [
    "/lib/path.dart"
  ],
  "/test/path_set_test.dart": [
    "/lib/path.dart"
  ],
  "/test/path_test.dart": [
    "/lib/path.dart"
  ],
  "/test/posix_test.dart": [
    "/lib/path.dart",
    "/test/utils.dart"
  ],
  "/test/relative_test.dart": [
    "/lib/path.dart",
    "/test/utils.dart"
  ],
  "/test/url_test.dart": [
    "/lib/path.dart",
    "/test/utils.dart"
  ],
  "/test/utils.dart": [
    "/lib/path.dart"
  ],
  "/test/windows_test.dart": [
    "/lib/path.dart",
    "/test/utils.dart"
  ]
}
{
  "/example/example.dart": [],
  "/example/example.g.dart": [],
  "/lib/builder.dart": [
    "/lib/src/json_part_builder.dart"
  ],
  "/lib/json_serializable.dart": [
    "/lib/src/json_literal_generator.dart",
    "/lib/src/json_serializable_generator.dart"
  ],
  "/lib/src/constants.dart": [],
  "/lib/src/decode_helper.dart": [
    "/lib/src/helper_core.dart",
    "/lib/src/json_literal_generator.dart",
    "/lib/src/unsupported_type_error.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/encoder_helper.dart": [
    "/lib/src/constants.dart",
    "/lib/src/helper_core.dart",
    "/lib/src/type_helpers/json_converter_helper.dart",
    "/lib/src/unsupported_type_error.dart"
  ],
  "/lib/src/field_helpers.dart": [
    "/lib/src/utils.dart"
  ],
  "/lib/src/helper_core.dart": [
    "/lib/src/json_key_utils.dart",
    "/lib/src/type_helper.dart",
    "/lib/src/type_helper_ctx.dart",
    "/lib/src/unsupported_type_error.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/json_key_utils.dart": [
    "/lib/src/json_literal_generator.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/json_literal_generator.dart": [
    "/lib/src/utils.dart"
  ],
  "/lib/src/json_part_builder.dart": [
    "/lib/src/json_literal_generator.dart",
    "/lib/src/json_serializable_generator.dart"
  ],
  "/lib/src/json_serializable_generator.dart": [
    "/lib/src/decode_helper.dart",
    "/lib/src/encoder_helper.dart",
    "/lib/src/field_helpers.dart",
    "/lib/src/helper_core.dart",
    "/lib/src/type_helper.dart",
    "/lib/src/type_helpers/big_int_helper.dart",
    "/lib/src/type_helpers/convert_helper.dart",
    "/lib/src/type_helpers/date_time_helper.dart",
    "/lib/src/type_helpers/duration_helper.dart",
    "/lib/src/type_helpers/enum_helper.dart",
    "/lib/src/type_helpers/iterable_helper.dart",
    "/lib/src/type_helpers/json_converter_helper.dart",
    "/lib/src/type_helpers/json_helper.dart",
    "/lib/src/type_helpers/map_helper.dart",
    "/lib/src/type_helpers/uri_helper.dart",
    "/lib/src/type_helpers/value_helper.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/lambda_result.dart": [],
  "/lib/src/shared_checkers.dart": [
    "/lib/src/helper_core.dart"
  ],
  "/lib/src/type_helper.dart": [],
  "/lib/src/type_helpers/big_int_helper.dart": [
    "/lib/src/type_helper.dart",
    "/lib/src/type_helpers/to_from_string.dart"
  ],
  "/lib/src/type_helpers/convert_helper.dart": [
    "/lib/src/json_key_utils.dart",
    "/lib/src/shared_checkers.dart",
    "/lib/src/type_helper.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/type_helpers/date_time_helper.dart": [
    "/lib/src/type_helper.dart",
    "/lib/src/type_helpers/to_from_string.dart"
  ],
  "/lib/src/type_helpers/duration_helper.dart": [
    "/lib/src/type_helper.dart"
  ],
  "/lib/src/type_helpers/enum_helper.dart": [
    "/lib/src/json_key_utils.dart",
    "/lib/src/json_literal_generator.dart",
    "/lib/src/type_helper.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/type_helpers/iterable_helper.dart": [
    "/lib/src/constants.dart",
    "/lib/src/lambda_result.dart",
    "/lib/src/shared_checkers.dart",
    "/lib/src/type_helper.dart"
  ],
  "/lib/src/type_helpers/json_converter_helper.dart": [
    "/lib/src/helper_core.dart",
    "/lib/src/json_key_utils.dart",
    "/lib/src/lambda_result.dart",
    "/lib/src/shared_checkers.dart",
    "/lib/src/type_helper.dart"
  ],
  "/lib/src/type_helpers/json_helper.dart": [
    "/lib/src/shared_checkers.dart",
    "/lib/src/type_helper.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/type_helpers/map_helper.dart": [
    "/lib/src/constants.dart",
    "/lib/src/shared_checkers.dart",
    "/lib/src/type_helper.dart",
    "/lib/src/unsupported_type_error.dart",
    "/lib/src/utils.dart",
    "/lib/src/type_helpers/to_from_string.dart"
  ],
  "/lib/src/type_helpers/to_from_string.dart": [
    "/lib/src/type_helper.dart"
  ],
  "/lib/src/type_helpers/uri_helper.dart": [
    "/lib/src/type_helper.dart",
    "/lib/src/type_helpers/to_from_string.dart"
  ],
  "/lib/src/type_helpers/value_helper.dart": [
    "/lib/src/helper_core.dart",
    "/lib/src/shared_checkers.dart",
    "/lib/src/type_helper.dart"
  ],
  "/lib/src/type_helper_ctx.dart": [
    "/lib/src/helper_core.dart",
    "/lib/src/type_helper.dart",
    "/lib/src/type_helpers/convert_helper.dart",
    "/lib/src/unsupported_type_error.dart",
    "/lib/src/utils.dart"
  ],
  "/lib/src/unsupported_type_error.dart": [],
  "/lib/src/utils.dart": [
    "/lib/src/helper_core.dart"
  ],
  "/lib/type_helper.dart": [
    "/lib/src/shared_checkers.dart",
    "/lib/src/type_helper.dart",
    "/lib/src/type_helpers/big_int_helper.dart",
    "/lib/src/type_helpers/convert_helper.dart",
    "/lib/src/type_helpers/date_time_helper.dart",
    "/lib/src/type_helpers/duration_helper.dart",
    "/lib/src/type_helpers/enum_helper.dart",
    "/lib/src/type_helpers/iterable_helper.dart",
    "/lib/src/type_helpers/json_converter_helper.dart",
    "/lib/src/type_helpers/json_helper.dart",
    "/lib/src/type_helpers/map_helper.dart",
    "/lib/src/type_helpers/uri_helper.dart",
    "/lib/src/type_helpers/value_helper.dart",
    "/lib/src/unsupported_type_error.dart"
  ],
  "/test/config_test.dart": [
    "/lib/builder.dart",
    "/lib/src/json_serializable_generator.dart",
    "/test/shared_config.dart"
  ],
  "/test/custom_configuration_test.dart": [
    "/lib/json_serializable.dart",
    "/lib/src/constants.dart",
    "/lib/src/type_helper.dart",
    "/test/shared_config.dart"
  ],
  "/test/default_value/default_value.dart": [
    "/test/default_value/default_value_interface.dart",
    "/test/default_value/default_value_interface.dart"
  ],
  "/test/default_value/default_value.g.dart": [],
  "/test/default_value/default_value.g_any_map__checked.dart": [
    "/test/default_value/default_value_interface.dart",
    "/test/default_value/default_value_interface.dart"
  ],
  "/test/default_value/default_value.g_any_map__checked.g.dart": [],
  "/test/default_value/default_value_interface.dart": [],
  "/test/default_value/default_value_test.dart": [
    "/test/test_utils.dart",
    "/test/default_value/default_value.dart",
    "/test/default_value/default_value.g_any_map__checked.dart",
    "/test/default_value/default_value_interface.dart"
  ],
  "/test/ensure_build_test.dart": [],
  "/test/enum_helper_test.dart": [
    "/lib/src/type_helpers/enum_helper.dart"
  ],
  "/test/generic_files/generic_class.dart": [],
  "/test/generic_files/generic_class.g.dart": [],
  "/test/generic_files/generic_test.dart": [
    "/test/test_utils.dart",
    "/test/generic_files/generic_class.dart"
  ],
  "/test/integration/integration_test.dart": [
    "/test/test_utils.dart",
    "/test/integration/json_test_common.dart",
    "/test/integration/json_test_example.dart"
  ],
  "/test/integration/json_test_common.dart": [],
  "/test/integration/json_test_example.dart": [
    "/test/integration/json_test_common.dart"
  ],
  "/test/integration/json_test_example.g.dart": [],
  "/test/integration/json_test_example.g_any_map.dart": [
    "/test/integration/json_test_common.dart"
  ],
  "/test/integration/json_test_example.g_any_map.g.dart": [],
  "/test/integration/json_test_example.g_non_nullable.dart": [
    "/test/integration/json_test_common.dart"
  ],
  "/test/integration/json_test_example.g_non_nullable.g.dart": [],
  "/test/json_serializable_test.dart": [
    "/lib/json_serializable.dart"
  ],
  "/test/kitchen_sink/json_converters.dart": [],
  "/test/kitchen_sink/kitchen_sink.dart": [
    "/test/kitchen_sink/json_converters.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/simple_object.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.factories.dart": [
    "/test/kitchen_sink/kitchen_sink.dart",
    "/test/kitchen_sink/kitchen_sink.g_any_map.dart",
    "/test/kitchen_sink/kitchen_sink.g_any_map__checked__non_nullable.dart",
    "/test/kitchen_sink/kitchen_sink.g_any_map__non_nullable.dart",
    "/test/kitchen_sink/kitchen_sink.g_exclude_null.dart",
    "/test/kitchen_sink/kitchen_sink.g_exclude_null__non_nullable.dart",
    "/test/kitchen_sink/kitchen_sink.g_explicit_to_json.dart",
    "/test/kitchen_sink/kitchen_sink.g_non_nullable.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.g.dart": [],
  "/test/kitchen_sink/kitchen_sink.g_any_map.dart": [
    "/test/kitchen_sink/json_converters.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/simple_object.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.g_any_map.g.dart": [],
  "/test/kitchen_sink/kitchen_sink.g_any_map__checked__non_nullable.dart": [
    "/test/kitchen_sink/json_converters.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/simple_object.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.g_any_map__checked__non_nullable.g.dart": [],
  "/test/kitchen_sink/kitchen_sink.g_any_map__non_nullable.dart": [
    "/test/kitchen_sink/json_converters.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/simple_object.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.g_any_map__non_nullable.g.dart": [],
  "/test/kitchen_sink/kitchen_sink.g_exclude_null.dart": [
    "/test/kitchen_sink/json_converters.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/simple_object.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.g_exclude_null.g.dart": [],
  "/test/kitchen_sink/kitchen_sink.g_exclude_null__non_nullable.dart": [
    "/test/kitchen_sink/json_converters.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/simple_object.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.g_exclude_null__non_nullable.g.dart": [],
  "/test/kitchen_sink/kitchen_sink.g_explicit_to_json.dart": [
    "/test/kitchen_sink/json_converters.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/simple_object.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.g_explicit_to_json.g.dart": [],
  "/test/kitchen_sink/kitchen_sink.g_non_nullable.dart": [
    "/test/kitchen_sink/json_converters.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/simple_object.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink.g_non_nullable.g.dart": [],
  "/test/kitchen_sink/kitchen_sink_interface.dart": [
    "/test/kitchen_sink/simple_object.dart"
  ],
  "/test/kitchen_sink/kitchen_sink_test.dart": [
    "/test/test_utils.dart",
    "/test/kitchen_sink/kitchen_sink.factories.dart",
    "/test/kitchen_sink/kitchen_sink_interface.dart",
    "/test/kitchen_sink/strict_keys_object.dart"
  ],
  "/test/kitchen_sink/simple_object.dart": [],
  "/test/kitchen_sink/simple_object.g.dart": [],
  "/test/kitchen_sink/strict_keys_object.dart": [],
  "/test/kitchen_sink/strict_keys_object.g.dart": [],
  "/test/literal/json_literal.dart": [],
  "/test/literal/json_literal.g.dart": [],
  "/test/literal/json_literal_test.dart": [
    "/test/test_utils.dart",
    "/test/literal/json_literal.dart"
  ],
  "/test/readme_test.dart": [],
  "/test/shared_config.dart": [],
  "/test/src/checked_test_input.dart": [],
  "/test/src/core_subclass_type_input.dart": [],
  "/test/src/default_value_input.dart": [],
  "/test/src/field_namer_input.dart": [],
  "/test/src/generic_test_input.dart": [],
  "/test/src/inheritance_test_input.dart": [],
  "/test/src/json_converter_test_input.dart": [],
  "/test/src/map_key_variety_test_input.dart": [],
  "/test/src/setter_test_input.dart": [],
  "/test/src/to_from_json_test_input.dart": [],
  "/test/src/unknown_enum_value_test_input.dart": [],
  "/test/src/unknown_type_test_input.dart": [],
  "/test/src/_json_serializable_test_input.dart": [],
  "/test/test_sources/test_sources.dart": [],
  "/test/test_utils.dart": [],
  "/test/utils_test.dart": [
    "/lib/src/utils.dart"
  ],
  "/tool/doc_builder.dart": [
    "/lib/src/utils.dart"
  ],
  "/tool/test_builder.dart": []
}

breaking change in lazy_memo

Hello,

the latest release 0.3.9 of directed_graph is not compatible with lazy_memo 0.1.9, since lazy_memo changed LazyMap to be immutable, which breaks the sortedTopologicalGraph method.

    // Get modifiable in-degree map.
    final localInDegreeMap = inDegreeMap;

....

  /// Returns a mapping between vertex and number of
  /// incoming connections.
  late final _inDegreeMap = LazyMap<T, int>(() { ... };

However, the version constraints of directed_graph 0.3.9 allow for lazy_memo 0.1.9.

I get that this is the fault of lazy_memo of making breaking changes with a minor release, but it would be great of you could restrict the version constraints so that users of directed graph do not have to hunt this down and add constraints on their own.

Thanks!

Not sure about results

Hi, I tried to use crawler.paths, but it is not returning results I expected. What I am doing wrong? I used DirectedGraph.fromData() with custom object that has == operator and hashCode override.

print(crawler.paths(graph.vertices[3],
graph.vertices[2])) result:

I/flutter ( 1739): {
I/flutter ( 1739):  M0IAX: [9A1FM, OH8STN, 9A1GS],
I/flutter ( 1739):  9A1FM: [M0IAX, OH8STN],
I/flutter ( 1739):  OH8STN: [M0IAX, 9A1FM],
I/flutter ( 1739):  9A1GS: [M0IAX, 9A1FM],
...
I/flutter ( 1739):  9A1AS: [M0IAA],
I/flutter ( 1739):  M0IAA: [],
I/flutter ( 1739):  9A3GS: [OH8TN],
I/flutter ( 1739):  OH8TN: [],
I/flutter ( 1739):  M1IAX: [OH2STN],
I/flutter ( 1739):  OH2STN: [],
I/flutter ( 1739):  OH8STZ: [M0AXA],
I/flutter ( 1739):  M0AXA: [],
I/flutter ( 1739):  9A2GS: [9A1GS],
I/flutter ( 1739): }

crawler.paths result:

[[9A1GS, M0IAX, 9A1FM, M0IAX, OH8STN], [9A1GS, M0IAX, 9A1FM, M0IAX, 9A1GS, 9A1FM, OH8STN], [9A1GS, M0IAX, 9A1FM, OH8STN], [9A1GS, M0IAX, OH8STN]]

I expected something like::

OK, FOUND:  [9A1GS, M0IAX, OH8STN], 
NOT FOUND: [9A1GS, 9A1FM, OH8STN], 
NOT FOUND: [9A1GS, 9A1FM, M0IAX, OH8STN]

graph.shortestPath result:

OK: [M0IAX, OH8STN] (the same length is [9A1FM, OH8STN], which is missing, but ok)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.