Git Product home page Git Product logo

graphs's People

Contributors

dcharkes avatar dependabot[bot] avatar devoncarew avatar franklinyow avatar hovadur avatar j-j-gajjar avatar jakemac53 avatar kevmoo avatar michaelrfairhurst avatar natebosch avatar nex3 avatar pq avatar scheglov avatar srawlins 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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

graphs's Issues

Use pkg:pedantic lints

Missing:

"avoid_relative_lib_imports",
"avoid_types_as_parameter_names",
"prefer_contains",
"prefer_equal_for_default_values",
"use_rethrow_when_possible"

Should we use named arguments?

Filing for discussion. @jakemac53 - any thoughts?

Initial implementation uses positional arguments for everything. For the algorithms we know we want to add the arguments which are Functions have relatively clear argument and return types, but when looking at the code without getting hints about analyzer errors they aren't super clear. Should we add some named arguments and use @required to give analyzer hints that they all need to be included?

before:

  var components = stronglyConnectedComponents<Node, Node>(
      graph.nodes.keys, (node) => node, (node) => graph.nodes[node] ?? []);

after:

  var components = stronglyConnectedComponents<Node, Node>(
      searchFrom: graph.nodes.keys,
      key: (node) => node,
      children: (node) => graph.nodes[node] ?? []);

Consider adding a shortestPath helper

Here's a tested implementation.

The only downside: I use PriorityQueue from pkg:collection. You could nix that and loose a bit of perf – whatever... CC @natebosch

import 'dart:collection';

import 'package:collection/collection.dart' show PriorityQueue;

/// If [sourceNode] equals [targetNode], `true` is always returned.
///
/// Assumes that [T] implements correct and efficient `==` and `hashCode`.
List<T> shortestPath<T>(
        T sourceNode, T targetNode, Iterable<T> Function(T) edgeWeight) =>
    shortestWeightedPath(sourceNode, targetNode,
        (T node) => edgeWeight(node).map((n) => MapEntry(n, 1)))?.value;

/// The value returned from [edgeWeight] must be greater than zero. This
/// requirement is verified in an assert. If violated When running without
/// asserts, the behavior is undefined.
///
/// If [sourceNode] equals [targetNode], `true` is always returned.
///
/// Assumes that [T] implements correct and efficient `==` and `hashCode`.
MapEntry<num, List<T>> shortestWeightedPath<T>(T sourceNode, T targetNode,
    Iterable<MapEntry<T, num>> Function(T) edgeWeight) {
  if (sourceNode == targetNode) {
    return MapEntry<num, List<T>>(0, []);
  }

  final distances = HashMap<T, MapEntry<num, List<T>>>();
  distances[sourceNode] = MapEntry<num, List<T>>(0, []);

  int compareDistance(T a, T b) {
    final distanceA = distances[a]?.key ?? double.infinity;
    final distanceB = distances[b]?.key ?? double.infinity;
    return distanceA.compareTo(distanceB);
  }

  final toVisit = PriorityQueue<T>(compareDistance)..add(sourceNode);

  MapEntry<num, List<T>> bestOption;

  while (toVisit.isNotEmpty) {
    final current = toVisit.removeFirst();
    final distanceToCurrent = distances[current];

    if (bestOption != null && distanceToCurrent.key >= bestOption.key) {
      // Skip any existing `toVisit` items that have no change of being
      // better than bestOption (if it exists)
      continue;
    }

    for (var edge in edgeWeight(current)) {
      assert(edge.value > 0, 'Edge weight must be greater than zero.');
      final existingDistance = distances[edge.key];

      final newOptionDistance = distanceToCurrent.key + edge.value;

      if (existingDistance == null ||
          existingDistance.key > newOptionDistance) {
        final newOption = MapEntry<num, List<T>>(newOptionDistance,
            distanceToCurrent.value.followedBy(<T>[edge.key]).toList());

        if (edge.key == targetNode) {
          assert(bestOption == null || bestOption.key > newOptionDistance);
          bestOption = newOption;
        }

        distances[edge.key] = newOption;
        if (bestOption == null || bestOption.key > newOption.key) {
          // Only add a node to visit if it might be a better path to the
          // target node
          toVisit.add(edge.key);
        }
      }
    }
  }

  assert(bestOption == distances[targetNode]);
  return bestOption;
}

Nullability of readNode in crawlAsync

In 6adde6d, the return type of readNode in crawlAsync was changed to a potentially non-nullable FutureOr<V>. Quoting the documentation of crawlAsync:

/// If [readNode] returns null for any key it will be ignored from the rest of
/// the graph. 

Should we make this a FutureOr<V?> Function(K) then? Or are users supposed to provide a nullable V and then filter out nulls in the end? If that's the intention, maybe the documentation needs some tweaking. Note that a nullable V wouldn't really work, since null values are still not added to the result.

cc @natebosch

latest update graphs 2.3.0 ruined common annotations json & hive in build_runner

I dunno if this is your issue, but...
Your library is in dependencies in build_runner and after last updating 2.2.0 --> 2.3.0 an issue was happened.

When there are both annotations in class, like that,

part 'user.freezed.dart';
part 'user.g.dart';

/// Класс пользователя для авторизации
@freezed
class AuthUser with _$AuthUser {
  /// Базовый класс typeId: 0, adapterName: 'AuthUserAdapter'
  @HiveType(typeId: 0)
  const factory AuthUser({
    @HiveField(0) required String id,
  }) = _AuthUser;

  /// AuthUser.fromJson
  factory AuthUser.fromJson(Map<String, dynamic> json) =>
      _$AuthUserFromJson(json);

json_annotation which is indirectly called from freezed had been adding its annotations in ".g.dart" alongside with hive

part of 'user.dart';

// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************

class AuthUserAdapter extends TypeAdapter<_$_AuthUser> {
  @override
  final int typeId = 0;


// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

_$_AuthUser _$$_AuthUserFromJson(Map<String, dynamic> json) => $checkedCreate(
      r'_$_AuthUser',
      json,
      ($checkedConvert) {
        final val = _$_AuthUser(

As a result of last night updating of graphs json generator overrides file .g.dart and previous info disappears.

I added this issue to build_runner repository too.

crawlAsync: crashes without pooling over HTTP requests (fix or document)

Noticed in an example that this crashes when used with HTTP if the number of edges returned is more HTTP requests to be created than the VM can handle.

crawlAsync should either implement its own throttling/pooling or at least should document that the number of pending async operations may grow unbounded and that users should implement their own throttling/pooling

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.