Ignore:
Timestamp:
05/02/19 23:50:27 (5 years ago)
Author:
Maciej Komosinski
Message:

Added another, improved way of calculating dissimilarity of two creatures/models. Details and comparisons in https://doi.org/10.1007/978-3-030-16692-2_8

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/model/similarity/simil_match.cpp

    r361 r869  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    88
    99/** Creates an empty matching for two objects of specified size.
    10         @param Obj0Size Size of the first object. Must be positive.
    11         @param Obj1Size Size of the second object. Must be positive.
     10                @param Obj0Size Size of the first object. Must be positive.
     11                @param Obj1Size Size of the second object. Must be positive.
    1212 */
    1313SimilMatching::SimilMatching(int Obj0Size, int Obj1Size)
    1414{
    15     // assure that sizes of objects are positive
    16     assert(Obj0Size > 0);
    17     assert(Obj1Size > 0);
    18 
    19     // create necessary vectors
    20     m_apvMatched[0] = new std::vector<int>(Obj0Size);
    21     m_apvMatched[1] = new std::vector<int>(Obj1Size);
    22 
    23     // assure that vectors are created
    24     assert(m_apvMatched[0] != NULL);
    25     assert(m_apvMatched[1] != NULL);
    26 
    27     // fill vectors with "unmatched" indicator
     15        // assure that sizes of objects are positive
     16        assert(Obj0Size > 0);
     17        assert(Obj1Size > 0);
     18
     19        // create necessary vectors
     20        m_apvMatched[0] = new std::vector<int>(Obj0Size);
     21        m_apvMatched[1] = new std::vector<int>(Obj1Size);
     22
     23        // assure that vectors are created
     24        assert(m_apvMatched[0] != NULL);
     25        assert(m_apvMatched[1] != NULL);
     26
     27        // fill vectors with "unmatched" indicator
    2828        for (unsigned int i = 0; i < m_apvMatched[0]->size(); i++)
    29     {
    30         m_apvMatched[0]->operator[](i) = -1;
    31     }
     29        {
     30                m_apvMatched[0]->operator[](i) = -1;
     31        }
    3232        for (unsigned int i = 0; i < m_apvMatched[1]->size(); i++)
    33     {
    34         m_apvMatched[1]->operator[](i) = -1;
    35     }
     33        {
     34                m_apvMatched[1]->operator[](i) = -1;
     35        }
    3636}
    3737
    3838/** A copying constructor.
    39         @param Source The object to be copied.
     39                @param Source The object to be copied.
    4040 */
    4141SimilMatching::SimilMatching(const SimilMatching &Source)
    4242{
    43     // copy the vectors of the actual matching
    44     m_apvMatched[ 0 ] = new std::vector<int>(* (Source.m_apvMatched[ 0 ]));
    45     m_apvMatched[ 1 ] = new std::vector<int>(* (Source.m_apvMatched[ 1 ]));
    46 
    47     // assure that vectors are created
    48     assert(m_apvMatched[0] != NULL);
    49     assert(m_apvMatched[1] != NULL);
     43        // copy the vectors of the actual matching
     44        m_apvMatched[0] = new std::vector<int>(*(Source.m_apvMatched[0]));
     45        m_apvMatched[1] = new std::vector<int>(*(Source.m_apvMatched[1]));
     46
     47        // assure that vectors are created
     48        assert(m_apvMatched[0] != NULL);
     49        assert(m_apvMatched[1] != NULL);
    5050}
    5151
     
    5454SimilMatching::~SimilMatching()
    5555{
    56     // delete vectors of matching
    57     delete m_apvMatched[0];
    58     delete m_apvMatched[1];
     56        // delete vectors of matching
     57        delete m_apvMatched[0];
     58        delete m_apvMatched[1];
    5959}
    6060
    6161/** Gets size of the specified object.
    62         @param Index of an object (must be 0 or 1).
    63         @return Size of the object (in elements).
     62                @param Index of an object (must be 0 or 1).
     63                @return Size of the object (in elements).
    6464 */
    6565int SimilMatching::GetObjectSize(int Obj)
    6666{
    67     // check parameter
    68     assert((Obj == 0) || (Obj == 1));
    69 
    70     // return the result
    71     return m_apvMatched[ Obj ]->size();
     67        // check parameter
     68        assert((Obj == 0) || (Obj == 1));
     69
     70        // return the result
     71        return m_apvMatched[Obj]->size();
    7272}
    7373
    7474/** Matches elements given by indices in the given objects.
    75         @param Obj0 Index of the first object. Must be 0 or 1.
    76         @param index0 Index of element in the first object. Must be a valid index
    77         ( >= 0 and < size of the object).
    78         @param Obj1 Index of the second object. Must be 0 or 1 and different from Obj0.
    79         @param Index1 index of element in the second object. Must be a valid index
    80         ( >= 0 and < size of the object).
     75                @param Obj0 Index of the first object. Must be 0 or 1.
     76                @param index0 Index of element in the first object. Must be a valid index
     77                ( >= 0 and < size of the object).
     78                @param Obj1 Index of the second object. Must be 0 or 1 and different from Obj0.
     79                @param Index1 index of element in the second object. Must be a valid index
     80                ( >= 0 and < size of the object).
    8181
    8282 */
    8383void SimilMatching::Match(int Obj0, int Index0, int Obj1, int Index1)
    8484{
    85     // check parameters of object 0
    86     assert((Obj0 == 0) || (Obj0 == 1));
    87     assert((Index0 >= 0) && (Index0 < (int) m_apvMatched[Obj0]->size()));
    88     // check parameters of object 1
    89     assert(((Obj1 == 0) || (Obj1 == 1)) && (Obj0 != Obj1));
    90     assert((Index1 >= 0) && (Index1 < (int) m_apvMatched[Obj1]->size()));
    91 
    92     // match given elements
    93     // matching_Obj0(Index0) = Index1
    94     m_apvMatched[ Obj0 ]->operator[](Index0) = Index1;
    95     // matching_Obj1(Index1) = Index0
    96     m_apvMatched[ Obj1 ]->operator[](Index1) = Index0;
     85        // check parameters of object 0
     86        assert((Obj0 == 0) || (Obj0 == 1));
     87        assert((Index0 >= 0) && (Index0 < (int)m_apvMatched[Obj0]->size()));
     88        // check parameters of object 1
     89        assert(((Obj1 == 0) || (Obj1 == 1)) && (Obj0 != Obj1));
     90        assert((Index1 >= 0) && (Index1 < (int)m_apvMatched[Obj1]->size()));
     91
     92        // match given elements
     93        // matching_Obj0(Index0) = Index1
     94        m_apvMatched[Obj0]->operator[](Index0) = Index1;
     95        // matching_Obj1(Index1) = Index0
     96        m_apvMatched[Obj1]->operator[](Index1) = Index0;
    9797}
    9898
    9999/** Checks if the given element in the given object is already matched.
    100         @param Obj Index of an object (must be 0 or 1).
    101         @param Index Index of an element in the given object. Must be a valid index
    102         ( >=0 and < size of the object).
    103         @return true if the given element is matched, false otherwise.
     100                @param Obj Index of an object (must be 0 or 1).
     101                @param Index Index of an element in the given object. Must be a valid index
     102                ( >=0 and < size of the object).
     103                @return true if the given element is matched, false otherwise.
    104104 */
    105105bool SimilMatching::IsMatched(int Obj, int Index)
    106106{
    107     // check parameters
    108     assert((Obj == 0) || (Obj == 1));
    109     assert((Index >= 0) && (Index < (int) m_apvMatched[ Obj ]->size()));
    110 
    111     // check if the element is matched
    112     if (m_apvMatched[ Obj ]->operator[](Index) >= 0)
    113     {
    114         return true;
    115     }
    116     else
    117     {
    118         return false;
    119     }
     107        // check parameters
     108        assert((Obj == 0) || (Obj == 1));
     109        assert((Index >= 0) && (Index < (int)m_apvMatched[Obj]->size()));
     110
     111        // check if the element is matched
     112        if (m_apvMatched[Obj]->operator[](Index) >= 0)
     113        {
     114                return true;
     115        }
     116        else
     117        {
     118                return false;
     119        }
    120120}
    121121
    122122/** Gets index of the element thet is matched in the other object withe the element given
    123         by parameters.
    124         @param Obj Index of an object (must be 0 or 1).
    125         @param Index Index of checked element in the given object.
    126         @return Index of the element (in the other organism) that is matched with the given
    127         element. WARNING! If the given element is not matched, the result may be smaller than 0
    128         (check IsMatched() before using GetMatchedIndex()).
     123                by parameters.
     124                @param Obj Index of an object (must be 0 or 1).
     125                @param Index Index of checked element in the given object.
     126                @return Index of the element (in the other organism) that is matched with the given
     127                element. WARNING! If the given element is not matched, the result may be smaller than 0
     128                (check IsMatched() before using GetMatchedIndex()).
    129129 */
    130130int SimilMatching::GetMatchedIndex(int Obj, int Index)
    131131{
    132     // check parameters
    133     assert((Obj == 0) || (Obj == 1));
    134     assert((Index >= 0) && (Index < (int) m_apvMatched[ Obj ]->size()));
    135 
    136     // return the index of the matched element
    137     return m_apvMatched[ Obj ]->operator[](Index);
    138 }
    139 
    140 /** Checks if the matching is already full, i.e. if the smaller object already has all its 
    141         elements matched.
    142         @return true if matching is full, false otherwise.
     132        // check parameters
     133        assert((Obj == 0) || (Obj == 1));
     134        assert((Index >= 0) && (Index < (int)m_apvMatched[Obj]->size()));
     135
     136        // return the index of the matched element
     137        return m_apvMatched[Obj]->operator[](Index);
     138}
     139
     140/** Checks if the matching is already full, i.e. if the smaller object already has all its
     141                elements matched.
     142                @return true if matching is full, false otherwise.
    143143 */
    144144bool SimilMatching::IsFull()
    145145{
    146     // assume that the matching is full
    147     bool bResult = true;
    148     // index of the smallest object
    149     int nObj;
    150 
    151     // find the smallest object (its index)
    152     if (m_apvMatched[ 0 ]->size() < m_apvMatched[ 1 ]->size())
    153     {
    154         nObj = 0;
    155     }
    156     else
    157     {
    158         nObj = 1;
    159     }
    160 
    161     // check if all elements of the smallest object are matched
     146        // assume that the matching is full
     147        bool bResult = true;
     148        // index of the smallest object
     149        int nObj;
     150
     151        // find the smallest object (its index)
     152        if (m_apvMatched[0]->size() < m_apvMatched[1]->size())
     153        {
     154                nObj = 0;
     155        }
     156        else
     157        {
     158                nObj = 1;
     159        }
     160
     161        // check if all elements of the smallest object are matched
    162162        for (unsigned int nElem = 0; nElem < m_apvMatched[nObj]->size(); nElem++)
    163     {
    164         if (m_apvMatched[ nObj ]->operator[](nElem) < 0)
    165         {
    166             // if any element is not matched, the result is false
    167             bResult = false;
    168             break;
    169         }
    170     }
    171 
    172     // return the result
    173     return bResult;
     163        {
     164                if (m_apvMatched[nObj]->operator[](nElem) < 0)
     165                {
     166                        // if any element is not matched, the result is false
     167                        bResult = false;
     168                        break;
     169                }
     170        }
     171
     172        // return the result
     173        return bResult;
    174174}
    175175
    176176/** Checks if the matching is empty (i.e. none of elements is matched).
    177     @return true if matching is empty, otherwise - false.
     177        @return true if matching is empty, otherwise - false.
    178178 */
    179179bool SimilMatching::IsEmpty()
    180180{
    181     // result - assume that matching is empty
    182     bool bResult = true;
    183 
    184     // matching is empty if either of objects has only unmatched elements
    185     // so it may be first object
    186     int nObj = 0;
     181        // result - assume that matching is empty
     182        bool bResult = true;
     183
     184        // matching is empty if either of objects has only unmatched elements
     185        // so it may be first object
     186        int nObj = 0;
    187187        for (unsigned int nElem = 0; nElem < m_apvMatched[nObj]->size(); nElem++)
    188     {
    189         if (m_apvMatched[ nObj ]->operator[](nElem) >= 0)
    190         {
    191             // if any element of the object is matched (unmatched objects have (-1))
    192             bResult = false;
    193             break;
    194         }
    195     }
    196 
    197     // return the result from the loop
    198     return bResult;
     188        {
     189                if (m_apvMatched[nObj]->operator[](nElem) >= 0)
     190                {
     191                        // if any element of the object is matched (unmatched objects have (-1))
     192                        bResult = false;
     193                        break;
     194                }
     195        }
     196
     197        // return the result from the loop
     198        return bResult;
    199199}
    200200
     
    203203void SimilMatching::Empty()
    204204{
    205     for (int iObj = 0; iObj < 2; iObj++) // a counter of objects
    206     {
    207         // for each object in the matching
     205        for (int iObj = 0; iObj < 2; iObj++) // a counter of objects
     206        {
     207                // for each object in the matching
    208208                for (unsigned int iElem = 0; iElem < m_apvMatched[iObj]->size(); iElem++) // a counter of objects' elements
    209         {
    210             // for each element iElem for the object iObj
    211             // set it as unmatched (marker: -1)
    212             m_apvMatched[ iObj ]->operator[](iElem) = -1;
    213         }
    214     }
    215 
    216     // the exit condition
    217     assert(IsEmpty() == true);
     209                {
     210                        // for each element iElem for the object iObj
     211                        // set it as unmatched (marker: -1)
     212                        m_apvMatched[iObj]->operator[](iElem) = -1;
     213                }
     214        }
     215
     216        // the exit condition
     217        assert(IsEmpty() == true);
    218218}
    219219
     
    222222void SimilMatching::PrintMatching()
    223223{
    224     int nBigger;
    225 
    226     // check which object is bigger
    227     if (m_apvMatched[ 0 ]->size() >= m_apvMatched[ 1 ]->size())
    228     {
    229         nBigger = 0;
    230     }
    231     else
    232     {
    233         nBigger = 1;
    234     }
    235 
    236     // print first line - indices of objects
    237     printf("[ ");
     224        int nBigger;
     225
     226        // check which object is bigger
     227        if (m_apvMatched[0]->size() >= m_apvMatched[1]->size())
     228        {
     229                nBigger = 0;
     230        }
     231        else
     232        {
     233                nBigger = 1;
     234        }
     235
     236        // print first line - indices of objects
     237        printf("[ ");
    238238        for (unsigned int i = 0; i < m_apvMatched[nBigger]->size(); i++)
    239     {
    240         printf("%2d ", i);
    241     }
    242     printf("]\n");
    243 
    244     // print second line and third - indices of elements matched with elements of the objects
    245     for (int nObj = 0; nObj < 2; nObj++)
    246     {
    247         // for both objects - print out lines of matched elements
    248         printf("[ ");
     239        {
     240                printf("%2d ", i);
     241        }
     242        printf("]\n");
     243
     244        // print second line and third - indices of elements matched with elements of the objects
     245        for (int nObj = 0; nObj < 2; nObj++)
     246        {
     247                // for both objects - print out lines of matched elements
     248                printf("[ ");
    249249                for (unsigned int i = 0; i < m_apvMatched[nObj]->size(); i++)
    250         {
    251             if (IsMatched(nObj, i))
    252             {
    253                 // if the element is matched - print the index
    254                 printf("%2d ", GetMatchedIndex(nObj, i));
    255             }
    256             else
    257             {
    258                 // if the element is not matched - print "X"
    259                 printf(" X ");
    260             }
    261         }
    262         printf("]\n");
    263     }
    264 }
     250                {
     251                        if (IsMatched(nObj, i))
     252                        {
     253                                // if the element is matched - print the index
     254                                printf("%2d ", GetMatchedIndex(nObj, i));
     255                        }
     256                        else
     257                        {
     258                                // if the element is not matched - print "X"
     259                                printf(" X ");
     260                        }
     261                }
     262                printf("]\n");
     263        }
     264}
Note: See TracChangeset for help on using the changeset viewer.