Hi Malte. Hope I'm not too late to the party :-)

Here's some sample code that appears to work on my small sample data. It's not easy to come up with good test data here - nothing obvious could generate realistic test data by program.

Summary is

1. deal with all equality cases first. For every set of equal-age names, we use the same name (first one alphabetically) for the 'younger' relationship table.

2. normalize the realtionships (always younger, replace by same-age equivalent

3. for each name, keep two lists - those older and still to be handled, and those older but already dealt with

4. repeatedly, take a name from the first list and try to move it to the second. If this name itself has nothing left on its 'still-to-do' list then we have completely moved this name - remove it from the still-to-do list.

This should be reasonably efficient, though there are possible optimizations by keeping back-pointers - so let me know if this is too slow when you start using thousands of names,

-- Alex.

global gSameAge   -- array of those who are the same age
global gRelate -- array of direct (i.e. defined) relationships
global gOlder -- array containing (one per line) all those who are known older than the key
global gOlderStillToDo

on c
   put URL "file:~/data.txt" into tData

   put empty into gSameAge
   put empty into gOlder
   put empty into gOlderStillToDo
   -- deal with all the equal age info
-- for each group of same-age people, we will use the first alphabetically
   -- step 1. normalize each individual equality to be alphabetocal
   -- step 2. sort the set of equality facts to be alphabetical
   -- step 3. for each subsequent name, store the earliest equal one
   repeat for each line  L in tData
      if word 2 of L = "=" then
         if word 1 of L < word 3 of L then
            put word 1 of L && word 3 of L & CR after tEqual
         else
            put word 3 of L && word 1 of L & CR after tEqual
         end if
      end if
   end repeat
   -- sort these to handle cases like a=b and b=d
   sort lines of tEqual
   repeat for each line L in tEqual
      if gSameAge[word 1 of L] is not empty then
         put gSameAge[word 1 of L] into gSameAge[word 2 of L]
      else
         put word 1 of L into gSameAge[word 2 of L]
      end if
   end repeat

   -- now normalize the direct relationships
   put empty into gRelate
   repeat for each line  L in tData
      if word 2 of L = "<" then
         put sample(word 1 of L) into t1
         put sample(word 3 of L) into t2
         put t1 && t2 & CR after tUnequal
      end if
   end repeat

   -- first the direct relationships
   repeat for each line L in tUnequal
      put word 2 of L & CR after gOlderStillToDo[word 1 of L]
   end repeat

   repeat 10000 timeS -- forever, but avoid infinite loops
      put 0 into tNeedToDoAgain
      put the keys of gOlderStillToDo into tKeys
      -- for each one that still has something to do
      repeat for each line K in tKeys
         put empty into tNewlyFound
         put empty into tStillToDo
         repeat for each line L in gOlderStillToDo[K]
            if L is not among the keys of gOlderStillToDo then
-- add this older one, *and* all names known to be older than it
               put L & CR after gOlder[K]
               put gOlder[L] & CR after tNewlyFound
else -- this one hasn't yet been done, so we may need another iteration
               put L & CR after tStillToDo
               add 1 to tNeedToDoAgain
            end if
         end repeat
         if tStillToDo is empty then
            delete variable gOlderStillToDo[K]
         else
            put tStillToDo into gOlderStillToDo[K]
         end if
         repeat for each line L in tNewlyFound
if L = K then -- there is a loop in age info - i.e. bad input !!
               ask "loop" && L && K
               exit to top
            end if
if L is not among the lines gOlder[K] and L is not among the lines of gOlderStillToDo[K] then
               put L & CR after gOlderStillToDo[K]
               add 1 to tNeedToDoAgain
            end if
         end repeat
      end repeat
      if tNeedToDoAgain = 0 then exit repeat
   end repeat
   repeat for each key K in gOlder
      put K & "--->" & CR after field "F"
      put gOlder[K] after field "F"

   end repeat
end c

function sample pA
   if gSameAge[pA] is not empty then
      return gSameAge[pA]
   else
      return pA
   end if
end sample




On 08/03/2011 18:49, Malte Brill wrote:
Thanks for the head ups folks,

Björnke and Mark: I do not have the exact ages to sort by. All I do have is 
relations:

Malte is older than Björnke
Mark is older than Malte

And now I need to compute if it is valid to say:
- Björnke is older than Mark  (obviously not)
- Björnke is the same age as Mark (obviously not)
- Björnke is younger than Mark. (That´s the one)

What comes easy to the human brain in fact appears to be a lot more difficult 
when having to be tackled computationaly.

Chris: Yes, I want such a list in the end. But in order to finally get this I 
will need to tell the machine which relations are legal first (the user tells 
which relations there are) and ideally filter out the data for relations that 
make no sense. Now I wish it was easy to tell the machine to just use logic and 
make sense itself :D This comparison has to be done for thousands of entities 
(children in this case).

Cheers,

Malte


_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode



_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

Reply via email to