/// <summary> /// Conrstructor for the recurse method for this set of parameters. /// </summary> /// <param name="targetValue"></param> /// <param name="values"></param> /// <param name="result"></param> public Recurse(decimal targetValue, List <Invoice> values, Hits hits) { this.targetValue = targetValue; this.values = values; this.hits = hits; this.path = new Invoice[values.Count]; }
/// <summary> /// The MatchSum FindSoluions entry point. This is used to set up for the recursion and hide /// the uninteresting parameter details of the Recurse routine from users. /// </summary> /// <param name="targetValue">The sum being matched.</param> /// <param name="inputValues">A List of match against targetValue.</param> /// <returns>List of List of decimal. Each sub list constitutes one match.</returns> public static Hits Hits(Payment payment, Invoices inputValues) { // Protect against invalid parameters if (inputValues == null || inputValues.Count == 0) { throw new ArgumentException("Please pass in a valid list of decimals."); } if (payment.Amount <= 0) { throw new ArgumentException("The targetValue has to be a non zero positive decimal."); } // Make a copy as we do no wish to disturb shape of the orignal List passed in. Invoices values = new Invoices(inputValues); // Sort in decending order to make the recursion more shallow by adding the // higest values first. There is no descnding sort option so Reverse is simpler // than writing a custom IComparer for these relatively small inputs. values.Sort(); values.Reverse(); // Call the recursive tree search for sums matching target. Hits hits = new Hits(payment); Recurse recurse = new Recurse(payment.Amount, values, hits); recurse.FindHits(); return(hits); }
private static void RandomTest() { // Setup a test dataset Invoices inputInvoices; List <Payment> inputPayments; GenerateRandomData(out inputInvoices, out inputPayments); // Write out the input invoice set Console.WriteLine("Invoices to match"); inputInvoices.Write(); Console.WriteLine("Number of payments " + inputPayments.Count); Console.WriteLine(); // Match all invoices against all payments; for (int i = 0; i < inputPayments.Count; i++) { // Write out the payment details. Console.WriteLine("Matches against Payment " + inputPayments[i].Date + " ID:" + inputPayments[i].Reference + " in the amount of " + inputPayments[i].Amount + " against an input set of " + inputInvoices.Count + " invoices" ); // Perform the match Invoices invoicesToMatch = inputInvoices.GetUpToDate(inputPayments[i].Date); Hits hits = MatchPayment.Hits(inputPayments[i], invoicesToMatch); Console.WriteLine("Found " + hits.Count + " hits. Attempting best hit"); Hit bestHit = hits.BestHit(); if (bestHit != null) { // Remove the hits from the match list. inputInvoices.Remove(bestHit); // Write out the match. bestHit.Write(); } else { Console.WriteLine("*** There was no match against this payment"); } Console.WriteLine(); } // Write all unmatched Invoices. Console.WriteLine("Unmatched invoices"); inputInvoices.Write(); // Wait for keypress to exit Console.WriteLine(); Console.WriteLine("Press Return to exit"); Console.ReadLine(); }
/// <summary> /// Simple test suitable for speed testing. /// </summary> private static void SimpleTest() { // Setup a test dataset Invoices inputInvoices; List <Payment> inputPayments; GenerateSimpleData(out inputInvoices, out inputPayments); // Mark the current time long ticks = DateTime.Now.Ticks; // Perform the match Hits hits = MatchPayment.Hits(inputPayments[0], inputInvoices); // Mark the end of computation Console.WriteLine("Search complete for " + inputInvoices.Count + " levels"); Console.WriteLine("Payment " + hits.Payment.Reference + " in the amount of " + hits.Payment.Amount); Console.WriteLine("Time taken: " + (DateTime.Now.Ticks - ticks) / 10000000.0 + " seconds"); Console.WriteLine(); // Write all hits. Console.WriteLine("Hits"); hits.Write(); Console.WriteLine(); // Write out the best hit. Console.WriteLine("Best hit"); Hit bestHit = hits.BestHit(); bestHit.Write(); Console.WriteLine(); // Write all unmatched Invoices. Console.WriteLine("Unmatched invoices"); inputInvoices.Remove(bestHit); inputInvoices.Write(); // Wait for keypress to exit Console.ReadLine(); }