neoml
neoml copied to clipboard
CMatchingGenerator misses some obvious matches
For some inputs CMatchingGenerator generates suboptimal matchings. Certain objects are effectively left unmatched, even though they have a match in the other set.
Here is a test I wrote that should pass but is currently failing. I found a few "bad" examples, this is one of the smallest. Here, two checks are passing, but the last one is failing: EXPECT_EQ( 7, FindMatchForLeft( 5 ) )
. Instead, left no.5 is matched to a different element with a score of 0.
TEST( CMatchingGenerator, UniqueMatches6x8 )
{
struct CMyPair {
typedef int Quality;
int LeftIndex = -1;
int RightIndex = -1;
Quality Score = 0;
Quality Penalty() const { return 1 - Score; }
};
const int numLeft = 6;
const int numRight = 8;
const int pairScores[numRight][numLeft] = {
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0}, // Left #3 matches right #5
{0, 0, 0, 0, 1, 0}, // Left #4 matches right #6
{0, 0, 0, 0, 0, 1} // Left #5 matches right #7
};
NeoML::CMatchingGenerator< CMyPair > generator( numLeft, numRight, 0, INT_MAX );
for( int leftInd = 0; leftInd < numLeft; ++leftInd ) {
for( int rightInd = 0; rightInd < numRight; ++rightInd ) {
CMyPair& pair = generator.PairMatrix()(leftInd, rightInd);
pair.LeftIndex = leftInd;
pair.RightIndex = rightInd;
pair.Score = pairScores[rightInd][leftInd];
}
}
generator.Build();
CArray<CMyPair> matching;
generator.GetNextMatching( matching );
const auto& FindMatchForLeft = [&matching]( int leftInd )
{
for( const CMyPair& pair : matching ) {
if( pair.LeftIndex == leftInd ) {
return pair.RightIndex;
}
}
return NotFound;
};
EXPECT_EQ( 5, FindMatchForLeft( 3 ) );
EXPECT_EQ( 6, FindMatchForLeft( 4 ) );
EXPECT_EQ( 7, FindMatchForLeft( 5 ) );
}