Heron Algorithm Recursive C# - c#

I'm trying to implement the heron algorithm recursively in C#.
I don't really understand where my code is wrong:
Given definition of algorithm:
x[n+1] = (p-1) /p*x[n] + a/p*x[n]^p-1
Where xo = 1 and p root a
public static double Heron(int x,int p,int a)
{
if(x == 0)
{
return 1.0;
}
return ((p-1.0)/p)*Heron(--x,p,a)+a/(p*Math.Pow(Heron(--x,p,a),--p));
}
e.g Heron(1,3,5) should return 7/3;

Don't modify the value of x and p in your expression.
Just use
double x_n = Heron(x-1,p,a);
return ((p-1.0)/p)*x_n+a/(p*Math.Pow(x_n,p-1));
I have also kept the value of the recursion in x_n so it does not get called twice.

Related

Starting value in optimization algorithms

I am trying to use the L-BFGS solver in Accord.net maths package in C#.
However, I cannot find how to define the starting value of the optimization.
How can we define it ?
According to official examples, the following syntax defines the initial value of x in the optimization process. However it does not work properly in the following example - as if another starting point was used by the algorithm.
//Target function to minimize;
public double f(double[] x) {
double z = Math.Cos(x[0])-0.2*x[0] + x[1] * x[1]; //Function with multiple local minima : x ~ { (2n+1)pi , 0 }
return z;
}
//Gradient
public double[] g(double[] x) {
double[] grad = {-Math.Sin(x[0])-0.2 , 2 * x[1]};
return grad;
}
double[] x = {3*3.141592,0}; // Starting value (local minimum, -2.88)
var lbfgs = new BroydenFletcherGoldfarbShanno(numberOfVariables: 2, function: f, gradient: g);
bool success = lbfgs.Minimize();
double minValue = lbfgs.Value;
double[] solution = lbfgs.Solution; // {3.34,0} This solution is a local min that has a higher value (-1.65) than the local min next to which we started !!
The syntax is simply:
lbfgs.Minimize(x);
Thank you "500 - Internal Server Error" !

In C#, what does a call to Sort with two parameters in brackets mean?

I recently came across an implementation of Djikstra's Shortest Path algorithm online and found the following call.
given a List of nodes of type int and a Dictionary of distances, of type , what does the following call mean
nodes.Sort((x, y) => distances[x] - distances[y]);
The full code is as follows:
public List<int> shortest_path(int start, int finish)
{
var previous = new Dictionary<int, int>();
var distances = new Dictionary<int, int>();
var nodes = new List<int>();
List<int> path = null;
foreach (var vertex in vertices)
{
if (vertex.Item1 == start)
{
distances[vertex.Item1] = 0;
}
else
{
distances[vertex.Item1] = int.MaxValue / 2;
}
nodes.Add(vertex.Item1);
}
while (nodes.Count != 0)
{
nodes.Sort((x, y) => distances[x] - distances[y]);
var smallest = nodes[0];
nodes.Remove(smallest);
if (smallest == finish)
{
path = new List<int>();
while (previous.ContainsKey(smallest))
{
path.Add(smallest);
smallest = previous[smallest];
}
break;
}
if (distances[smallest] == int.MaxValue)
{
break;
}
foreach (var neighbor in vertices[smallest].Item2)
{
var alt = distances[smallest] + neighbor.Item2;
if (alt < distances[neighbor.Item1])
{
distances[neighbor.Item1] = alt;
previous[neighbor.Item1] = smallest;
}
}
}
return path;
}
I searched for the answer a lot but there doesn't seem to be any clear explanation of what it means.
I do know that in general in LINQ, a call to Array.Select((x,i)=>...) means that x is the actual element in the array and i is the index of element x in the array, but this doesn't seem to be the case above.
Would appreciate any explanation thanks.
In C#, what does a call to Sort with two parameters in brackets mean?
You have this line of code:
nodes.Sort((x, y) => distances[x] - distances[y]);
You are not passing two parameters to the sort method but you are passing one parameter which is a delegate that takes 2 parameters. You are essentially doing the following but using a lambda notation:
var nodes = new List<int>();
nodes.Sort(SortIt);
And here is the SortIt method:
private int SortIt(int x, int y)
{
return distances[x] - distances[y];
}
Keep in mind if you did it using the above approach, distances will have to be a class level field so the SortIt method can access it. With lambda expressions, this is what you have, it will just capture the distances variable and this is called a closure. Read this article if you want to know what closures are.
Sorting is implemented by comparing two items at a time.
The two parameters in parentheses are the two items the callback function should compare.
List.Sort Method takes an optional comparison delegate as a comparer.
https://msdn.microsoft.com/en-us/library/w56d4y5z(v=vs.110).aspx
in your example:
(x, y) => distances[x] - distances[y]) is a delegate that Sort uses as a comparer.
if distances[x] - distances[y] < 0; x is bigger;
if distances[x] - distances[y] > 0; y is bigger;
if distances[x] - distances[y] > 0; both are even;
This method will sort the elements in the entire List using the specified System.Comparison.
Where System.Comparison is a delegate
public delegate int Comparison<in T>(
T x,
T y
)
Think of it like this, you are passing the sort method a way to decide which element in the array is a precedent to the other. The sort function will use the compare function you specified to determine the precedence of each element in the returned sorted list. Therefore this function will get two elements and it will return a value indicating the result of the precendence.
let x be the first argument and y the second argument.
x < y -> the function will return a number less than 0
x = y -> the function will return 0
x > y -> the function will return a number bigger than 0
In conclusion, this function you pass to the Sort method will help the Sort function to sort the array as you wish it should sort it.

Dice Sorensen Distance error calculating Bigrams without using Intersect method

I have been programming an object to calculate the DiceSorensen Distance between two strings. The logic of the operation is not so difficult. You calculate how many two letter pairs exist in a string, compare it with a second string and then perform this equation
2(x intersect y)/ (|x| . |y|)
where |x| and |y| is the number of bigram elements in x & y. Reference can be found here for further clarity https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient
So I have tried looking up how to do the code online in various spots but every method I have come across uses the 'Intersect' method between two lists and as far as I am aware this won't work because if you have a string where the bigram already exists it won't add another one. For example if I had a string
'aaaa'
I would like there to be 3 'aa' bigrams but the Intersect method will only produce one, if i am incorrect on this assumption please tell me cause i wondered why so many people used the intersect method. My assumption is based on the MSDN website https://msdn.microsoft.com/en-us/library/bb460136(v=vs.90).aspx
So here is the code I have made
public static double SorensenDiceDistance(this string source, string target)
{
// formula 2|X intersection Y|
// --------------------
// |X| + |Y|
//create variables needed
List<string> bigrams_source = new List<string>();
List<string> bigrams_target = new List<string>();
int source_length;
int target_length;
double intersect_count = 0;
double result = 0;
Console.WriteLine("DEBUG: string length source is " + source.Length);
//base case
if (source.Length == 0 || target.Length == 0)
{
return 0;
}
//extract bigrams from string 1
bigrams_source = source.ListBiGrams();
//extract bigrams from string 2
bigrams_target = target.ListBiGrams();
source_length = bigrams_source.Count();
target_length = bigrams_target.Count();
Console.WriteLine("DEBUG: bigram counts are source: " + source_length + " . target length : " + target_length);
//now we have two sets of bigrams compare them in a non distinct loop
for (int i = 0; i < bigrams_source.Count(); i++)
{
for (int y = 0; y < bigrams_target.Count(); y++)
{
if (bigrams_source.ElementAt(i) == bigrams_target.ElementAt(y))
{
intersect_count++;
//Console.WriteLine("intersect count is :" + intersect_count);
}
}
}
Console.WriteLine("intersect line value : " + intersect_count);
result = (2 * intersect_count) / (source_length + target_length);
if (result < 0)
{
result = Math.Abs(result);
}
return result;
}
In the code somewhere you can see I call a method called listBiGrams and this is how it looks
public static List<string> ListBiGrams(this string source)
{
return ListNGrams(source, 2);
}
public static List<string> ListTriGrams(this string source)
{
return ListNGrams(source, 3);
}
public static List<string> ListNGrams(this string source, int n)
{
List<string> nGrams = new List<string>();
if (n > source.Length)
{
return null;
}
else if (n == source.Length)
{
nGrams.Add(source);
return nGrams;
}
else
{
for (int i = 0; i < source.Length - n; i++)
{
nGrams.Add(source.Substring(i, n));
}
return nGrams;
}
}
So my understanding of the code step by step is
1) pass in strings
2) 0 length check
3) create list and pass up bigrams into them
4) get the lengths of each bigram list
5) nested loop to check in source position[i] against every bigram in target string and then increment i until no more source list to check against
6) perform equation mentioned above taken from wikipedia
7) if result is negative Math.Abs it to return a positive result (however i know the result should be between 0 and 1 already this is what keyed me into knowing i was doing something wrong)
the source string i used is source = "this is not a correct string" and the target string was, target = "this is a correct string"
the result I got was -0.090909090908
I'm SURE (99%) that what I'm missing is something small like a mis-calculated length somewhere or a count mis-count. If anyone could point out what i'm doing wrong I'd be really grateful. Thank you for your time!
This looks like homework, yet this similarity metric on strings is new to me so I took a look.
Algorith implementation in various languages
As you may notice the C# version uses HashSet and takes advantage of the IntersectWith method.
A set is a collection that contains no duplicate elements, and whose
elements are in no particular order.
This solves your string 'aaaa' puzzle. Only one bigram there.
My naive implementation on Rextester
If you prefer Linq then I'd suggest Enumerable.Distinct, Enumerable.Union and Enumerable.Intersect. These should mimic very well the duplicate removal capabilities of the HashSet.
Also found this nice StringMetric framework written in Scala.

Need help for search optimization

I am fairly new to programming and i need some help with optimizing.
Basically a part of my method does:
for(int i = 0; i < Tiles.Length; i++)
{
x = Tiles[i].WorldPosition.x;
y = Tiles[i].WorldPosition.y;
z = Tiles[i].WorldPosition.z;
Tile topsearch = Array.Find(Tiles,
search => search.WorldPosition == Tiles[i].WorldPosition +
new Vector3Int(0,1,0));
if(topsearch.isEmpty)
{
// DoMyThing
}
}
So i am searching for a Tile in a position which is 1 unit above the current Tile.
My problem is that for the whole method it takes 0.1 secs which results in a small hick up..Without Array.Find the method is 0.01 secs.
I tried with a for loop also, but still not great result, because i need 3 more checks for
the bottom, left and right..
Can somebody help me out and point me a way of acquiring some fast results?
Maybe i should go with something like threading?
You could create a 3-dimensional array so that you can look up a tile at a specific location by just looking what's in Tiles[x, y + 1, z].
You can then iterate through your data in 2 loops: one to build up Tiles and one to do the checks you are doing in your code above, which would then just be:
for(int i = 0; i < Tiles.Length; i++)
{
Tile toFind = Tiles[Tile[i].x, Tile[i].y + 1, Tile[i].z];
if (toFind != null) ...
}
You would have to dimension the array so that you have 1 extra row in the y so that Tiles[x, y + 1, z] doesn't cause an index-out-of-range exception.
Adding to Roy's solution, if the space is not continuous, as it might be, you could put a hashcode of WorldPosition (the x, y and z coordinates) to some good use here.
I mean you could override WorldPosition's GetHashCode with your own implementation like that:
public class WorldPosition
{
public int X;
public int Y;
public int Z;
public override int GetHashCode()
{
int result = X.GetHashCode();
result = (result * 397) ^ Y.GetHashCode();
result = (result * 397) ^ Z.GetHashCode();
return result;
}
}
See Why is '397' used for ReSharper GetHashCode override? for explanation.
Then you can put your tiles in a Dictionary<WorldPosition, Tile>.
This would allow for quickly looking up for dict[new WorldPosition(x, y, z + 1)] etc. Dictionaries use hashcode for keys, so it would be fast.
First, like #Roy suggested, try storing the values in an array so you can access them with x,y,z coordinates,
Another thing you could do is change the search to
Tile topsearch = Array.Find(Tiles,
search => search.WorldPosition.x == Tiles[i].WorldPosition.x &&
search.WorldPosition.y == (Tiles[i].WorldPosition.y + 1) &&
search.WorldPosition.z == Tiles[i].WorldPosition.z)
This might be faster as well, depending on how many fields your WorldPosition has

Find the closest number in a list of numbers

I have a list of constant numbers. I need to find the closest number to x in the list of the numbers. Any ideas on how to implement this algorithm?
Well, you cannot do this faster than O(N) because you have to check all numbers to be sure you have the closest one. That said, why not use a simple variation on finding the minimum, looking for the one with the minimum absolute difference with x?
If you can say the list is ordered from the beginning (and it allows random-access, like an array), then a better approach is to use a binary search. When you end the search at index i (without finding x), just pick the best out of that element and its neighbors.
I suppose that the array is unordered. In ordered it can be faster
I think that the simpliest and the fastest method is using linear algorithm for finding minimum or maximum but instead of comparing values you will compare absolute value of difference between this and needle.
In the C++ ( I can't C# but it will be similar ) can code look like this:
// array of numbers is haystack
// length is length of array
// needle is number which you are looking for ( or compare with )
int closest = haystack[0];
for ( int i = 0; i < length; ++i ) {
if ( abs( haystack[ i ] - needle ) < abs( closest - needle ) ) closest = haystack[i];
}
return closest;
In general people on this site won't do your homework for you. Since you didn't post code I won't post code either. However, here's one possible approach.
Loop through the list, subtracting the number in the list from x. Take the absolute value of this difference and compare it to the best previous result you've gotten and, if the current difference is less than the best previous result, save the current number from the list. At the end of the loop you'll have your answer.
private int? FindClosest(IEnumerable<int> numbers, int x)
{
return
(from number in numbers
let difference = Math.Abs(number - x)
orderby difference, Math.Abs(number), number descending
select (int?) number)
.FirstOrDefault();
}
Null means there was no closest number. If there are two numbers with the same difference, it will choose the one closest to zero. If two numbers are the same distance from zero, the positive number will be chosen.
Edit in response to Eric's comment:
Here is a version which has the same semantics, but uses the Min operator. It requires an implementation of IComparable<> so we can use Min while preserving the number that goes with each distance. I also made it an extension method for ease-of-use:
public static int? FindClosestTo(this IEnumerable<int> numbers, int targetNumber)
{
var minimumDistance = numbers
.Select(number => new NumberDistance(targetNumber, number))
.Min();
return minimumDistance == null ? (int?) null : minimumDistance.Number;
}
private class NumberDistance : IComparable<NumberDistance>
{
internal NumberDistance(int targetNumber, int number)
{
this.Number = number;
this.Distance = Math.Abs(targetNumber - number);
}
internal int Number { get; private set; }
internal int Distance { get; private set; }
public int CompareTo(NumberDistance other)
{
var comparison = this.Distance.CompareTo(other.Distance);
if(comparison == 0)
{
// When they have the same distance, pick the number closest to zero
comparison = Math.Abs(this.Number).CompareTo(Math.Abs(other.Number));
if(comparison == 0)
{
// When they are the same distance from zero, pick the positive number
comparison = this.Number.CompareTo(other.Number);
}
}
return comparison;
}
}
It can be done using SortedList:
Blog post on finding closest number
If the complexity you're looking for counts only the searching the complexity is O(log(n)). The list building will cost O(n*log(n))
If you're going to insert item to the list much more times than you're going to query it for the closest number then the best choice is to use List and use naive algorithm to query it for the closest number. Each search will cost O(n) but time to insert will be reduced to O(n).
General complexity: If the collection has n numbers and searched q times -
List: O(n+q*n)
Sorted List: O(n*log(n)+q*log(n))
Meaning, from some q the sorted list will provide better complexity.
Being lazy I have not check this but shouldn't this work
private int FindClosest(IEnumerable<int> numbers, int x)
{
return
numbers.Aggregate((r,n) => Math.Abs(r-x) > Math.Abs(n-x) ? n
: Math.Abs(r-x) < Math.Abs(n-x) ? r
: r < x ? n : r);
}
Haskell:
import Data.List (minimumBy)
import Data.Ord (comparing)
findClosest :: (Num a, Ord a) => a -> [a] -> Maybe a
findClosest _ [] = Nothing
findClosest n xs = Just $ minimumBy (comparing $ abs . (+ n)) xs
Performance wise custom code will be more use full.
List<int> results;
int targetNumber = 0;
int nearestValue=0;
if (results.Any(ab => ab == targetNumber ))
{
nearestValue= results.FirstOrDefault<int>(i => i == targetNumber );
}
else
{
int greaterThanTarget = 0;
int lessThanTarget = 0;
if (results.Any(ab => ab > targetNumber ))
{
greaterThanTarget = results.Where<int>(i => i > targetNumber ).Min();
}
if (results.Any(ab => ab < targetNumber ))
{
lessThanTarget = results.Where<int>(i => i < targetNumber ).Max();
}
if (lessThanTarget == 0 )
{
nearestValue= greaterThanTarget;
}
else if (greaterThanTarget == 0)
{
nearestValue= lessThanTarget;
}
else if (targetNumber - lessThanTarget < greaterThanTarget - targetNumber )
{
nearestValue= lessThanTarget;
}
else
{
nearestValue= greaterThanTarget;
}
}

Categories

Resources