/// <summary> /// This Method ensures a match is possible and if so clusters two nodes /// </summary> /// <param name="matchData"> MatchData Object </param> /// <returns> </returns> public static Cluster ClusterNodes(MatchData matchData) { INode firstRoot = matchData.First.Shred.Root(); INode secondRoot = matchData.Second.Shred.Root(); ClusterData result = IsMatch(matchData, firstRoot, secondRoot); if (result == null) { return null; } // Mirror the smaller object if need be if (result.Match == Match.Inverted) { if (firstRoot.Size() < secondRoot.Size()) { firstRoot.Mirror(); result.FirstDirection = Enumeration.Opposite(result.FirstDirection); } else { secondRoot.Mirror(); result.SecondDirection = Enumeration.Opposite(result.SecondDirection); } } // If the FirstNode's Edge is on the Right, it should go on the LEFT (make sense? ) if (result.FirstDirection == Direction.FromRight && result.SecondDirection == Direction.FromLeft) { return new Cluster(firstRoot, secondRoot, result.Match, matchData); } return new Cluster(secondRoot, firstRoot, result.Match, matchData); }
/// <summary> /// Clusters Two INodes together, sets new root/parent/left and right edges /// </summary> /// <param name="left"> Node on the left </param> /// <param name="right"> Node on the Right </param> /// <param name="match"> Inverted or Not Inverted </param> /// <param name="matchData"> Optional MatchData variable, store clustering information </param> public Cluster(INode left, INode right, Match match = Match.NonInverted, MatchData matchData = null) { if (match == Match.Impossible) { throw new ArgumentException("Match is apparently impossible why are you trying?"); } // Now Build the new nodes _left = left; _right = right; _matchData = matchData; _size = left.Size() + right.Size(); _leftedge = left.LeftEdge(); _rightedge = right.RightEdge(); // Set the parents accordingly left.Parent(this); right.Parent(this); _parent = null; // change the roots _left.Root(this); _right.Root(this); // Update Count Id = _count++; }
/// <summary> /// IsMatch determines if two shreds can be placed next to each other and thus matched. /// It returns a match.inverted or match.noninverted if possible or match.impossible if not. /// You shouldn't need to call IsMatch, rather use the safe ClusterNodes() method which will /// do it for you /// </summary> /// <param name="matchData"> </param> /// <returns> </returns> private static ClusterData IsMatch(MatchData matchData, INode firstRoot, INode secondRoot) { Side first = matchData.First; Side second = matchData.Second; Tuple<Match, Direction> firstFit; Tuple<Match, Direction> secondFit; // Cannot match when you have the same root if (firstRoot == secondRoot) { return null; } firstFit = IsFit(firstRoot, first.Shred, first); if (firstFit.Item1 == Match.Impossible) { return null; } secondFit = IsFit(secondRoot, second.Shred, second); if (secondFit.Item1 == Match.Impossible) { return null; } //if (firstFit.Item1 == Match.Inverted && secondFit.Item1 == Match.Inverted) //{ // return new ClusterData(Match.NonInverted, secondFit.Item2, firstFit.Item2); //} //else if (firstFit.Item1 == Match.NonInverted && secondFit.Item1 == Match.NonInverted) if (firstFit.Item1 == secondFit.Item1) { return new ClusterData(Match.NonInverted, firstFit.Item2, secondFit.Item2); } else if (firstFit.Item1 == Match.Inverted && secondFit.Item1 == Match.NonInverted || firstFit.Item1 == Match.NonInverted && secondFit.Item1 == Match.Inverted) { return new ClusterData(Match.Inverted, firstFit.Item2, secondFit.Item2); } return null; }
public static INode SmartClusterNodes(MatchData matchData) { throw new NotImplementedException(); }
/// <summary> /// This Method clusters two nodes forcibly with no match /// </summary> /// <param name="matchData"> MatchData Object </param> /// <param name="match"> Indicates how the MatchData is Matched </param> /// <returns> </returns> public static Cluster ForceClusterNodes(MatchData matchData, Match match = Match.NonInverted) { return new Cluster(matchData.First.Shred, matchData.Second.Shred, match); }