eschulte / graph Goto Github PK
View Code? Open in Web Editor NEWSimple graph data structure and algorithms
Home Page: http://eschulte.github.io/graph
License: MIT License
Simple graph data structure and algorithms
Home Page: http://eschulte.github.io/graph
License: MIT License
GRAPH - simple graph data structure and algorithms The GRAPH library strives for simplicity both in backing data structures and in usage. Graphs and Digraphs are represented as CLOS objects with methods and algorithms provided for graph manipulation and analysis. Note: currently this library is only supported on SBCL, Clozure CL, and Allegro CL because of the need to create hashes with custom equality tests, however custom equality tests are commonly supported so extending to other lisps should be simple. Patches welcome. For more information see http://eschulte.github.com/graph.
I was doing advent of code, day 25: https://adventofcode.com/2023/day/25
the test data is:
(let ((g (make-instance 'graph)))
(graph:populate
g
:nodes '(jqt rhn xhk nvd rsh frs pzl lsr hfx cmg qnr lhk bvb ntq rzs)
:edges-w-values '(((jqt rhn) . 1)
((jqt xhk) . 1)
((jqt nvd) . 1)
((rsh frs) . 1)
((rsh pzl) . 1)
((rsh lsr) . 1)
((xhk hfx) . 1)
((cmg qnr) . 1)
((cmg nvd) . 1)
((cmg lhk) . 1)
((cmg bvb) . 1)
((rhn xhk) . 1)
((rhn bvb) . 1)
((rhn hfx) . 1)
((bvb xhk) . 1)
((bvb hfx) . 1)
((pzl lsr) . 1)
((pzl hfx) . 1)
((pzl nvd) . 1)
((qnr nvd) . 1)
((ntq jqt) . 1)
((ntq hfx) . 1)
((ntq bvb) . 1)
((ntq xhk) . 1)
((nvd lhk) . 1)
((lsr lhk) . 1)
((rzs qnr) . 1)
((rzs cmg) . 1)
((rzs lsr) . 1)
((rzs rsh) . 1)
((frs qnr) . 1)
((frs lhk) . 1)
((frs lsr) . 1)))
(graph:min-cut g))
min-cut
returns different results each time, only sometimes finding the correct result of 3.
This seems to be caused from the mutation side-effect of sort, in graph.lisp:
(loop :while rest :do
;; grow A by adding the node most tightly connected to A
(let ((new (car (sort rest #'> :key {connection-weight a}))))
(setf rest (remove new rest))
(push new a)))
changing it to (sort (copy-tree rest) ...
and it returns the correct result every time.
I can make it work on LispWorks, i.e. run (graph/test:test) without failure, by changing make-diedge-hash-table, make-edge-hash-table and copy-hash to do on LispWorks the same as they do on CCL.
BTW: If edges are always two element lists, then you can optimize the hash-function by doing
(logxor (sxhash (car edge)) (sxhash (second edge))
That eliminates the allocation in copy-tree and the call to sort.
Also consider making an edge a cons rather than a list, which saved a cons object for each edge entry, but that requires more changes.
Trying asdf:test-system
on graph, I got these errors:
ADD-DUPLICATE-EDGE-TO-SMALL-GRAPH
Error: Test assertion failed:
Expression (MEMBER '(BAR FOO) (EDGES *GRAPH*)
TEST #'TREE-EQUAL) evaluated to true
0: '(BAR FOO) => (:BAR :FOO)
1: (EDGES *GRAPH*) => ((:FOO :BAR) (:BAR :BAZ) (:FOO :BAZ) (:BAR :FOO))
3: #'TREE-EQUAL => #<Function TREE-EQUAL>
[condition type: ASSERTION-FAILED]
CLOSED-GROUPS-IN-LESS-SMALL-GRAPH
Error: Test assertion failed:
Binary predicate (EVERY X Y) failed.
x: (THE (VALUES FUNCTION &OPTIONAL)
(CURRY #'CLOSEDP *GRAPH*)) => #<Closure (:INTERNAL CURRY 0)
@
#x30791da52>
y: (CONNECTED-GROUPS-OF-SIZE *GRAPH* 3) => ((:BAR :BAZ :FOO)
(:ZAP :ZAF :QUX))
[condition type: ASSERTION-FAILED]
CLUSTERING-COEFFICIENT-OF-LESS-SMALL-GRAPH
Error: Test assertion failed:
Binary predicate (= X Y) failed.
x: 1 => 1
y: (CLUSTERING-COEFFICIENT *GRAPH*) => 0
[condition type: ASSERTION-FAILED]
This was after I added an implementation of copy-hash
for Allegro (I will submit a PR).
I'll look into these myself as time permits, but I wanted to report them for now.
Building with SBCL 2.1.0.49-5491c03a5 / ASDF 3.3.1 for quicklisp dist creation.
Trying to build commit id c8752ad
graph fails to build with the following error:
Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001A40103}>: Can't inherit "MAP" from "DAMN-FAST-PRIORITY-QUEUE", it is inherited from "COMMON-LISP"
I can't get topological-sort
to work with any graph.
It would be really nice to have a shortest path function for undirected/weighted graphs.
Hello, and thank you for such a great library. I have a very minor feature request that would help me immensely.
Would it be possible for MINIMUM-SPANNING-TREE to take an optional argument specifying if it should use RANDOM-ELT or not? The reason why this is so important to me, is I need to create deterministic graphs for use in a project generating game maps using a seedable PRNG. For this case, something that is guaranteed to create the same MST every time, like FIRST instead of RANDOM-ELT.
The only alternative I have at the moment, apart from writing my own (which I actually had and replaced with this), is to specify a different weight for each edge, which I think is bad on multiple levels.
Thank you
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.