Hi,
I have a further question regarding this problem. Just to recap, I am
ordering narrative scenes by time and precedence. In other words, all
scenes MUST be ordered in time (this constraint overrides all others)
and also, scenes which occur at the same time are ordered by causality -
this is implemented by searching for the maximal value of the sum of all
scenes which have been identified as having a precedence scene. I have a
function {IsPreced X Y} which returns true if X is a preceding scene of
Y, false otherwise.
The main solver script is this:
fun {Sorter Ls}
%%Ls is a list of unsorted scenes
proc {$ Root}
Preced
%%a list of indexes to the actual scene list
Scenes={List.number 1 {Length Ls} 1}
%%a FD record for the position of each scene
%%ie Position.X is the position of scene X
Position={FD.record position Scenes 1#{Length Scenes}}
%%FD var for number of satisfied precedence constraints
NumPrec={FD.decl}
in
%%a record representing any precedent scenes found
Preced={FD.record preced Scenes 0#{Length Scenes}}
%%only one precedence action used at a time
%%ie a scene can not be a precedence of another scene more than once
for X in 1..{Length Scenes} do
{FD.atMost 1 Preced X}
end
Root=r(numprecedences: NumPrec position: Position preced : Preced)
{FD.distinct Position}
%%just to limit NumPrec to a sensible value
NumPrec<:{Length @AllScenes}
%%if time of X is before time of Y then order accordingly
for X in Scenes do
for Y in Scenes do
if X\=Y andthen {Utils.getDetails scene time {Nth Ls X}
}<{Utils.getDetails scene time {Nth Ls Y}} then
Position.X<:Position.Y
end
%%if X is a precedent scene for Y, update Preced record if not
already found
if X\=Y andthen {IsPreced X Y} then
if {Not {IsDet Preced.Y}} then Preced.Y=:X end
end
end
end
%%finally, sum the number of scenes which have matching precedent
scenes
{FD.sum for X in Scenes collect:Collect do
for Y in Scenes do
if X\=Y andthen {IsPreced X Y} then %X is a precedent
of Y
{Collect (Position.X=<:Position.Y)}
end
end
end '=:' NumPrec}
%%search for highest number of matching precedences first
{FD.distribute generic(order:naive value:max) [NumPrec]}
%%then look for positions
{FD.distribute ff Position}
%%and keep Preced record updated
{FD.distribute naive Preced}
end
end
Preced is a record which contains fields that are either 0 or a
reference to a matching precedence scene. The number of fields which are
NOT 0 should in theory match the value of NumPrec.
This script gives a single solution which looks okay at first glance.
NumPrec is determined as 6 and I get 6 entries in my Preced record
matching the 6 identified precedences.
However, if I search for further solutions in the explorer, I can find
solutions which have 7 or more entries in the Preced record (ie 7 or
more matched precedences) but NumPrec is still determined as 6 - why
isn't this 7 or more?
This is something I am at a loss to explain. If anyone could shed any
light on this I would be extremely grateful.
Also, as an afterthought, I wondered if the distribution steps for
Position and Preced can be combined into one statement without affecting
the script?
Regards
Mark
Raphael Collet wrote:
Dear Mark,
I wrote "simple", because this solution might be very efficient if
many of the preferences are conflicting. The issue is that a
propagator like
B = (X =<: Y)
will perform no propagation until either B is known, or both X and Y
are known. To get maximal performance, you need to have as much
propagation as possible. A good heuristics might be to determine the
B's as soon as possible. Something like
Bs = for X in Scenes collect:Collect do
for Y in Scenes do
if X\=Y andthen {IsPreced X Y} then %X is a precedent of Y
{Collect (Position.X=<:Position.Y)}
end
end
end
{FD.sum Bs '=:' NumPrec}
%% determine NumPrec, then the Bs, trying high values first, then the
positions
{FD.distribute generic(order:naive value:max) NumPrec|Bs}
{FD.distribute ff Position}
I haven't tried it, but that's something you could give a try at.
Cheers,
Raphael
On Thu, Feb 25, 2010 at 1:00 PM, mark richardson
<[email protected] <mailto:[email protected]>> wrote:
Hi,
Thank you so much for your help with this.
I did have another small problem that I have now solved - I had
{IsPreced X Y} returning true if Y had no precedences at all which
was causing chaos.
(Oh and I deliberately left the distribution of the position
vector out of the message, but thank you for your reminder :+) )
You say that this approach is a 'simple way to maximize the number
of preferences'.
I might regret asking this, but is there a way which is less
simple, but perhaps better?
Regards
Mark
Raphael Collet wrote:
Dear Mark,
Yes, I think you got it right. That is a simple way to maximize
the number of preferences. (Just don't forget to distribute the
vector Position in your script.)
Cheers,
Raphael
On Thu, Feb 25, 2010 at 12:26 PM, mark richardson
<[email protected] <mailto:[email protected]>> wrote:
Hi,
I've modified the script slightly to this:
{FD.sum
for X in Scenes collect:Collect do
for Y in Scenes do
if X\=Y andthen {IsPreced X Y} then %X is a precedent of Y
{Collect (Position.X=<:Position.Y)}
end
end
end '=:' NumPrec}
I realised the mistake I was making with X and Y instead of
Position.X and Position.Y and mistyping 'and' instead of
'andthen'
Regards
Mark
--
Mark Richardson MBCS
Research Assistant
University of Teesside, UK
Email: [email protected]
<mailto:[email protected]>
[email protected] <mailto:[email protected]>
Skype: mark.richardson.
_________________________________________________________________________________
mozart-users mailing list
[email protected] <mailto:[email protected]>
http://www.mozart-oz.org/mailman/listinfo/mozart-users
------------------------------------------------------------------------
_________________________________________________________________________________
mozart-users mailing list [email protected]
<mailto:[email protected]>
http://www.mozart-oz.org/mailman/listinfo/mozart-users
--
Mark Richardson MBCS
Research Assistant
University of Teesside, UK
Email: [email protected] <mailto:[email protected]>
[email protected] <mailto:[email protected]>
Skype: mark.richardson.
_________________________________________________________________________________
mozart-users mailing list
[email protected] <mailto:[email protected]>
http://www.mozart-oz.org/mailman/listinfo/mozart-users
------------------------------------------------------------------------
_________________________________________________________________________________
mozart-users mailing list
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users
--
Mark Richardson MBCS
Research Assistant
University of Teesside, UK
Email: [email protected]
[email protected]
Skype: mark.richardson.
_________________________________________________________________________________
mozart-users mailing list
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users