Recent

Author Topic: LGenerics: yet another generics collection  (Read 37468 times)

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Yet another generics collection
« Reply #45 on: August 10, 2020, 02:48:10 pm »
There shouldn't seem to be any problems, but to be honest, I haven't tried.

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Yet another generics collection
« Reply #46 on: August 10, 2020, 03:48:38 pm »
There shouldn't seem to be any problems, but to be honest, I haven't tried.

Thanks for reply.

I figured out, it works, but only if I add
  (in addition to LGenerics/lgenerics/ in Other unit files(-Fu))
  LGenerics/lgenerics/include to Include files(-Fi),
otherwise compiler cannot find {$I EnumsH.inc}.

I'd suggest improvement in form of replacing such includes as {$i include/xyz.inc}, so -Fi LGenerics/lgenerics/include will not be necessary (as actually being a part of *.pas units).

Another one, how do you construct graphs, can I use builtin hashing helpers for this?
Code: Pascal  [Select][+][-]
  1. uses
  2.    LGSimpleGraph, LGHelpers;
  3. type
  4.   TMyGraph = specialize TGSimpleGraph<TMyVertexClass, TMyEdgeClass, TWhat?>;
  5.  

Thanks again.
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Yet another generics collection
« Reply #47 on: August 10, 2020, 04:48:06 pm »
Thanks for the suggestion.

To use the built-in helper for a class, it is enough to declare the graph as
Code: Pascal  [Select][+][-]
  1. uses
  2.    LGSimpleGraph, LGHelpers;
  3. type
  4.   TMyGraph = specialize TGSimpleGraph<TMyVertexClass, TMyEdgeClass, TMyVertexClass>;
  5.  

Note that the built-in helper uses the TObject.Equals and TObject.GetHashCode methods under the hood.

AlexTP

  • Hero Member
  • *****
  • Posts: 2386
    • UVviewsoft
Re: Yet another generics collection
« Reply #48 on: August 10, 2020, 05:13:06 pm »

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Yet another generics collection
« Reply #49 on: August 10, 2020, 07:43:36 pm »
Thank you very much, that's very kind.

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Yet another generics collection
« Reply #50 on: August 24, 2020, 09:05:45 pm »
Again about graphs.
Is there a suggested way of (un)serialization?

Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Yet another generics collection
« Reply #51 on: August 25, 2020, 03:33:27 am »
Only the simplest SaveToStream/LoadFromStream.

mr-highball

  • Full Member
  • ***
  • Posts: 233
    • Highball Github
Re: Yet another generics collection
« Reply #52 on: August 25, 2020, 04:15:03 am »
Saw your library back when it was first posted and have to say, you've got some good stuff in here. Just wanted to say it's been starred and to keep up the good work 👍👍

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Yet another generics collection
« Reply #53 on: August 25, 2020, 11:50:54 am »
Thank you very much.

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Yet another generics collection
« Reply #54 on: August 26, 2020, 02:41:11 pm »
Only the simplest SaveToStream/LoadFromStream.

Well, for Vetices there are Items, but I can't figure out how can I exactly iterate through Edges as linear list.
Can you provide an example?
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Yet another generics collection
« Reply #55 on: August 26, 2020, 04:38:03 pm »
It seems I misunderstood your question?

There is the Edges method, which returns enumerable, which enumerates all edges of the graph.
On an undirected graph each edge will meet twice, which may be inconvenient.
Therefore the undirected graph also has the DistinctEdges method.

This code
Code: Pascal  [Select][+][-]
  1. program print_edges;
  2. {$mode delphi}
  3. uses
  4.   SysUtils, LGUtils, LGSimpleGraph;
  5.  
  6. type
  7.   TRef = TGAutoRef<TStrChart>;
  8.  
  9. var
  10.   Ref: TRef;
  11.   g: TStrChart;
  12.   s: string;
  13.   e: TStrChart.TEdge;
  14. begin
  15.   g := Ref;
  16.   g.AddEdge('one', 'two');
  17.   g.AddEdge('one', 'three');
  18.   g.AddEdge('two', 'four');
  19.   g.AddEdge('two', 'five');
  20.   g.AddEdge('three', 'six');
  21.   g.AddEdge('three', 'seven');
  22.   g.AddEdge('six', 'eight');
  23.   g.AddEdge('seven', 'eight');
  24.   g.AddEdge('eight', 'one');
  25. { or
  26.   g.AddEdges(
  27.     ['one', 'two', 'one', 'three', 'two', 'four', 'two', 'five', 'three', 'six',
  28.      'three', 'seven', 'six', 'eight', 'seven', 'eight', 'eight', 'one']); }
  29.  
  30.   WriteLn('Vertices:');
  31.   for s in g.Vertices do
  32.     WriteLn(s);
  33.  
  34.   WriteLn;
  35.  
  36.   WriteLn('Edges:');
  37.   for e in g.DistinctEdges do
  38.     WriteLn(g[e.Source], ' -- ', g[e.Destination]);
  39. end.
  40.  
will print
Code: Text  [Select][+][-]
  1. Vertices:
  2. one
  3. two
  4. three
  5. four
  6. five
  7. six
  8. seven
  9. eight
  10.  
  11. Edges:
  12. one -- two
  13. one -- three
  14. one -- eight
  15. two -- four
  16. two -- five
  17. three -- six
  18. three -- seven
  19. six -- eight
  20. seven -- eight
  21.  

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Yet another generics collection
« Reply #56 on: August 26, 2020, 06:31:53 pm »
Yes, my case is undirected graphs (with my own TVertex and TEdge classes), and I need to save/load whole dataset to text/xml (both structure and objects).
Also I need to visualize it in form of "circles connected by lines", so I guess DistinctEdges is what I need.

Currently, I'm using another graph library (C-code linked to my Pascal project), but found your one, and evaluating it. It's very complex, not yet get used to it.

Also, does DistinctEdges return cached value, or does it recalculate list on the fly (from adjacency matrix?)?
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Yet another generics collection
« Reply #57 on: August 26, 2020, 07:42:46 pm »
Also, does DistinctEdges return cached value, or does it recalculate list on the fly (from adjacency matrix?)?
The iterator simply traverses the vertex adjacency lists.

BTW, there is a way(rather primitive) to draw a graph.
This code will save the graph from the previous example in Graphviz' dot format:
Code: Pascal  [Select][+][-]
  1. program save2dot;
  2. {$mode delphi}
  3. uses
  4.   SysUtils, LGUtils, LGSimpleGraph;
  5. var
  6.   Ref: TGAutoRef<TStrChart>;
  7.   g: TStrChart;
  8.   DotWriter: TGAutoRef<TStrChartDotWriter>;
  9. begin
  10.   g := Ref;
  11.   g.Title := 'Chart';
  12.   g.AddEdges(['one', 'two', 'one', 'three', 'two', 'four', 'two', 'five', 'three', 'six',
  13.               'three', 'seven', 'six', 'eight', 'seven', 'eight', 'eight', 'one']);
  14.  
  15.   with DotWriter.Instance do
  16.     begin
  17.       ShowTitle := True;
  18.       SizeX := 4;
  19.       SizeY := 4;
  20.       SaveToFile(g, 'Chart.dot')
  21.     end;
  22. end.
  23.  
If you feed the resulting file to Graphviz, you will get a picture similar to the one in the attachment.

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Yet another generics collection
« Reply #58 on: August 26, 2020, 11:34:17 pm »
Well, I know about Graphviz, but I must use canvas to draw and edit graph layout...

And what about memory management?
Should I take care about freeing my custom vertex and edge class instances?
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Yet another generics collection
« Reply #59 on: August 27, 2020, 06:55:18 am »
If instances of vertices and edges are not stored anywhere except the graph, then certainly yes.
Provided that you do not remove the vertices and edges of the graph while manipulating with it, this can be done in the destructor. Otherwise, you also need to override the protected methods DoRemoveVertex and DoRemoveEdge

 

TinyPortal © 2005-2018