private void AddVertex(int vertexPosition, ErrorOnDuplicate errorOnDuplicate) { lock (Values) { if (!Values.Any()) { // AddVertex values up to the specified vertex. for (int i = 0; i <= vertexPosition; i++) { if (!Values.ContainsKey(i)) // if the row is missing, add it. { Values.Add(i, new Dictionary <int, bool>()); // Now that we've added a new row, we must create its columns up to the rowcount of the first row. // AddVertex an entry for edge 0. if (!Values[i].ContainsKey(0)) { Values[i].Add(0, false); // i.e. if the cell does not have a dictionary entry (for column 0), then add it. } } } } var columnCount = Values.FirstOrDefault().Value.Count; // We may also need to ensure that all required columns exist. if (Values.ContainsKey(vertexPosition)) // If duplicate, throw exception if indicated. { if (Values[vertexPosition].Count == columnCount) // if column counts match, we should be okay. { if (errorOnDuplicate == ErrorOnDuplicate.Yes) { throw new IncidenceException("Duplicate vertex = " + vertexPosition + " deteted!"); } } else // if column counts don't match, then we need to create some columns. { // At this point, we know that Values[vertexPosition] exists. for (int i = 0; i < columnCount; i++) { if (!Values[vertexPosition].ContainsKey(i)) { Values[vertexPosition].Add(i, false); } } // Now that we've created the columns for the new row. } } else // i.e. if row does not exist in matrix, we must create entries up to that row number. { for (int i = 0; i <= vertexPosition; i++) { if (!Values.ContainsKey(i)) // if the row is missing, add it. { Values.Add(i, new Dictionary <int, bool>()); // Now that we've added a new row, we must create its columns up to the rowcount of the first row. for (int j = 0; j < columnCount; j++) { Values[i].Add(j, false); // i.e. if the cell does not have a dictionary entry (for column), then add it. } } } } } }
private void AddEdge(int edgePosition, ErrorOnDuplicate errorOnDuplicate) { // Remember, when we add a new edge, we must add the new column to every row. lock (Values) { if (!Values.Any()) { AddVertex(0); } if (!this.IsEdgeInMatrix(edgePosition)) // i.e. if column is not in all rows. { foreach (var row in Values) // then add the new column to every row { // AddVertex up to the missing edge. for (int i = 0; i <= edgePosition; i++) // Performance can be improved if we only need to check the diff. { if (!row.Value.ContainsKey(i)) { row.Value.Add(i, false); } } { if (errorOnDuplicate == ErrorOnDuplicate.Yes) { throw new IncidenceException("Duplicate edge = " + edgePosition + " detected!"); } } } } } }
//public UndirectedAdjacencyMatrix(int size) //{ // Values = new bool[size][]; // for (int i = 0; i < size; i++) // { // Values[i] = new bool[size]; // for (int j = 0; j < size; j++) // { // Values[i][j] = false; // } // } //} // For thread-safe enumeration, see: http://www.codeproject.com/Articles/56575/Thread-safe-enumeration-in-C public void Add(int vertexPosition, ErrorOnDuplicate errorOnDuplicate) { lock (Values) { // first we must check if the vertexPosition is larger than size of array. var currentRowCount = Values.Count; if (vertexPosition < currentRowCount) { // then we must check if the identity element is true. If so, the array is already occupied there, so throw an exception. if (Values.ContainsKey(vertexPosition) && Values[vertexPosition].ContainsKey(vertexPosition)) { if (Values[vertexPosition][vertexPosition] == true) { if (errorOnDuplicate == ErrorOnDuplicate.Yes) { throw new DuplicateNameException( "Error: Element already exists at specified position in UndirectedAdjacencyMatrix."); } // else, do nothing. } else { // Else, we can set the identity for that position to true. Values[vertexPosition][vertexPosition] = true; } } } else { var rowCountDiff = vertexPosition - currentRowCount; // 2 = 10 - 8. for (int i = 0; i <= rowCountDiff; i++) { // for each place in the gap, we must construct a row with size equal to our new position. var newRow = new Dictionary <int, bool>(vertexPosition); // we need to first initialize the values of the new row. for (int j = 0; j <= vertexPosition; j++) // the number of column values we must add increases with the number of rows. { newRow.Add(j, false); // initialize to default as false. } // Values.AddVertex(i + size -1,newRow); // Use this line if we get out of bounds exception. Values.Add(i + currentRowCount, newRow); // These keys must be new (>i) because we are adding the elements to the end of the list. // If any rows have fewer elements (i.e. columns) than newRow, we must add elements (false) to them. // Get rows that have fewer elements than newRow. var newRowColumns = newRow.Count; for (int j = 0; j < Values.Count; j++) // < or <= ?? { int currentColumnCount = Values[j].Count; if (currentColumnCount < newRow.Count) // i.e. if our rows don't yet have same numbers of columns. { var columnCountDiff = newRowColumns - currentColumnCount; // i.e. get the diff for the starting index position of new columns for (int k = 0; k < columnCountDiff; k++) { Values[j].Add(k + currentColumnCount, false); // AddVertex default elements to the row until the number of elements matches newRow. } } } // At this point, all of the rows should have equal numbers of columns. for (int j = 0; j < vertexPosition; j++) { // all of the new row values should be false except for the row value at our vertexPosition. var pos = currentRowCount + i; var row = Values[pos]; Values[currentRowCount + i][j] = false; } } Values[vertexPosition][vertexPosition] = true; } } }