/// <summary> /// Prints information about a single integer sequences. /// </summary> /// <param name="sequence">sequence to list</param> /// <param name="corbaName">name of the sequence in the CORBA system</param> public static void PrintInfo(IntegerSequence sequence, Name corbaName) { Console.WriteLine("Sequence ID: {0}, kind: {1}", corbaName.ID, corbaName.Kind); Console.WriteLine("Name: {0}", sequence.name); Console.WriteLine("Maximal supported index: {0}", sequence.maxIndex); Console.WriteLine("Description:\n{0}", sequence.description); }
public void Statistics_DicModeAlgTest() { var target = new DicModeAlgorithm <int>(); var source = new IntegerSequence(); for (var i = 0; i < 1000; ++i) { source.Clear(); source.Add(0, i); var innerActual = target.Run(source); Assert.AreEqual(source.Count, innerActual.Count); innerActual.Sort(); for (var j = 0; j < source.Count; ++j) { Assert.AreEqual(source[j], innerActual[j]); } } var arraySource = new int[] { 1, 3, 2, 2, 1, 3, 3, 3, 3, 4, 2 }; var expected = 3; var actual = target.Run(arraySource); Assert.AreEqual(1, actual.Count); Assert.AreEqual(expected, actual[0]); }
/// <summary> /// Obtém a solução do problema a partir das variáveis de compatibilidade. /// </summary> /// <param name="resultCosts">Os custos por componente.</param> /// <param name="variables">A lista das variáveis escolhidas.</param> /// <param name="costsMatrices">As matrizes de custos.</param> /// <returns>A solução.</returns> private GreedyAlgSolution <CostsType>[] GetSolution( CostsType[] resultCosts, List <CoordsElement>[] variables, List <ILongSparseMathMatrix <CostsType> > costsMatrices) { var result = new GreedyAlgSolution <CostsType> [variables.Length]; for (int i = 0; i < result.Length; ++i) { var integerSequence = new IntegerSequence(); integerSequence.Add(0, costsMatrices[i].GetLength(0) - 1); var currentVariables = variables[i]; for (int j = 0; j < currentVariables.Count; ++j) { var column = currentVariables[j].Column; integerSequence.Remove(column); } var algSol = new GreedyAlgSolution <CostsType>(integerSequence); algSol.Cost = resultCosts[i]; result[i] = algSol; } return(result); }
private ElementType GetMinimumSum( IntegerSequence chosenReferences, SparseDictionaryMathMatrix <ElementType> currentMatrix, ElementType[] currentLineBoard, IEnumerable <KeyValuePair <int, ILongSparseMatrixLine <ElementType> > > lines, int chosenSolution) { var sum = this.ring.AdditiveUnity; var solutionValue = chosenReferences[chosenSolution]; var minimumCover = GetMinimumCover(chosenReferences, lines, solutionValue); sum = this.ring.Add(sum, minimumCover); var columns = currentMatrix.GetColumns(solutionValue); foreach (var column in columns) { if (column.Key != solutionValue) { var currentValue = currentMatrix[solutionValue, column.Key]; if (this.ring.Equals(currentValue, currentLineBoard[column.Key])) { minimumCover = this.GetMinimumCover( chosenReferences, lines, column.Key); minimumCover = this.ring.Add(minimumCover, this.ring.AdditiveInverse(currentValue)); sum = this.ring.Add(sum, minimumCover); } } } return(sum); }
public int IntegerFromSequence(int startingValue = 0, int step = 1) { var sequence = new IntegerSequence(startingValue, step, Integer()); var finalSequence = Maybe.Wrap(_sequences.FirstOrDefault(s => s.Equals(sequence))).ValueOr(sequence); _sequences.Add(finalSequence); var integerFromSequence = finalSequence.Next(); return(integerFromSequence); }
internal GreedyAlgSolution(IntegerSequence chosen) { if (chosen == null) { throw new ArgumentNullException("chosen"); } else { this.chosen = chosen; } }
/// <summary> /// Cria instâncias de objectos do tipo <see cref="IntegerSequenceSubVector{CoeffType}"/>. /// </summary> /// <param name="vector">O vector principal.</param> /// <param name="indicesSequence">A sequência de inteiros que define o sub-vector.</param> /// <exception cref="ArgumentNullException">Se o vector proporcionado for nulo.</exception> public IntegerSequenceSubVector(IVector <CoeffType> vector, IntegerSequence indicesSequence) { if (vector == null) { throw new ArgumentNullException("vector"); } else { this.vector = vector; this.indicesSequence = indicesSequence.Clone(); } }
/// <summary> /// Remove as colunas especificadas pelos índices. /// </summary> /// <param name="columnsIndices">Os índices.</param> public void RemoveColumns(IntegerSequence columnsIndices) { if (columnsIndices == null) { throw new ArgumentNullException("columnsIndices"); } else { columnsIndices.ForeachBlock((start, end) => { this.columns.RemoveRange(start, end - start + 1); }); } }
/// <summary> /// Calcula as entradas da matriz de multiplicação. /// </summary> /// <param name="data">A matriz.</param> /// <param name="diagonalElement">O elemento na diagonal.</param> /// <param name="subMatrixSequence">A sequência que define a sub-matriz.</param> /// <param name="singleValueSequence">A sequência que define o valor.</param> /// <param name="multiplicator">O objecto responsável pela multiplicação de matrizes.</param> /// <param name="multiplicationMatrix">A matriz que comporta o resultado da multiplicação.</param> private void FillMultiplicationMatrix( IMathMatrix <ElementType> data, ElementType diagonalElement, IntegerSequence subMatrixSequence, IntegerSequence singleValueSequence, MatrixMultiplicationOperation <ElementType> multiplicator, IMatrix <ElementType> multiplicationMatrix) { var dimension = multiplicationMatrix.GetLength(1); var rowSubMatrix = data.GetSubMatrix(singleValueSequence, subMatrixSequence); var columnSubMatrix = data.GetSubMatrix(subMatrixSequence, singleValueSequence); var mainSubMatrix = data.GetSubMatrix(subMatrixSequence, subMatrixSequence); for (int i = 0; i < dimension; ++i) { multiplicationMatrix[i, i] = this.ring.MultiplicativeUnity; } for (int i = 0; i < dimension; ++i) { multiplicationMatrix[i + 1, i] = this.ring.AdditiveInverse(diagonalElement); } var vectorsMultiply = multiplicator.Multiply(rowSubMatrix, columnSubMatrix); for (int i = 0; i < dimension - 1; ++i) { multiplicationMatrix[i + 2, i] = this.ring.AdditiveInverse(vectorsMultiply[0, 0]); } vectorsMultiply = multiplicator.Multiply(rowSubMatrix, mainSubMatrix); vectorsMultiply = multiplicator.Multiply(vectorsMultiply, columnSubMatrix); for (int i = 0; i < dimension - 2; ++i) { multiplicationMatrix[i + 3, i] = this.ring.AdditiveInverse(vectorsMultiply[0, 0]); } var subMatrix = mainSubMatrix; for (int i = 3; i < dimension; ++i) { subMatrix = multiplicator.Multiply(mainSubMatrix, subMatrix); vectorsMultiply = multiplicator.Multiply(rowSubMatrix, subMatrix); vectorsMultiply = multiplicator.Multiply(vectorsMultiply, columnSubMatrix); for (int j = 0; j < dimension - i; ++j) { multiplicationMatrix[j + i + 1, j] = this.ring.AdditiveInverse(vectorsMultiply[0, 0]); } } }
private ElementType GetMinimumCover( IntegerSequence chosenReferences, IEnumerable <KeyValuePair <int, ILongSparseMatrixLine <ElementType> > > lines, int solutionValue) { var minimumCover = default(ElementType); var lineEnumerator = lines.GetEnumerator(); var status = lineEnumerator.MoveNext(); if (status) { var line = lineEnumerator.Current; if (line.Key != solutionValue && chosenReferences.Contains(line.Key) && line.Value.ContainsColumn(solutionValue)) { minimumCover = line.Value[solutionValue]; } else { status = lineEnumerator.MoveNext(); while (status && (line.Key == solutionValue || !chosenReferences.Contains(line.Key) || !line.Value.ContainsColumn(solutionValue))) { status = lineEnumerator.MoveNext(); } } while (status) { line = lineEnumerator.Current; if (line.Key != solutionValue && chosenReferences.Contains(line.Key) && line.Value.ContainsColumn(solutionValue)) { var compareValue = line.Value[solutionValue]; if (this.comparer.Compare(compareValue, minimumCover) < 0) { minimumCover = compareValue; } } } } return(minimumCover); }
/// <summary> /// Lists summary for all integer sequence implementations registered in the system. /// </summary> public void ListServices() { List <Name> names = this.dir.ServiceNames; Console.WriteLine("Registered sequence implementations:"); foreach (Name name in names) { Console.WriteLine(StringUtils.Delimiter); try { IntegerSequence reference = dir.Resolve(name); StringUtils.PrintInfo(reference, name); } catch (ServiceException ex) { StringUtils.PrintErroneousInfo(ex, name); } } }
public void Statistics_DicMedianAlgTest() { var target = new DicMedianAlgorithm <int>(); var source = new IntegerSequence(); var expected = 1; for (var i = 1; i < 1000; i += 2) { source.Clear(); source.Add(1, i); var actual = target.Run(source); Assert.AreEqual(expected, actual.Item1); Assert.AreEqual(expected, actual.Item2); ++expected; } expected = 1; for (var i = 2; i < 1000; i += 2) { source.Clear(); source.Add(1, i); var actual = target.Run(source); Assert.AreEqual(expected++, actual.Item1); Assert.AreEqual(expected, actual.Item2); } var arraySource = new int[] { 1, 3, 2, 2, 1, 3, 3, 3, 3, 4, 2 }; expected = 3; var outerActual = target.Run(arraySource); Assert.AreEqual(expected, outerActual.Item1); Assert.AreEqual(expected, outerActual.Item2); arraySource = new int[] { 1, 3, 2, 2, 1, 3, 3, 3, 4, 2 }; expected = 2; outerActual = target.Run(arraySource); Assert.AreEqual(expected++, outerActual.Item1); Assert.AreEqual(expected, outerActual.Item2); }
/// <summary> /// Permite obter o valor mínimo entre as colunas da matriz para as linhas escolhidas com excepção /// de uma delas. /// </summary> /// <param name="chosen">As linhas escolhidas.</param> /// <param name="exceptLine"> /// A linha que não vai ser considerada.</param> /// <param name="column">A coluna sobre a qual é calculado o mínimo.</param> /// <param name="costs">A matriz dos custos.</param> /// <returns>O valor do custo mínimo.</returns> private CoeffType GetMinimumFromColumn( IntegerSequence chosen, int exceptLine, int column, ILongSparseMathMatrix <CoeffType> costs) { var result = default(CoeffType); var chosenEnumerator = chosen.GetEnumerator(); var state = chosenEnumerator.MoveNext(); var keep = true; while (state && keep) { // Pesquisa pelo primeiro elemento. var currentChosen = chosenEnumerator.Current; if (currentChosen != exceptLine) { var currentLine = default(ILongSparseMatrixLine <CoeffType>); if (costs.TryGetLine(currentChosen, out currentLine)) { var columnValue = default(CoeffType); if (currentLine.TryGetColumnValue(column, out columnValue)) { if (this.coeffsField.IsAdditiveUnity(columnValue)) { return(columnValue); } else { result = columnValue; keep = false; } } } } state = chosenEnumerator.MoveNext(); } if (keep) { throw new OdmpProblemException("Something went very wrong. Check if costs matrix is valid."); } else { while (state) { var currentChosen = chosenEnumerator.Current; if (currentChosen != exceptLine) { var currentLine = default(ILongSparseMatrixLine <CoeffType>); if (costs.TryGetLine(currentChosen, out currentLine)) { var columnValue = default(CoeffType); if (currentLine.TryGetColumnValue(column, out columnValue)) { if (this.coeffsField.IsAdditiveUnity(columnValue)) { return(columnValue); } else { if (this.comparer.Compare(columnValue, result) < 0) { result = columnValue; } } } } } state = chosenEnumerator.MoveNext(); } } return(result); }
public void construct() { // make sure the last item is and end row if (!items[items.Count - 1].endRow) { endRow(); } // have to initialize some variable types first to get the actual size for (int i = 0; i < items.Count; i++) { items[i].initialize(); } setToRequiredSize(output.matrix); int matrixRow = 0; List <Item> row = new List <Item>(); for (int i = 0; i < items.Count; i++) { Item item = items[i]; if (item.endRow) { int expectedRows = 0; int numCols = 0; for (int j = 0; j < row.Count; j++) { Item v = row[j]; int numRows = v.getRows(); if (j == 0) { expectedRows = numRows; } else if (v.getRows() != expectedRows) { throw new InvalidOperationException("Row miss-matched. " + numRows + " " + v.getRows()); } if (v.matrix) { CommonOps_DDRM.insert(v.getMatrix(), output.matrix, matrixRow, numCols); } else if (v.variable.getType() == VariableType.SCALAR) { output.matrix.set(matrixRow, numCols, v.getValue()); } else if (v.variable.getType() == VariableType.INTEGER_SEQUENCE) { IntegerSequence sequence = ((VariableIntegerSequence)v.variable).sequence; int col = numCols; while (sequence.hasNext()) { output.matrix.set(matrixRow, col++, sequence.next()); } } else { throw new ParseError("Can't insert a variable of type " + v.variable.getType() + " inside a matrix!"); } numCols += v.getColumns(); } matrixRow += expectedRows; row.Clear(); } else { row.Add(item); } } }
/// <summary> /// Escolhe a referência que maximiza o ganho. /// </summary> /// <param name="chosenReferences">As referências escolhidas anteriormente.</param> /// <param name="currentMatrix">A matriz dos custos.</param> /// <param name="currentLineBoard">A linha que contém a condensação dos custos das linhas escolhidas.</param> /// <returns>O índice da linha corresponde à próxima referência bem como o ganho respectivo.</returns> public Tuple <int, ElementType> Run( IntegerSequence chosenReferences, ILongSparseMathMatrix <ElementType> currentMatrix, ElementType[] currentLineBoard) { var result = default(KeyValuePair <int, ILongSparseMatrixLine <ElementType> >); var lines = currentMatrix.GetLines(); var currentMaxGain = this.ring.AdditiveInverse(this.ring.MultiplicativeUnity); var foundRef = false; Parallel.ForEach(lines, line => { if (!chosenReferences.Contains(line.Key)) { var sum = this.ring.AdditiveUnity; foreach (var column in line.Value) { if (column.Key != line.Key) { var currentValue = column.Value; if (this.comparer.Compare(currentValue, currentLineBoard[column.Key]) < 0) { var difference = this.ring.Add( currentLineBoard[column.Key], this.ring.AdditiveInverse(currentValue)); sum = this.ring.Add(sum, difference); } } else { sum = this.ring.Add(sum, currentLineBoard[column.Key]); } } lock (this.lockObject) { if (this.comparer.Compare(currentMaxGain, sum) < 0) { currentMaxGain = sum; result = line; foundRef = true; } } } }); if (foundRef) { foreach (var column in result.Value.GetColumns()) { if (column.Key != result.Key) { if (this.comparer.Compare(column.Value, currentLineBoard[column.Key]) < 0) { currentLineBoard[column.Key] = column.Value; } } else { currentLineBoard[column.Key] = this.ring.AdditiveUnity; } } return(Tuple.Create(result.Key, currentMaxGain)); } else { return(Tuple.Create(-1, currentMaxGain)); } }
/// <summary> /// Obtém o sub-vector especificado pela sequência especificada. /// </summary> /// <param name="indices">A sequência.</param> /// <returns>O sub-vector.</returns> public IVector <CoeffType> GetSubVector(IntegerSequence indices) { return(new IntegerSequenceSubVector <CoeffType>(this, indices)); }
void Start() { count = 0; levelComplete = false; countText.text = "Sequence Collected: "; livesText.text = "Lives left: " + noOfLivesLeft.ToString(); levelText.text = "Level " + (levelToLoad + 1).ToString () + " of 77"; winText.text = ""; hydrateSequences(); initColourMap (); currentSequence = this.sequences [levelToLoad]; expectedIndex = 0; int randomNumber = 0; for (int i = 0; i < currentSequence.Elements.Length; i++) { randomNumber = currentSequence.Elements[i]; //Debug.Log(randomNumber); if ((randomNumber >= 0) && (randomNumber < 10) ){ Transform singleDigitObject = (Transform)Instantiate (sphere, new Vector3 (Random.Range(-9.5f,9.5f), 0.5f, Random.Range(-9.5f,9.5f)), Quaternion.identity); //Debug.Log(decimalPointFinder(4, randomNumber)[0][1]); singleDigitObject.gameObject.renderer.material.color = colourMap[randomNumber]; singleDigitObject.gameObject.GetComponent<CubeRotator>().number = randomNumber; } else if ((randomNumber >= 10) && (randomNumber < 99) ){ Transform doubleDigitObject = (Transform)Instantiate (twoSidedCube, new Vector3 (Random.Range(-9.5f,9.5f), 0.5f, Random.Range(-9.5f,9.5f)), Quaternion.identity); int noAtUnit = decimalPointFinder(2, randomNumber)[0][1]; int noAtTens = decimalPointFinder(2, randomNumber)[1][1]; doubleDigitObject.FindChild("Back").renderer.material.color = colourMap[noAtUnit]; doubleDigitObject.FindChild("Front").renderer.material.color = colourMap[noAtTens]; doubleDigitObject.gameObject.GetComponent<CubeRotator>().number = randomNumber; } else if ((randomNumber >= 100) && (randomNumber < 999) ){ Transform threeDigitObject = (Transform)Instantiate (threeSidedShape, new Vector3 (Random.Range(-9.5f,9.5f), 0.5f, Random.Range(-9.5f,9.5f)), Quaternion.identity); int noAtUnit = decimalPointFinder(3, randomNumber)[0][1]; int noAtTens = decimalPointFinder(3, randomNumber)[1][1]; int noAtHundreds = decimalPointFinder(3, randomNumber)[2][1]; threeDigitObject.FindChild("Horizontal").FindChild("Front").renderer.material.color = colourMap[noAtUnit]; threeDigitObject.FindChild("Horizontal").FindChild("Back").renderer.material.color = colourMap[noAtUnit]; threeDigitObject.FindChild("Lateral Left").FindChild("Front").renderer.material.color = colourMap[noAtTens]; threeDigitObject.FindChild("Lateral Left").FindChild("Back").renderer.material.color = colourMap[noAtTens]; threeDigitObject.FindChild("Lateral Right").FindChild("Front").renderer.material.color = colourMap[noAtHundreds]; threeDigitObject.FindChild("Lateral Right").FindChild("Back").renderer.material.color = colourMap[noAtHundreds]; threeDigitObject.gameObject.GetComponent<CubeRotator>().number = randomNumber; } else { Transform fourDigitObject = (Transform)Instantiate (fourSidedCube, new Vector3 (Random.Range(-9.5f,9.5f), 0.5f, Random.Range(-9.5f,9.5f)), Quaternion.identity); int noAtUnit = decimalPointFinder(4, randomNumber)[0][1]; int noAtTens = decimalPointFinder(4, randomNumber)[1][1]; int noAtHundreds = decimalPointFinder(4, randomNumber)[2][1]; int noAtThousands = decimalPointFinder(4, randomNumber)[3][1]; fourDigitObject.FindChild("Back").renderer.material.color = colourMap[noAtUnit]; fourDigitObject.FindChild("Front").renderer.material.color = colourMap[noAtTens]; fourDigitObject.FindChild("Right").renderer.material.color = colourMap[noAtHundreds]; fourDigitObject.FindChild("Left").renderer.material.color = colourMap[noAtThousands]; fourDigitObject.gameObject.GetComponent<CubeRotator>().number = randomNumber; } } }
public VariableIntegerSequence createIntegerSequence(IntegerSequence sequence) { return(new VariableIntegerSequence(sequence)); }
public void Statistcs_EnumGeneralizeMeanBlockAlgorithmTest() { var integerNumb = new IntegerDomain(); var target = new EnumGeneralizedMeanAlgorithm <int, double, int>( i => i, d => d, (d, i) => d / i, new DoubleField(), integerNumb); var blockNumber = 2500; var integerSequence = new IntegerSequence(); for (var i = 1; i < 5500; ++i) { integerSequence.Add(i); var expected = (i + 1) / 2.0; var actual = target.Run <double>( integerSequence, blockNumber, (j, k) => j / (double)k, (d1, d2) => d1 * d2); Assert.IsTrue(Math.Abs(expected - actual) < 0.0001); } integerSequence = new IntegerSequence(); var n = 1000500; integerSequence.Add(1, n); var outerExpected = (n + 1) / 2.0; var outerActual = target.Run <double>( integerSequence, blockNumber, (j, k) => j / (double)k, (d1, d2) => d1 * d2); Assert.AreEqual(outerExpected, outerActual); var integerDomain = new BigIntegerDomain(); var fractionField = new FractionField <BigInteger>(integerDomain); var fracTarget = new EnumGeneralizedMeanAlgorithm <int, Fraction <BigInteger>, int>( i => new Fraction <BigInteger>(i, 1, integerDomain), d => d, (d, i) => d.Divide(i, integerDomain), fractionField, integerNumb); var fractionExpected = new Fraction <BigInteger>(n + 1, 2, integerDomain); var fractionActual = fracTarget.Run <Fraction <BigInteger> >( integerSequence, blockNumber, (j, k) => new Fraction <BigInteger>(j, k, integerDomain), (d1, d2) => d1.Multiply(d2, integerDomain)); Assert.AreEqual(fractionExpected, fractionActual); // Teste com alteração da função directa fracTarget.DirectFunction = i => new Fraction <BigInteger>(new BigInteger(i) * i, 1, integerDomain); fractionExpected = new Fraction <BigInteger>( (new BigInteger(n) + BigInteger.One) * (2 * new BigInteger(n) + 1), 6, integerDomain); fractionActual = fracTarget.Run <Fraction <BigInteger> >( integerSequence, blockNumber, (j, k) => new Fraction <BigInteger>(j, k, integerDomain), (d1, d2) => d1.Multiply(d2, integerDomain)); // Teste com transformação var transformedTarget = new EnumGeneralizedMeanAlgorithm <BigInteger, Fraction <BigInteger>, int>( i => new Fraction <BigInteger>(i, 1, integerDomain), d => d, (d, i) => d.Divide(i, integerDomain), fractionField, integerNumb); var transformedSeq = new TransformEnumerable <int, BigInteger>( integerSequence, i => new BigInteger(i) * i); var transformedExpected = new Fraction <BigInteger>( (new BigInteger(n) + BigInteger.One) * (2 * new BigInteger(n) + 1), 6, integerDomain); var transformedActual = transformedTarget.Run <Fraction <BigInteger> >( transformedSeq, blockNumber, (j, k) => new Fraction <BigInteger>(j, k, integerDomain), (d1, d2) => d1.Multiply(d2, integerDomain)); Assert.AreEqual(transformedExpected, transformedActual); }
/// <summary> /// Obtém a submatriz indicada no argumento considerado como sequência de inteiros. /// </summary> /// <param name="lines">As correnadas das linhas que constituem a submatriz.</param> /// <param name="columns">As correnadas das colunas que constituem a submatriz.</param> /// <returns>A submatriz procurada.</returns> public IMatrix<CoeffType> GetSubMatrix(IntegerSequence lines, IntegerSequence columns) { return new IntegerSequenceSubMatrix<CoeffType>(this, lines, columns); }
public GreedyAlgSolution() { this.chosen = new IntegerSequence(); }
/// <summary> /// Determina o polinómio característico de uma matriz. /// </summary> /// <param name="data">A matriz.</param> /// <returns>O polinómio característico.</returns> public UnivariatePolynomialNormalForm <ElementType> Run(ISquareMathMatrix <ElementType> data) { if (data == null) { return(new UnivariatePolynomialNormalForm <ElementType>(this.variableName)); } else { var lines = data.GetLength(0); if (lines == 0) { return(new UnivariatePolynomialNormalForm <ElementType>(this.variableName)); } else if (lines == 1) { var entry = data[0, 0]; var result = new UnivariatePolynomialNormalForm <ElementType>( this.ring.MultiplicativeUnity, 1, this.variableName, this.ring); result = result.Add(this.ring.AdditiveInverse(entry), 0, this.ring); return(result); } else if (lines == 2) { var variablePol = new UnivariatePolynomialNormalForm <ElementType>( this.ring.MultiplicativeUnity, 1, this.variableName, this.ring); var firstDiagonalElement = variablePol.Add( this.ring.AdditiveInverse(data[0, 0]), this.ring); var secondDiagonalElement = variablePol.Add( this.ring.AdditiveInverse(data[1, 1]), this.ring); var result = firstDiagonalElement.Multiply(secondDiagonalElement, this.ring); result = result.Add( this.ring.AdditiveInverse(this.ring.Multiply(data[0, 1], data[1, 0])), this.ring); return(result); } else { var matrixFactory = new ArrayMathMatrixFactory <ElementType>(); var matrixMultiplicator = new MatrixMultiplicationOperation <ElementType>( matrixFactory, this.ring, this.ring); var subMatrixSequence = new IntegerSequence(); var singleValueSequence = new IntegerSequence(); IMatrix <ElementType> multiplicationMatrix = new ArrayMathMatrix <ElementType>( lines + 1, lines, this.ring.AdditiveUnity); subMatrixSequence.Add(1, lines - 1); singleValueSequence.Add(0); this.FillMultiplicationMatrix( data, data[0, 0], subMatrixSequence, singleValueSequence, matrixMultiplicator, multiplicationMatrix); var currentDimension = 1; while (currentDimension < lines - 1) { subMatrixSequence.Clear(); singleValueSequence.Clear(); subMatrixSequence.Add(currentDimension + 1, lines - 1); singleValueSequence.Add(currentDimension); var otherLines = lines - currentDimension; var otherMultiplicationMatrix = new ArrayMathMatrix <ElementType>( otherLines + 1, otherLines, this.ring.AdditiveUnity); this.FillMultiplicationMatrix( data, data[currentDimension, currentDimension], subMatrixSequence, singleValueSequence, matrixMultiplicator, otherMultiplicationMatrix); multiplicationMatrix = matrixMultiplicator.Multiply( multiplicationMatrix, otherMultiplicationMatrix); ++currentDimension; } var lastOtherMultiplicationMatrix = new ArrayMathMatrix <ElementType>( 2, 1, this.ring.AdditiveUnity); lastOtherMultiplicationMatrix[0, 0] = this.ring.MultiplicativeUnity; lastOtherMultiplicationMatrix[1, 0] = this.ring.AdditiveInverse(data[currentDimension, currentDimension]); multiplicationMatrix = matrixMultiplicator.Multiply( multiplicationMatrix, lastOtherMultiplicationMatrix); var result = new UnivariatePolynomialNormalForm <ElementType>( multiplicationMatrix[0, 0], lines, this.variableName, this.ring); for (int i = 1; i <= lines; ++i) { result = result.Add(multiplicationMatrix[i, 0], lines - i, this.ring); } return(result); } } }
public VariableIntegerSequence(IntegerSequence sequence) : base(VariableType.INTEGER_SEQUENCE) { ; this.sequence = sequence; }
public void Statistcs_EnumGeneralizeMeanAlgorithmTest() { var integerNumb = new IntegerDomain(); var target = new EnumGeneralizedMeanAlgorithm <int, double, int>( i => i, d => d, (d, i) => d / i, new DoubleField(), integerNumb); var integerSequence = new IntegerSequence(); for (var i = 1; i < 5000; ++i) { integerSequence.Add(i); var expected = (i + 1) / 2.0; var actual = target.Run(integerSequence); Assert.AreEqual(expected, actual); } integerSequence = new IntegerSequence(); var n = 1000000; integerSequence.Add(1, n); var outerExpected = (n + 1) / 2.0; var outerActual = target.Run(integerSequence); Assert.AreEqual(outerExpected, outerActual); var bigIntegerDomain = new BigIntegerDomain(); var fractionField = new FractionField <BigInteger>(bigIntegerDomain); var fractionTarget = new EnumGeneralizedMeanAlgorithm <int, Fraction <BigInteger>, int>( i => new Fraction <BigInteger>(i, 1, bigIntegerDomain), d => d, (d, i) => d.Divide(i, bigIntegerDomain), fractionField, integerNumb); var fractionExpected = new Fraction <BigInteger>(n + 1, 2, bigIntegerDomain); var fractionActual = fractionTarget.Run(integerSequence); Assert.AreEqual(fractionExpected, fractionActual); // Teste com alteração da função directa fractionTarget.DirectFunction = i => new Fraction <BigInteger>(new BigInteger(i) * i, 1, bigIntegerDomain); fractionExpected = new Fraction <BigInteger>( (new BigInteger(n) + BigInteger.One) * (2 * new BigInteger(n) + 1), 6, bigIntegerDomain); fractionActual = fractionTarget.Run(integerSequence); Assert.AreEqual(fractionExpected, fractionActual); // Teste com transformação var transformedTarget = new EnumGeneralizedMeanAlgorithm <BigInteger, Fraction <BigInteger>, int>( i => new Fraction <BigInteger>(i, 1, bigIntegerDomain), d => d, (d, i) => d.Divide(i, bigIntegerDomain), fractionField, integerNumb); var transformedSeq = new TransformEnumerable <int, BigInteger>( integerSequence, i => new BigInteger(i) * i); var transformedExpected = new Fraction <BigInteger>( (new BigInteger(n) + BigInteger.One) * (2 * new BigInteger(n) + 1), 6, bigIntegerDomain); var transformedActual = transformedTarget.Run(transformedSeq); Assert.AreEqual(transformedExpected, transformedActual); }
/// <summary> /// Escolhe a referência que minimiza a perda. /// </summary> /// <param name="chosenReferences">As referências escolhidas anteriormente.</param> /// <param name="currentMatrix">A matriz dos custos.</param> /// <param name="currentLineBoard">A linha que contém a condensação dos custos das linhas escolhidas.</param> /// <returns>O índice da linha correspondente à próxima referência bem como a perda respectiva.</returns> public Tuple <int, ElementType> Run( IntegerSequence chosenReferences, SparseDictionaryMathMatrix <ElementType> currentMatrix, ElementType[] currentLineBoard) { var result = -1; var currentMinimumLost = default(ElementType); var lines = currentMatrix.GetLines(); if (chosenReferences.Count > 2) { currentMinimumLost = this.GetMinimumSum( chosenReferences, currentMatrix, currentLineBoard, lines, 2); result = 2; } Parallel.For(2, chosenReferences.Count, chosenSolution => { var sum = this.GetMinimumSum( chosenReferences, currentMatrix, currentLineBoard, lines, chosenSolution); lock (this.lockObject) { if (this.comparer.Compare(sum, currentMinimumLost) < 0) { currentMinimumLost = sum; result = chosenSolution; } } }); if (result != -1) { var solutionValue = chosenReferences[result]; var minimumCover = this.GetMinimumCover( chosenReferences, lines, solutionValue); currentLineBoard[solutionValue] = minimumCover; var columns = currentMatrix.GetColumns(solutionValue); foreach (var column in columns) { if (column.Key != solutionValue) { var currentValue = currentMatrix[solutionValue, column.Key]; if (this.ring.Equals(currentValue, currentLineBoard[column.Key])) { minimumCover = this.GetMinimumCover( chosenReferences, lines, solutionValue); currentLineBoard[column.Key] = minimumCover; } } } } return(Tuple.Create(result, currentMinimumLost)); }
/// <summary> /// Obtém a submatriz indicada no argumento considerado como sequência de inteiros. /// </summary> /// <param name="lines">As correnadas das linhas que constituem a submatriz.</param> /// <param name="columns">As correnadas das colunas que constituem a submatriz.</param> /// <returns>A submatriz procurada.</returns> public IMatrix <ElementType> GetSubMatrix(IntegerSequence lines, IntegerSequence columns) { return(new IntegerSequenceSubMatrix <ElementType>(this, lines, columns)); }
/// <summary> /// Calcula o custo da substituição de uma mediana por outra. /// </summary> /// <param name="replacementMedian">A mediana que substitui.</param> /// <param name="medianToBeReplaced">A mediana que é substituída.</param> /// <param name="existingMedians">As medianas que forma escolhidas.</param> /// <param name="costs">A matriz dos custos.</param> /// <param name="currentSolutionBoard">O quadro de solução actual.</param> /// <param name="replacementSolutionBoard">O quadro da solução substituída.</param> /// <returns>O valor do mínimo.</returns> private CoeffType ComputeReplacementCost( int replacementMedian, int medianToBeReplaced, IntegerSequence existingMedians, ILongSparseMathMatrix <CoeffType> costs, CoeffType[] currentSolutionBoard, CoeffType[] replacementSolutionBoard) { Array.Copy(currentSolutionBoard, replacementSolutionBoard, currentSolutionBoard.Length); var result = this.coeffsField.AdditiveUnity; var minimum = this.GetMinimumFromColumn( existingMedians, medianToBeReplaced, medianToBeReplaced, costs); replacementSolutionBoard[medianToBeReplaced] = minimum; result = this.coeffsField.Add(result, minimum); var boardValue = currentSolutionBoard[replacementMedian]; replacementSolutionBoard[replacementMedian] = this.coeffsField.AdditiveUnity; result = this.coeffsField.Add( result, this.coeffsField.AdditiveInverse(boardValue)); // Remove a linha a ser substituída. var currentRow = default(ILongSparseMatrixLine <CoeffType>); if (costs.TryGetLine(medianToBeReplaced, out currentRow)) { foreach (var column in currentRow.GetColumns()) { if (column.Key != medianToBeReplaced && column.Key != replacementMedian) { if (this.coeffsField.Equals(column.Value, replacementSolutionBoard[column.Key])) { var current = replacementSolutionBoard[column.Key]; minimum = this.GetMinimumFromColumn( existingMedians, medianToBeReplaced, column.Key, costs); replacementSolutionBoard[column.Key] = minimum; var temp = this.coeffsField.Add( minimum, this.coeffsField.AdditiveInverse(current)); result = this.coeffsField.Add(result, temp); } } } } // Insere a linha a substituir. if (costs.TryGetLine(replacementMedian, out currentRow)) { foreach (var column in currentRow.GetColumns()) { if (column.Key != replacementMedian) { var current = replacementSolutionBoard[column.Key]; if (this.comparer.Compare(column.Value, current) < 0) { replacementSolutionBoard[column.Key] = column.Value; var temp = this.coeffsField.Add( column.Value, this.coeffsField.AdditiveInverse(current)); result = this.coeffsField.Add(result, temp); } } } } return(result); }
/// <summary> /// Permite calcular o custo associado à escolha de um conjunto de medianas escolhidas. /// </summary> /// <param name="chosen">O conjunto de medianas escolhidas.</param> /// <param name="costs">A matriz dos custos.</param> /// <param name="solutionBoard">A linha que mantém os mínimos por mediana.</param> /// <returns>O valor do custo associado à escolha.</returns> private CoeffType ComputeCost( IntegerSequence chosen, ILongSparseMathMatrix <CoeffType> costs, CoeffType[] solutionBoard, BitArray marked) { var resultCost = this.coeffsField.AdditiveUnity; foreach (var item in chosen) { var currentCostLine = default(ILongSparseMatrixLine <CoeffType>); if (costs.TryGetLine(item, out currentCostLine)) { foreach (var column in currentCostLine.GetColumns()) { if (column.Key == item) { if (marked[item]) { resultCost = this.coeffsField.Add( resultCost, this.coeffsField.AdditiveInverse(solutionBoard[item])); } else { marked[item] = true; } solutionBoard[item] = this.coeffsField.AdditiveUnity; } else { if (marked[column.Key]) { var boardCost = solutionBoard[column.Key]; if (this.comparer.Compare(column.Value, boardCost) < 0) { solutionBoard[column.Key] = column.Value; var difference = this.coeffsField.Add( column.Value, this.coeffsField.AdditiveInverse(boardCost)); resultCost = this.coeffsField.Add( resultCost, difference); } } else { resultCost = this.coeffsField.Add( resultCost, column.Value); solutionBoard[column.Key] = column.Value; marked[column.Key] = true; } } } } else { marked[item] = true; solutionBoard[item] = this.coeffsField.AdditiveUnity; } } for (int i = 0; i < marked.Length; ++i) { if (!marked[i] && !chosen.Contains(i)) { throw new OdmpProblemException("Not all nodes are covered by some median."); } } return(resultCost); }
/// <summary> /// Obtém a submatriz indicada no argumento considerado como sequência de inteiros. /// </summary> /// <param name="lines">As correnadas das linhas que constituem a submatriz.</param> /// <param name="columns">As correnadas das colunas que constituem a submatriz.</param> /// <returns>A submatriz procurada.</returns> public IMatrix <bool> GetSubMatrix(IntegerSequence lines, IntegerSequence columns) { return(new IntegerSequenceSubMatrix <bool>(this, lines, columns)); }
/// <summary> /// Obtém uma solução a partir duma aproximação inicial. /// </summary> /// <param name="approximateMedians">As medianas.</param> /// <param name="costs">Os custos.</param> /// <param name="niter">O número máximo melhoramentos a serem aplicados à solução encontrada.</param> /// <returns>A solução construída a partir da aproximação.</returns> public GreedyAlgSolution <CoeffType> Run( CoeffType[] approximateMedians, ILongSparseMathMatrix <CoeffType> costs, int niter) { if (approximateMedians == null) { throw new ArgumentNullException("approximateMedians"); } else if (costs == null) { throw new ArgumentNullException("costs"); } else if (approximateMedians.Length != costs.GetLength(1)) { throw new ArgumentException("The number of medians must match the number of columns in costs matrix."); } else { var settedSolutions = new IntegerSequence(); var approximateSolutions = new List <int>(); var sum = this.coeffsField.AdditiveUnity; for (int i = 0; i < approximateMedians.Length; ++i) { var currentMedian = approximateMedians[i]; if (!this.coeffsField.IsAdditiveUnity(currentMedian)) { sum = this.coeffsField.Add(sum, approximateMedians[i]); if (this.converter.CanApplyDirectConversion(currentMedian)) { var converted = this.converter.DirectConversion(currentMedian); if (converted == 1) { settedSolutions.Add(i); } else { throw new OdmpProblemException(string.Format( "The median {0} at position {1} of medians array can't be converted to the unity.", currentMedian, i)); } } else { approximateSolutions.Add(i); } } } if (this.converter.CanApplyDirectConversion(sum)) { var convertedSum = this.converter.DirectConversion(sum); if (convertedSum <= 0 || convertedSum > approximateMedians.Length) { throw new IndexOutOfRangeException(string.Format( "The medians sum {0} is out of bounds. It must be between 1 and the number of elements in medians array.", convertedSum)); } var solutionBoard = new CoeffType[approximateMedians.Length]; var marked = new BitArray(approximateMedians.Length, false); if (settedSolutions.Count == convertedSum) { var result = new GreedyAlgSolution <CoeffType>(settedSolutions); result.Cost = this.ComputeCost(settedSolutions, costs, solutionBoard, marked); return(result); } else { // Partição das mediana em dois conjuntos: as que vão falzer parte da solução e as restantes // entre as soluções aproximadas. var recoveredMedians = new List <int>(); var unrecoveredMedians = new List <int>(); var innerComparer = new InnerComparer(approximateMedians, this.comparer); approximateSolutions.Sort(innerComparer); var count = convertedSum - settedSolutions.Count; var i = 0; for (; i < count; ++i) { recoveredMedians.Add(approximateSolutions[i]); settedSolutions.Add(approximateSolutions[i]); } for (; i < approximateSolutions.Count; ++i) { unrecoveredMedians.Add(approximateSolutions[i]); } var currentCost = this.ComputeCost(settedSolutions, costs, solutionBoard, marked); // Processa as melhorias de uma forma simples caso seja possível if (unrecoveredMedians.Count > 0 && niter > 0) { var exchangeSolutionBoard = new CoeffType[solutionBoard.Length]; var currentBestBoard = new CoeffType[solutionBoard.Length]; for (i = 0; i < niter; ++i) { var itemToExchange = -1; var itemToExchangeIndex = -1; var itemToExchangeWith = -1; var itemToExchangeWithIndex = -1; var minimumCost = this.coeffsField.AdditiveUnity; for (int j = 0; j < recoveredMedians.Count; ++j) { for (int k = 0; k < unrecoveredMedians.Count; ++k) { var replacementCost = this.ComputeReplacementCost( unrecoveredMedians[k], recoveredMedians[j], settedSolutions, costs, solutionBoard, exchangeSolutionBoard); if (this.comparer.Compare(replacementCost, minimumCost) < 0) { // Aceita a troca itemToExchange = recoveredMedians[j]; itemToExchangeIndex = j; itemToExchangeWith = unrecoveredMedians[k]; itemToExchangeWithIndex = k; minimumCost = replacementCost; var swapBestBoard = currentBestBoard; currentBestBoard = exchangeSolutionBoard; exchangeSolutionBoard = swapBestBoard; } } } if (itemToExchange == -1 || itemToExchangeWith == -1) { i = niter - 1; } else { // Efectua a troca var swapSolutionBoard = solutionBoard; solutionBoard = currentBestBoard; currentBestBoard = swapSolutionBoard; currentCost = this.coeffsField.Add(currentCost, minimumCost); settedSolutions.Remove(itemToExchange); settedSolutions.Add(itemToExchangeWith); var swap = recoveredMedians[itemToExchangeIndex]; recoveredMedians[itemToExchangeIndex] = unrecoveredMedians[itemToExchangeWithIndex]; unrecoveredMedians[itemToExchangeWithIndex] = swap; } } } return(new GreedyAlgSolution <CoeffType>(settedSolutions) { Cost = currentCost }); } } else { throw new OdmpProblemException("The sum of medians can't be converted to an integer."); } } }