JESS: [EXTERNAL] question on sorting
"Felix Chan" <[email protected]> Mon, 5 Mar 2012 17:57:25 -0800
| Newsgroups | gmane.comp.java.jess |
|---|---|
| Message-ID | <CAEg6sM__HoyzmRVPw7SCfi+UfBQvBFCcuRdkdPHLPEieJD3iBQ@mail.gmail.com> |
Hi,
I need to rank a set of facts based on a score. I came up with the idea
that I first find the top ranked fact using one rule, followed by ranking
the remaining facts using another rule.
It works. But I suspect that this method will not be very efficient if I
have to rank thousands of facts, rather than just 4 as in my example below.
I also suspect that someone must have solved this sorting problem in a much
better way.
Any recommendation would be much appreciated. Many thanks.
Felix
/******************************************************************/
(deftemplate driver (slot driverId) (slot score) (slot rank))
(defrule rankFirstDriver
"find top ranked driver if none has been ranked"
(not (driver (rank ~nil))) ; if no drivers have been
ranked
?d1 <- (driver (score ?s1)) ; if we can find a driver with
score s1
(not (driver (score ?s2&:(> ?s2 ?s1)))) ; but no other drivers have a
score higher than s1
=>
(modify ?d1 (rank 1))
)
(defrule rankOtherDrivers
"rank other drivers after top ranked drivers have been found"
(driver (rank 1)) ; if top ranked driver has been found
; find lowest ranked driver
(driver (rank ?r1&~nil))
(not (driver (rank ?r2&~nil&:(> ?r2 ?r1))))
; find unranked driver with highest score
?d <- (driver (score ?s1) (rank nil))
(not (driver (score ?s2&:(> ?s2 ?s1)) (rank nil)))
=>
(modify ?d (rank (+ ?r1 1)))
)
(reset)
(assert (driver (driverId 1) (score 100)))
(assert (driver (driverId 2) (score 50)))
(assert (driver (driverId 3) (score 200)))
(assert (driver (driverId 4) (score 75)))
(run)
(facts)
/*********************************/
/***** OUTPUT **************/
f-0 (MAIN::initial-fact)
f-1 (MAIN::driver (driverId 1) (score 100) (rank 2))
f-2 (MAIN::driver (driverId 2) (score 50) (rank 4))
f-3 (MAIN::driver (driverId 3) (score 200) (rank 1))
f-4 (MAIN::driver (driverId 4) (score 75) (rank 3))
For a total of 5 facts in module MAIN.