Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Topological sort
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  5 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Nick Day  
View profile  
 More options Nov 11, 2:04 pm
From: Nick Day <nicke...@gmail.com>
Date: Wed, 11 Nov 2009 11:04:03 -0800 (PST)
Local: Wed, Nov 11 2009 2:04 pm
Subject: Topological sort
Hi,

I've been trying to implement a topological sort and have been
struggling a bit. I have a map of symbol vs collection of symbols
like:

{a [b c], b [c], c [nil]}

which can be read as 'a' depends on 'b' and 'c', 'b' depends on 'c'
and 'c' doesn't depend on anything.  I've been trying to write
something that returns a collection of the dependencies in order (c,
b, a) but so far I've only been able to do it using a ref to store
intermediate output of the sorting.  I was wondering if anyone has
already done something similar?

cheers,
Nick


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jan  
View profile  
 More options Nov 12, 1:01 am
From: jan <jan.mare...@gmail.com>
Date: Thu, 12 Nov 2009 17:01:39 +1100
Local: Thurs, Nov 12 2009 1:01 am
Subject: Re: Topological sort

Nick Day <nicke...@gmail.com> writes:
> I've been trying to implement a topological sort and have been
> struggling a bit. I have a map of symbol vs collection of symbols
> like:

> {a [b c], b [c], c [nil]}

> which can be read as 'a' depends on 'b' and 'c', 'b' depends on 'c'
> and 'c' doesn't depend on anything.  I've been trying to write
> something that returns a collection of the dependencies in order (c,
> b, a) but so far I've only been able to do it using a ref to store
> intermediate output of the sorting.  I was wondering if anyone has
> already done something similar?

clojure.contrib.graph/dependency-list might be close enough for you

(use 'clojure.contrib.graph)

(dependency-list {:nodes [:a :b :c]
                                  :neighbors {:a [:b :c]
                                                          :b [:c]}})
=>[#{:c} #{:b} #{:a}]

--
jan


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
John Harrop  
View profile  
 More options Nov 12, 1:06 am
From: John Harrop <jharrop...@gmail.com>
Date: Thu, 12 Nov 2009 01:06:26 -0500
Local: Thurs, Nov 12 2009 1:06 am
Subject: Re: Topological sort

On Wed, Nov 11, 2009 at 2:04 PM, Nick Day <nicke...@gmail.com> wrote:
> Hi,

> I've been trying to implement a topological sort and have been
> struggling a bit. I have a map of symbol vs collection of symbols
> like:

> {a [b c], b [c], c [nil]}

> which can be read as 'a' depends on 'b' and 'c', 'b' depends on 'c'
> and 'c' doesn't depend on anything.  I've been trying to write
> something that returns a collection of the dependencies in order (c,
> b, a) but so far I've only been able to do it using a ref to store
> intermediate output of the sorting.  I was wondering if anyone has
> already done something similar?

You mean pure functionally?

First, I'd represent no dependencies as an empty vector rather than a vector
with a single nil in it.

Then, consider how you get the first few entries: you find all the nodes
with no dependencies.

How do you get the next few? The nodes whose only dependencies are nodes you
already have.

This suggests the algorithm:

(defn find-a-node [deps already-have-nodes]
  (some (fn [[k v]] (if (empty? (remove already-have-nodes v)) k)) deps))

This will return a key from deps whose corresponding value contains no
objects not in the set already-have-nodes.

Next, we just need to apply it repeatedly until it comes up empty:

(defn order-nodes [deps]
  (loop [deps deps already-have-nodes #{} output []]
    (if (empty? deps)
      output
      (if-let [item (find-a-node deps already-have-nodes)]
        (recur
          (dissoc deps item)
          (conj already-have-nodes item)
          (conj output item))
        (throw (Exception. "Circular dependency."))))))

This seems to work:

user=> (order-nodes {1 [2 3] 2 [3] 3 []})
[3 2 1]
user=> (order-nodes {1 [2 3] 2 [3] 3 [2]})
#<CompilerException java.lang.Exception: Circular dependency.
(NO_SOURCE_FILE:0)>

No refs, atoms, or other mutable state, or cheating using Java mutable
objects or set-var-root!, etc.; rewriting the above with iterate, reduce, or
similar instead of loop/recur is left as an exercise for the reader. :)


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Nick Day  
View profile  
 More options Nov 16, 8:38 am
From: Nick Day <nicke...@gmail.com>
Date: Mon, 16 Nov 2009 05:38:44 -0800 (PST)
Local: Mon, Nov 16 2009 8:38 am
Subject: Re: Topological sort
brilliant, this has been very helpful - thanks to both for taking the
time to answer!

On Nov 12, 6:06 am, John Harrop <jharrop...@gmail.com> wrote:


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Christophe Grand  
View profile  
 More options Nov 16, 10:43 am
From: Christophe Grand <christo...@cgrand.net>
Date: Mon, 16 Nov 2009 16:43:46 +0100
Local: Mon, Nov 16 2009 10:43 am
Subject: Re: Topological sort
Just for the fun of writing it:

(defn topological-sort [x]
  (mapcat
    #(for [[k v] % :when (empty? v)] k)
    (take-while seq
      (iterate #(into {} (for [[k v] % :when (seq v)] [k (mapcat % v)])) x))))

user=> (topological-sort {1 [2 3] 2 [3] 3 []})
(3 2 1)

Note that it's not the same algorithm as Jon's and it doesn't detect cycles.

Christophe

--
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (en)

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google