/// <summary> /// Adds an incidence matrix for the STS(v) to the log file. Logfile has to be created beforehand. /// Rows of the matrix represent vertices and the colums represent the triples. /// If a triple contains an vertex, the value of the coresponding martix element is 1. Otherwise it's 0. /// </summary> /// <param name="sts"></param> public static void AppendIncidenceMatrix(SteinerTripleSystem sts) { using (StreamWriter streamWriter = new StreamWriter(path, true)) { List<string> matrixRows = new List<string>(); for (int i = 1; i <= sts.NumVertex(); i++) { matrixRows.Add(string.Empty); } foreach (Triple tr in sts) { for (int i = 1; i <= sts.NumVertex(); i++) { if (tr.X == i || tr.Y == i || tr.Z == i) { matrixRows[i - 1] += "1 "; } else { matrixRows[i - 1] += "0 "; } } } foreach (string line in matrixRows) { streamWriter.Write(line.Trim() + "\n"); } streamWriter.Write("\n"); } }
/// <summary> /// Generates a different decomposition (possibly isomorphic) /// </summary> /// <returns>STS(v)</returns> public SteinerTripleSystem NextDecomposition(SteinerTripleSystem sts) { RemoveRandBlocks(sts); while (NumBlocks < v * (v - 1) / 6) { Switch(); } return ConstructBlocks(v, Other); }
/// <summary> /// Creates a log file with a single incidence matrix /// Log file starts with v and b /// UNIX line endings /// </summary> /// <param name="logPath">Path of the log file</param> public static void CreateLogFile(string logPath, SteinerTripleSystem sts) { path = logPath; using (StreamWriter streamWriter = new StreamWriter(path, false)) { //Write v and b to the first line of the logfile streamWriter.Write(sts.NumVertex().ToString() +" " + sts.NumTriples().ToString() + "\n"); streamWriter.Write("\n"); } AppendIncidenceMatrix(sts); }
/// <summary> /// Starts the Bose construction /// </summary> /// <param name="v">Number of vertices in a graph</param> /// <returns>STS(v) generated by the construction</returns> public SteinerTripleSystem StartAlgorithm(int v) { this.v = v; this.n = (v - 3) / 6; this.b = v * (v - 1) / 6; this.quasigroup = new Quasigroup(2 * n + 1); this.sts = new SteinerTripleSystem(v, b); CreateTypeOne(); CreateTypeTwo(); return this.sts; }
/// <summary> /// Removes a random number of blocks from the decomposition. /// </summary> private void RemoveRandBlocks(SteinerTripleSystem sts) { Random rand = new Random(); for (int i = 0; i < sts.NumTriples(); i++) { bool removeBlock = rand.NextDouble() > ALPHA; if (removeBlock) { Triple triple = sts.GetElement(i); RemoveBlock(triple.X, triple.Y, triple.Z); } } }
/// <summary> /// Constructs the block set B that contains all the triples in the STS(v) /// </summary> /// <param name="v">Number of vertices</param> /// <param name="Other">Array that keeps track of the third point in a block containing x and y</param> /// <returns>STS(v) generated by the algorithm</returns> protected SteinerTripleSystem ConstructBlocks(int v, int[,] Other) { SteinerTripleSystem sts = new SteinerTripleSystem(v, b); int z; for (int x = 1; x <= v; x++) { for (int y = x + 1; y <= v; y++) { z = Other[x, y]; if (z > y) { sts.AddTriple(x, y, z); } } } return sts; }
/// <summary> /// Starts the graph decompostition /// </summary> private void startDecompostion() { this.isDecompositionStarted = true; this.sts = this.algorithm.StartAlgorithm(this.numVertex); showDecompositionButtons(); hideAlgorithmPickerButtons(); }
/// <summary> /// Removes old graph elements /// </summary> private void clearGraphElements() { this.canvasMain.Children.Clear(); this.vertexDictionary.Clear(); this.edgeDictionary.Clear(); this.sts = null; this.index = 0; this.isDecompositionStarted = false; }