--
You received this message because you are subscribed to the Google Groups "CLIPSESG" group.
To post to this group, send email to CLIP...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/CLIPSESG?hl=en
--> IF YOU NO LONGER WANT TO RECEIVE EMAIL <--
Visit this group at http://groups.google.com/group/CLIPSESG?hl=en
Click on "Edit my membership" link.
Select the "No Email" radio button.
Click the "Save these settings" button.
--> IF YOU WANT TO UNSUBSCRIBE <--
Visit this group at http://groups.google.com/group/CLIPSESG?hl=en
Sign in
Click on "Edit my membership" link.
Click the "Unsubscribe" button.
Note: This appears to be the most reliable way to unsubscribe
Alternately, send email to CLIPSESG-u...@googlegroups.com. You will receive an email which you must respond to as well to unsubscribe. Clicking the link mentioned in the unsubscribe reply does not appear to work reliably.
---
You received this message because you are subscribed to a topic in the Google Groups "CLIPSESG" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clipsesg/RsUUog8YoDs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clipsesg+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clipsesg/929e1b00-23b9-433e-82dd-5ad90f54fb31n%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clipsesg/e00897c7-0a54-48a9-bfcf-45d44e42d5e8n%40googlegroups.com.
Here's a version that seems to be faster on all points (but I checked only a few cases). There's some redundancy in some template slots, but it's convenient.
Rule randomly-create-edges could probably be replaced by some extension of function init.
(defglobal ?*max-length* = 20)
(defglobal ?*cycle-count* = 0)
(deftemplate vertex
(slot vId (type INTEGER))
)
(deftemplate edge
(slot fromVid (type INTEGER))
(slot toVid (type INTEGER))
)
(deftemplate loopless-open-path
(slot length (type INTEGER)) ; = number of edges = number of vertices - 1
(slot first-vertex (type INTEGER)) ; should always be the smallest of all the vertices
(multislot vertices) ; contains both first-vertex and last-vertex; all vertices should be different
(slot last-vertex (type INTEGER))
)
(deftemplate cycle
;;; closed path with no inner loops
(slot length (type INTEGER)) ; = number of edges = number of different vertices
(multislot edges)
)
(deffunction print-cycle (?l $?vertices)
;;; ?l = number of edges = number of different vertices
(printout t "cycle[" ?l "]: ")
(loop-for-count (?i 1 ?l) do
(printout t (nth$ ?i ?vertices) "->")
)
(printout t (nth$ 1 ?vertices))
(printout t crlf)
)
(deffunction init(?n)
;;; create ?n vertices
(bind ?*cycle-count* 0)
(loop-for-count (?vId 1 ?n) do
(assert (vertex (vId ?vId)))
)
)
(defrule randomly-create-edges
(declare (salience 20))
(vertex (vId ?vid1))
(vertex (vId ?vid2))
=>
(if (= (random 1 1000) 1) then
(assert (edge (fromVid ?vid1) (toVid ?vid2)))
)
(if (= (random 1 1000) 1) then
(assert (edge (fromVid ?vid2) (toVid ?vid1)))
)
)
(defrule FindSimpleCycles
(declare (salience 10))
(loopless-open-path (length ?l) (first-vertex ?vId1) (vertices $?vert) (last-vertex ?last))
(edge (fromVid ?last) (toVid ?vId1))
=>
(assert (cycle (length (+ ?l 1)) (edges $?vert ?vId1)))
(bind ?*cycle-count* (+ ?*cycle-count* 1))
; (print-cycle (+ ?l 1) ?vert)
)
( defrule loopless-path-2
(edge (fromVid ?vId1 ) (toVid ?vId2&:(<> ?vId2 ?vId1)))
(edge (fromVid ?vId2&:(< ?vId1 ?vId2)) (toVid ?vId3&:(<> ?vId3 ?vId1 ?vId2)))
=>
(assert (loopless-open-path (length 2) (first-vertex ?vId1) (vertices ?vId1 ?vId2 ?vId3) (last-vertex ?vId3) ))
)
(defrule extend-loopless-open-path
(loopless-open-path (length ?l&:(< ?l ?*max-length*)) (first-vertex ?vId1) (vertices $?vert) (last-vertex ?last))
(edge (fromVid ?last) (toVid ?newVid&:(< ?newVid ?vId1)&:(not (member$ ?newVid $?vert))))
=>
(assert (loopless-open-path (length (+ ?l 1)) (first-vertex ?vId1) (vertices $?vert ?newVid) (last-vertex ?newVid)))
)
;;; tests
(reset)
(release-mem)
(init 1000)
(timer (run))
?*cycle-count*
(timer (reset))
CLIPS> (timer (clear))
4.91142272949219e-05
CLIPS> (load "edge.clp")
CLIPS> (timer (load-facts "edge.fct"))
31.1876230239868
CLIPS> (timer (run))
0.331338167190552
CLIPS> (timer (reset))
3.35309410095215
Notes:
1) Unsurprisingly, most of the time is spent in "load-facts" (i.e. when propagation occurs in the Rete)
2) If repeating the same, there are some small random fluctuations
3) Changing between 64.x and 63.x, or using CLIPS-IDE instead of CLIPS-core, fluctuations remain in the same ranges.
(length$ (get-fact-list))
65182
CLIPS> (length$ (find-all-facts ((?f vertex)) TRUE))
1000
CLIPS> (length$ (find-all-facts ((?f edge)) TRUE))
2009
CLIPS> (length$ (find-all-facts ((?f cycle)) TRUE))
62172