/// <summary> /// Ons the matrix source changed impl. /// </summary> /// <param name="oldValue">Old value.</param> /// <param name="newValue">New value.</param> protected virtual void OnMatrixSourceChangedImpl(CostMatrix oldValue, CostMatrix newValue) { Children.Clear(); if (MatrixSource == null) { return; } for (int row = 0; row < MatrixSource.NumberOfRows; row++) { for (int col = 0; col < MatrixSource.NumberOfColumns; col++) { var cell = new MatrixCell() { Row = row, Column = col, Text = MatrixSource[row, col].ToString() }; Children.Add(cell); } } UpdateCells(Width, Height); }
private void btnLoadScene_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; IList <ICartesianCoordinate> coordinates = null; CostMatrix <double> costs = null; if (radioButton1.Checked) { coordinates = LoadCSV_Coordinates(Path.Combine(dropboxlocation, @"10001.csv")); } else if (radioButton2.Checked) { coordinates = new[] { new Point(3, 0), new Point(3, 5), new Point(5, 2), new Point(1, 1), new Point(4, 6) }; } if (radioButton4.Checked) { costs = LoadCSV_Costs(Path.Combine(dropboxlocation, @"dump.csv"), coordinates.Count); } else if (radioButton3.Checked) { var costWithFunction = new CostWithFunction <ICartesianCoordinate>(coordinates, Diverse.DistanceSquared); costs = new CostMatrix <double>(costWithFunction, coordinates.Count); } boundingRectangle = coordinates.BoundingRectangle(); // for viewport algorithmSet = new AlgorithmSet <ICartesianCoordinate>(coordinates, costs); algorithmSet.ClusterAfterIterationEvent += algorithmSet_ClusterAfterIterationEvent; algorithmSetClusters = null; lastTSPResultWithClusters = null; panel1.Refresh(); }
/// <summary> /// Parse the specified input into cost-matrix/grid /// </summary> /// <returns>The parsed matrix.</returns> /// <param name="input">String input</param> /// <remarks>The input consists of a sequence of row specifications. /// Each row is represented by a series of delimited integers on a single line. /// Note: integers are not restricted to being positive. </remarks> /// <exception cref="ArgumentNullException" /> /// <exception cref="FormatException" /> public CostMatrix Parse(string input) { //Check for empty input if (string.IsNullOrWhiteSpace(input)) { throw new ArgumentNullException(nameof(input)); } //Check whether input is in expected delimited format (extra spaces or newlines are allowed). if (!IsValid(input)) { throw new FormatException($"Invalid {nameof(input)}: Unexpected pattern, or characters."); } //Split input string for rows (using newline as delimiter) var valueRows = Regex.Split(input.Trim(), NEWLINE_PATTERN); //Initialize with invalid value var numberOfColumns = -1; //Initialize list (which we will use to fill, or generate cost matrix later) var costValueList = new List <string[]>(); foreach (var valueRow in valueRows) { //ignore empty rows (usually caused by extra whitespace) if (string.IsNullOrWhiteSpace(valueRow)) { continue; } //split each row for column values var values = Regex.Split(valueRow.Trim(), m_columnDelimiter); //remove empty strings (usually caused by extra whitespace) values = values.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); //Initialize first and validate in the next round if (numberOfColumns == -1) { numberOfColumns = values.Length; } else if (numberOfColumns != values.Length) { throw new FormatException($"Invalid {nameof(input)}: Column sizing is not uniform."); } costValueList.Add(values); } //Once we have parsed cost-value list, use it to generate cost-matrix var costGrid = new CostMatrix(costValueList.Count, numberOfColumns); costGrid.FillCostGrid(costValueList); return(costGrid); }
/// <summary> /// Prints the cost matrix. /// </summary> /// <param name="grid">Grid.</param> static void PrintCostMatrix(CostMatrix grid) { Console.WriteLine(); Console.ForegroundColor = MSG_COLOR; Console.WriteLine("You entered: "); Console.ForegroundColor = DATA_COLOR; Console.WriteLine(grid.ToString()); }
public ClusteredGraphToCostMatrix(ICostByReference <TNode, double> costsUnclustered, IList <Cluster <TNode, double> > clusters) { var costsArrayClusters = new List <double[]>(); var relevantNodes = clusters.SelectMany(cl => cl.Nodes.Count() == 1 ? new[] { new ClusterNode { cluster = cl, node = cl.Nodes.First() } } : new[] { new ClusterNode { cluster = cl, node = cl.Nodes.First() }, new ClusterNode { cluster = cl, node = cl.Nodes.Last() } }); ClusterEndPoints = relevantNodes.ToList(); foreach (var first in ClusterEndPoints) { var costsForFirstNode = new List <double>(); foreach (var second in ClusterEndPoints) { if (!Object.ReferenceEquals(first.cluster, second.cluster)) { var cost = costsUnclustered.Cost(first.node, second.node) * 100000; costsForFirstNode.Add(cost); } else { if (Object.ReferenceEquals(first.node, second.node)) { var cost = costsUnclustered.Cost(first.node, second.node); costsForFirstNode.Add(cost); } else { double cost; if (Object.ReferenceEquals(first, first.cluster.Nodes.First())) { cost = first.cluster.TotalCost - first.cluster.TotalCostReverse < 0D ? 0D : first.cluster.TotalCost - first.cluster.TotalCostReverse; } else { cost = first.cluster.TotalCostReverse - first.cluster.TotalCost < 0D ? 0D : first.cluster.TotalCostReverse - first.cluster.TotalCost; } costsForFirstNode.Add(cost); } } } costsArrayClusters.Add(costsForFirstNode.ToArray()); } CostMatrix = new CostMatrix <double>(costsArrayClusters.ToArray()); }
public async Task UpdateCostMatrixAsync(CostMatrix costMatrix, string company) { var queryParameters = new DynamicParameters(); queryParameters.Add("@CostmatrixId", costMatrix.CostMatrixId); queryParameters.Add("@Description", costMatrix.Description); queryParameters.Add("@CompanyId", company); queryParameters.Add("@CostMatrixLines", ConvertToCostmatrixUDTT(costMatrix.CostMatrixLines)); await ExecuteNonQueryAsync( StoredProcedureNames.UpdateCostMatrix, queryParameters, true); }
public IList <Cluster <TNode, double> > Solve([NotNull] IList <TNode> Nodes, [NotNull] CostAnalyzer <double> costanalyzer, double maxCostOfNearestNeighbor, int maxNodesPerCluster = -1) { var clusterFactory = new ClusterFactory(Nodes, costanalyzer); var transposedCostMatrix = CostMatrix <double> .CreateTransposed(costanalyzer.CostMatrix); var transposedCostanalyzer = new CostAnalyzer <double>(transposedCostMatrix); // While unhandled indexes available and the loop runs for at most a certain amount of times, continue the algorithm for (var counter = 0; counter < Nodes.Count * maxFactorOfLoopCount && clusterFactory.NodesAsIndexes.Count > 0; counter++) { // set the current pointer to a random node index among the nodes not yet classified in a cluster int currentPointer = clusterFactory.NodesAsIndexes[randomizer.Next(0, clusterFactory.NodesAsIndexes.Count - 1)]; var candidateCluster = CalculateCluster(clusterFactory.NodesAsIndexes, costanalyzer, transposedCostanalyzer, maxCostOfNearestNeighbor, maxNodesPerCluster); if (candidateCluster.Count > 1) { // loop over the cluster again maybe to cut the cluster in pieces. Clusters with one item are thrown back in the pool for (int indexInCluster = 0; indexInCluster < candidateCluster.Count - 1; indexInCluster++) { var maxCostInCluster = indexInCluster == 0 ? costanalyzer.AllNeighborsOrdered(candidateCluster[0])[candidateCluster[1]] : candidateCluster.Take(indexInCluster + 1).Tuples().Max(t => costanalyzer.AllNeighborsOrdered(t.Item1)[t.Item2]); var nodesOutsideClusterQuiteCloseToCluster = costanalyzer.AllNeighborsOrdered(candidateCluster[indexInCluster]) .Where(neighbor => !candidateCluster.Contains(neighbor.Key) && neighbor.Value <= maxCostInCluster); if (nodesOutsideClusterQuiteCloseToCluster.Count() > 1) // Split the cluster { var firstPart = candidateCluster.GetRange(0, indexInCluster + 1); clusterFactory.CreateCluster(firstPart); candidateCluster.RemoveRange(0, indexInCluster + 1); indexInCluster = -1; } } } clusterFactory.CreateCluster(candidateCluster); } // Here we add the singleton clusters from the remaining nodes clusterFactory.CreateSingletonClusters(); return(clusterFactory.ListOfClusters); }
/// <summary> /// Fills the cost grid. /// </summary> /// <param name="costGrid">Target cost-grid to be filled.</param> /// <param name="costValues">Parsed input cost values.</param> public static void FillCostGrid(this CostMatrix costGrid, IList <string[]> costValues) { if (costValues == null) { throw new ArgumentNullException(nameof(costValues)); } for (var row = 0; row < costGrid.NumberOfRows; row++) { for (var col = 0; col < costGrid.NumberOfColumns; col++) { costGrid[row, col] = costValues[row][col].ToCostValue(); } } }
public void Ensure_PathIsCalculated_OnValidMatrixInput(DataSet data) { var inputCostGrid = new CostMatrix(data.MappedCostValues); var actualPath = _target.GetLowestTraversalPath(inputCostGrid); Assert.AreEqual(actualPath.IsValid, data.IsPathAvailable); Assert.AreEqual(actualPath.TotalCost, data.TotalCost, message: data.Input); if (!actualPath.RowIndices.SequenceEqual(data.PathRowIndices)) { Assert.Inconclusive( Extensions.ToMessage( expected: data.PathRowIndices, actual: actualPath.RowIndices)); } }
/// <summary> /// Computes the lowest cost path, in recursive manner. /// </summary> /// <returns>Calculate the lowest cost path.</returns> /// <param name="matrix">Cost matrix.</param> /// <param name="row">For specified row.</param> /// <param name="column">For specified column.</param> TraversalPath ComputeLowestCostPath(CostMatrix matrix, int row, int column) { TraversalPath lowestPath; if (column == 0) { //If we have reached the first column, we send back a new path instance lowestPath = new TraversalPath(matrix.NumberOfColumns); } else { //Calculate lowest path for one-row up from previous column var rowUpCostPath = ComputeLowestCostPath(matrix, matrix.RowUp(row), column - 1); //Calculate lowest path for current row from previous column var rowNextCostPath = ComputeLowestCostPath(matrix, row, column - 1); //Calculate lowest path for one-row down from previous column var rowDownCostPath = ComputeLowestCostPath(matrix, matrix.RowDown(row), column - 1); //and find the lowest path from all three possible moves lowestPath = rowUpCostPath; if (rowNextCostPath < lowestPath) { lowestPath = rowNextCostPath; } if (rowDownCostPath < lowestPath) { lowestPath = rowDownCostPath; } } //once we have the lowest possible move (or cost) we append that to current path //and also validate if it reaches max possible cost (if it does we invalidate the //path to abadon it) var nextPathTraversalCost = lowestPath.TotalCost + matrix[row, column]; if (nextPathTraversalCost <= m_maxCost) { lowestPath.Append(row, matrix[row, column]); } else { lowestPath.Invalidate(); } return(lowestPath); }
public async Task <long> CreateCostMatrixAsync(CostMatrix costMatrix, string company) { var queryParameters = new DynamicParameters(); queryParameters.Add("@Name", costMatrix.Name); queryParameters.Add("@Description", costMatrix.Description); queryParameters.Add("@CompanyId", company); queryParameters.Add("@CostMatrixLines", ConvertToCostmatrixUDTT(costMatrix.CostMatrixLines)); queryParameters.Add("@CostMatrixId", dbType: DbType.Int64, direction: ParameterDirection.Output); await ExecuteNonQueryAsync(StoredProcedureNames.CreateCostmatrix, queryParameters, true); var costMatrixId = queryParameters.Get <long>("@CostMatrixId"); return(costMatrixId); }
/// <summary> /// Finds next row-index for move-down traversal /// </summary> /// <returns>The up.</returns> /// <param name="costGrid">Cost grid.</param> /// <param name="row">Row index</param> public static int RowDown(this CostMatrix costGrid, int row) { if (costGrid == null) { throw new ArgumentNullException(nameof(costGrid)); } if (row < 0 || row >= costGrid.NumberOfRows) { throw new IndexOutOfRangeException($"Invalid index for {nameof(row)}"); } if (row == costGrid.NumberOfRows - 1) { return(0); } return(row + 1); }
static void Main(string[] args) { int[,] matrix = new int[, ] { { 1500, 4000, 4500 }, { 2000, 6000, 3500 }, { 2000, 4000, 2500 } }; CostMatrix costMatrix = new CostMatrix(matrix); costMatrix.Display(); HungarianAlgoPerformer performer = new HungarianAlgoPerformer(costMatrix); performer.Execute(); costMatrix.Display(); Console.WriteLine($"Result: {costMatrix.ResultSum}"); int[] optAssignments = performer.CostMatrix.OptimalAssignments(); foreach (int item in optAssignments) { Console.Write($"{item}, "); } }
/// <summary> /// Applies strategy/algorithm for calculating lowest-cost path across /// the specified cost-matrix. /// </summary> /// <returns>The lowest traversal path.</returns> /// <param name="matrix">The cost matrix.</param> public override TraversalPath GetLowestTraversalPath(CostMatrix matrix) { //start with null-path TraversalPath lowestCostPath = null; for (int row = 0; row < matrix.NumberOfRows; row++) { //for each row in matrix initiate recursive method to calculate lowest //traversal path. But, we start from the end (last column and move on to first column) var costPath = ComputeLowestCostPath(matrix, row, matrix.NumberOfColumns - 1); //for every row, compare cost (lowest traversal for corresponding row) and //accordingly set the lowestCostPath if (lowestCostPath == null || costPath <= lowestCostPath) { lowestCostPath = costPath; } } //if not path found, send empty traversal path return(lowestCostPath ?? new TraversalPath(0)); }
public static void AreEqual(CostMatrix costGrid, int[,] values, string message = null) { if (values == null) { Assert.IsTrue(costGrid.NumberOfColumns == 0 && costGrid.NumberOfRows == 0, message); return; } if (values != null) { Assert.IsTrue(costGrid.NumberOfColumns == values.GetLength(1) && costGrid.NumberOfRows == values.GetLength(0), message); } for (var i = 0; i < values.GetLength(0); i++) { for (var j = 0; j < values.GetLength(1); j++) { Assert.AreEqual(costGrid[i, j], values[i, j], message); } } }
private void Initialise() { var costMatrixCopy = CostMatrix.Copy(); if (CostMatrix.NumberOfRows > CostMatrix.NumberOfColumns) { _isTransposed = true; costMatrixCopy = costMatrixCopy.Transpose(); } _numberOfRows = costMatrixCopy.NumberOfRows; _numberOfColumns = costMatrixCopy.NumberOfColumns; _c = costMatrixCopy.Data; _path = new int[_numberOfRows + _numberOfColumns + 1, 2]; _rowCover = new int[_numberOfRows]; _columnCover = new int[_numberOfColumns]; _m = new double[_numberOfRows, _numberOfColumns]; _stepNumber = 1; }
private void btnLoadScene_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; IList<ICartesianCoordinate> coordinates = null; CostMatrix<double> costs = null; if (radioButton1.Checked) { coordinates = LoadCSV_Coordinates(Path.Combine(dropboxlocation, @"10001.csv")); } else if (radioButton2.Checked) { coordinates = new[] { new Point(3, 0), new Point(3, 5), new Point(5, 2), new Point(1, 1), new Point(4, 6) }; } if (radioButton4.Checked) { costs = LoadCSV_Costs(Path.Combine(dropboxlocation, @"dump.csv"), coordinates.Count); } else if (radioButton3.Checked) { var costWithFunction = new CostWithFunction<ICartesianCoordinate>(coordinates, Diverse.DistanceSquared); costs = new CostMatrix<double>(costWithFunction, coordinates.Count); } boundingRectangle = coordinates.BoundingRectangle(); // for viewport algorithmSet = new AlgorithmSet<ICartesianCoordinate>(coordinates, costs); algorithmSet.ClusterAfterIterationEvent += algorithmSet_ClusterAfterIterationEvent; algorithmSetClusters = null; lastTSPResultWithClusters = null; panel1.Refresh(); }
/// <summary> /// Finds the maximum value of a function. The solution vector /// will be made available at the <see cref="Solution" /> property. /// </summary> /// /// <returns>Returns <c>true</c> if the method converged to a <see cref="Solution" />. /// In this case, the found value will also be available at the <see cref="Value" /> /// property.</returns> /// public bool Maximize() { return(run(CostMatrix.Multiply(-1))); }
/// <summary> /// Finds the minimum value of a function. The solution vector /// will be made available at the <see cref="Solution" /> property. /// </summary> /// /// <returns>Returns <c>true</c> if the method converged to a <see cref="Solution" />. /// In this case, the found value will also be available at the <see cref="Value" /> /// property.</returns> /// public bool Minimize() { return(run(CostMatrix.Copy())); }
public static MyEvaluation TestInstances(Instances testInstances, Classifier cls, CostMatrix costMatrix = null) { //Evaluation eval = new Evaluation(testInstances, new CostMatrix(new BufferedReader(new FileReader(m_costFileName)))); MyEvaluation eval; if (costMatrix != null) { eval = new MyEvaluation(costMatrix); } else { eval = new MyEvaluation(); } //eval.crossValidateModel(cls, origInstances, 5, new java.util.Random(1)); //WriteLog(eval.toSummaryString()); //WriteLog("Confusion matrix is " + eval.toMatrixString()); //WriteLog("total cose is " + eval.totalCost()); //WriteLog("Crossvalidate is done."); //using (System.IO.StreamWriter sw = new StreamWriter(string.Format("{0}\\crossValidateResult.txt", m_baseDir), true)) //{ // sw.WriteLine(string.Format("CrossValidate Data from {0} to {1}", m_trainTimeStart.ToString(m_dateTimeFormat), m_trainTimeEnd.ToString(m_dateTimeFormat))); // sw.WriteLine(eval.toSummaryString()); // sw.WriteLine("Confusion matrix is " + eval.toMatrixString()); //} //eval.evaluateModel(cls, origInstances); //WriteEvalSummary(eval, string.Format("Train Data from {0} to {1}", m_trainTimeStart.ToString(m_dateFormat), m_trainTimeEnd.ToString(m_dateFormat))); eval.evaluateModel(cls, testInstances); return(eval); }
/// <summary> /// Applies strategy/algorithm for calculating lowest-cost path across /// the specified cost-matrix. /// </summary> /// <returns>The lowest traversal path.</returns> /// <param name="matrix">The cost matrix.</param> public override TraversalPath GetLowestTraversalPath(CostMatrix matrix) { //create a matrix that will cache traversal-cost for each cell TraversalPath[,] cachedPaths = new TraversalPath[matrix.NumberOfRows, matrix.NumberOfColumns]; //in this case we first go column by column for (int column = 0; column < matrix.NumberOfColumns; column++) { //and calculate lowest traversal cost for that particular cell (each row in column) for (int row = 0; row < matrix.NumberOfRows; row++) { //initilize traversal path cachedPaths[row, column] = new TraversalPath(column + 1); //get cost for current cell var currentCellCost = matrix[row, column]; int traversalCost; if (column == 0) { //as it is first column, traversal-cost is same as current cell traversalCost = currentCellCost; } else { //get adjacent up row index var rowUpIndex = matrix.RowUp(row); //get adjacent down row index var rowDownIndex = matrix.RowDown(row); //get traversal cost for adjacent up-row for previous column var traversalPathFromUpRow = cachedPaths[rowUpIndex, column - 1]; //get traversal cost from current row for previous column var traversalPathFromPrevRow = cachedPaths[row, column - 1]; //get traversal cost from adjacent down-row for previous column var traversalPathFromDownRow = cachedPaths[rowDownIndex, column - 1]; //and find the lowest path from all three possible moves var lowestTraversalPath = traversalPathFromUpRow; if (traversalPathFromPrevRow < lowestTraversalPath) { lowestTraversalPath = traversalPathFromPrevRow; } if (traversalPathFromDownRow < lowestTraversalPath) { lowestTraversalPath = traversalPathFromDownRow; } //once we have the lowest traversal cost we copy that onto current cell cache TraversalPath.Copy(lowestTraversalPath, cachedPaths[row, column]); //and calculate total traversalCost = lowestTraversalPath.TotalCost + currentCellCost; } //if traversal cost is valid, we append that current cell cache if (traversalCost <= m_maxCost) { cachedPaths[row, column].Append(row, currentCellCost); } //else we abadon the path (that is invalidate the cell) else { cachedPaths[row, column].Invalidate(); } } } //With the cache grid ready and initialized, we find the lowest cost by //traversing TraversalPath lowestCostPath = null; if (matrix.NumberOfColumns >= 1) { for (int row = 0; row < matrix.NumberOfRows; row++) { var costPath = cachedPaths[row, matrix.NumberOfColumns - 1]; if (lowestCostPath == null || costPath <= lowestCostPath) { lowestCostPath = costPath; } } } return(lowestCostPath ?? new TraversalPath(0)); }
public AlgorithmSet(IList <TNode> nodes, CostMatrix <double> costMatrix) : this() { this.Nodes = nodes; CostMatrix = costMatrix; }
/// <summary> /// Applies strategy/algorithm for calculating lowest-cost path across /// the specified cost-matrix. /// </summary> /// <returns>The lowest traversal path.</returns> /// <param name="matrix">The cost matrix.</param> public abstract TraversalPath GetLowestTraversalPath(CostMatrix matrix);