I have a struct called "Complex" in my project (I build it with using C#) and as the name of the struct implies, it's a struct for complex numbers. That struct has a built-in method called "Modulus" so that I can calculate the modulus of a complex number. The things are quite easy up to now.
The thing is, I create an array out of this struct and I want to sort the array according to the modulus of the complex numbers contained.(greater to smaller). Is there a way for that?? (Any algorithm suggestions will be welcomed.)
Thank you!!
Complex[] complexArray = ...
Complex[] sortedArray = complexArray.OrderByDescending(c => c.Modulus()).ToArray();
First of all, you can increase performances comparing squared modulus instead of modulus.
You don't need the squared root: "sqrt( a * a + b * b ) >= sqrt( c * c + d * d )" is equivalent to "a * a + b + b >= c * c + d * d".
Then, you can write a comparer to sort complex numbers.
public class ComplexModulusComparer :
IComparer<Complex>,
IComparer
{
public static readonly ComplexModulusComparer Default = new ComplexModulusComparer();
public int Compare(Complex a, Complex b)
{
return a.ModulusSquared().CompareTo(b.ModulusSquared());
}
int IComparer.Compare(object a, object b)
{
return ((Complex)a).ModulusSquared().CompareTo(((Complex)b).ModulusSquared());
}
}
You can write also the reverse comparer, since you want from greater to smaller.
public class ComplexModulusReverseComparer :
IComparer<Complex>,
IComparer
{
public static readonly ComplexModulusReverseComparer Default = new ComplexModulusReverseComparer();
public int Compare(Complex a, Complex b)
{
return - a.ModulusSquared().CompareTo(b.ModulusSquared());
}
int IComparer.Compare(object a, object b)
{
return - ((Complex)a).ModulusSquared().CompareTo(((Complex)b).ModulusSquared());
}
}
To sort an array you can then write two nice extension method ...
public static void SortByModulus(this Complex[] array)
{
Array.Sort(array, ComplexModulusComparer.Default);
}
public static void SortReverseByModulus(this Complex[] array)
{
Array.Sort(array, ComplexModulusReverseComparer.Default);
}
Then in your code...
Complex[] myArray ...;
myArray.SortReverseByModulus();
You can also implement the IComparable, if you wish, but a more correct and formal approach is to use the IComparer from my point of view.
public struct Complex :
IComparable<Complex>
{
public double R;
public double I;
public double Modulus() { return Math.Sqrt(R * R + I * I); }
public double ModulusSquared() { return R * R + I * I; }
public int CompareTo(Complex other)
{
return this.ModulusSquared().CompareTo(other.ModulusSquared());
}
}
And then you can write the ReverseComparer that can apply to every kind of comparer
public class ReverseComparer<T> :
IComparer<T>
{
private IComparer<T> comparer;
public static readonly ReverseComparer<T> Default = new ReverseComparer<T>();
public ReverseComparer<T>() :
this(Comparer<T>.Default)
{
}
public ReverseComparer<T>(IComparer<T> comparer)
{
this.comparer = comparer;
}
public int Compare(T a, T b)
{
return - this.comparer.Compare(a, b);
}
}
Then when you need to sort....
Complex[] array ...;
Array.Sort(array, ReverseComparer<Complex>.Default);
or in case you have another IComparer...
Complex[] array ...;
Array.Sort(array, new ReverseComparer<Complex>(myothercomparer));
RE-EDIT-
Ok i performed some speed test calculation.
Compiled with C# 4.0, in release mode, launched with all instances of visual studio closed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace TestComplex
{
class Program
{
public struct Complex
{
public double R;
public double I;
public double ModulusSquared()
{
return this.R * this.R + this.I * this.I;
}
}
public class ComplexComparer :
IComparer<Complex>
{
public static readonly ComplexComparer Default = new ComplexComparer();
public int Compare(Complex x, Complex y)
{
return x.ModulusSquared().CompareTo(y.ModulusSquared());
}
}
private static void RandomComplexArray(Complex[] myArray)
{
// We use always the same seed to avoid differences in quicksort.
Random r = new Random(2323);
for (int i = 0; i < myArray.Length; ++i)
{
myArray[i].R = r.NextDouble() * 10;
myArray[i].I = r.NextDouble() * 10;
}
}
static void Main(string[] args)
{
// We perform some first operation to ensure JIT compiled and optimized everything before running the real test.
Stopwatch sw = new Stopwatch();
Complex[] tmp = new Complex[2];
for (int repeat = 0; repeat < 10; ++repeat)
{
sw.Start();
tmp[0] = new Complex() { R = 10, I = 20 };
tmp[1] = new Complex() { R = 30, I = 50 };
ComplexComparer.Default.Compare(tmp[0], tmp[1]);
tmp.OrderByDescending(c => c.ModulusSquared()).ToArray();
sw.Stop();
}
int[] testSizes = new int[] { 5, 100, 1000, 100000, 250000, 1000000 };
for (int testSizeIdx = 0; testSizeIdx < testSizes.Length; ++testSizeIdx)
{
Console.WriteLine("For " + testSizes[testSizeIdx].ToString() + " input ...");
// We create our big array
Complex[] myArray = new Complex[testSizes[testSizeIdx]];
double bestTime = double.MaxValue;
// Now we execute repeatCount times our test.
const int repeatCount = 15;
for (int repeat = 0; repeat < repeatCount; ++repeat)
{
// We fill our array with random data
RandomComplexArray(myArray);
// Now we perform our sorting.
sw.Reset();
sw.Start();
Array.Sort(myArray, ComplexComparer.Default);
sw.Stop();
double elapsed = sw.Elapsed.TotalMilliseconds;
if (elapsed < bestTime)
bestTime = elapsed;
}
Console.WriteLine("Array.Sort best time is " + bestTime.ToString());
// Now we perform our test using linq
bestTime = double.MaxValue; // i forgot this before
for (int repeat = 0; repeat < repeatCount; ++repeat)
{
// We fill our array with random data
RandomComplexArray(myArray);
// Now we perform our sorting.
sw.Reset();
sw.Start();
myArray = myArray.OrderByDescending(c => c.ModulusSquared()).ToArray();
sw.Stop();
double elapsed = sw.Elapsed.TotalMilliseconds;
if (elapsed < bestTime)
bestTime = elapsed;
}
Console.WriteLine("linq best time is " + bestTime.ToString());
Console.WriteLine();
}
Console.WriteLine("Press enter to quit.");
Console.ReadLine();
}
}
}
And here the results:
For 5 input ...
Array.Sort best time is 0,0004
linq best time is 0,0018
For 100 input ...
Array.Sort best time is 0,0267
linq best time is 0,0298
For 1000 input ...
Array.Sort best time is 0,3568
linq best time is 0,4107
For 100000 input ...
Array.Sort best time is 57,3536
linq best time is 64,0196
For 250000 input ...
Array.Sort best time is 157,8832
linq best time is 194,3723
For 1000000 input ...
Array.Sort best time is 692,8211
linq best time is 1058,3259
Press enter to quit.
My machine is an Intel I5, 64 bit windows seven.
Sorry! I did a small stupid bug in the previous edit!
ARRAY.SORT OUTPEFORMS LINQ, yes by a very small amount, but as suspected, this amount grows with n, seems in a not-so-linear way. It seems to me both code overhead and a memory problem (cache miss, object allocation, GC ... don't know).
You can always use SortedList :) Assuming modulus is int:
var complexNumbers = new SortedList<int, Complex>();
complexNumbers.Add(number.Modulus(), number);
public struct Complex: IComparable<Complex>
{
//complex rectangular number: a + bi
public decimal A
public decimal B
//synonymous with absolute value, or in geometric terms, distance
public decimal Modulus() { ... }
//CompareTo() is the default comparison used by most built-in sorts;
//all we have to do here is pass through to Decimal's IComparable implementation
//via the results of the Modulus() methods
public int CompareTo(Complex other){ return this.Modulus().CompareTo(other.Modulus()); }
}
You can now use any sorting method you choose on any collection of Complex instances; Array.Sort(), List.Sort(), Enumerable.OrderBy() (it doesn't use your IComparable, but if Complex were a member of a containing class you could sort the containing class by the Complex members without having to go the extra level down to comparing moduli), etc etc.
You stated you wanted to sort in descending order; you may consider multiplying the results of the Modulus() comparison by -1 before returning it. However, I would caution against this as it may be confusing; you would have to use a method that normally gives you descending order to get the list in ascending order. Instead, most sorting methods allow you to specify either a sorting direction, or a custom comparison which can still make use of the IComparable implementation:
//This will use your Comparison, but reverse the sort order based on its result
myEnumerableOfComplex.OrderByDescending(c=>c);
//This explicitly negates your comparison; you can also use b.CompareTo(a)
//which is equivalent
myListOfComplex.Sort((a,b) => return a.CompareTo(b) * -1);
//DataGridView objects use a SortDirection enumeration to control and report
//sort order
myGridViewOfComplex.Sort(myGridViewOfComplex.Columns["ComplexColumn"], ListSortDirection.Descending);
Related
I am writing some code on geometry processing, delaunay triangulation to be more specific, and I need it to be fast, so I use simple arrays of primitive as data structure to represent my triangulation information, here is a sample of it
private readonly float2[] points;
private readonly int[] pointsHalfEdgeStartCount;
private readonly int[] pointsIncomingHalfEdgeIndexes;
So let's say I want to iterate fast through all the incoming half-edge of the point of index p, I just do this using the precomputed arrays:
int count = pointsHalfEdgeStartCount[p * 2 + 1];
for (int i = 0; i < count; i++)
{
var e = pointsIncomingHalfEdgeIndexes[pointsHalfEdgeStartCount[p * 2] + i]
}
// pointsHalfEdgeStartCount[p * 2] is the start index
And this is fast enought, but does not feel safe or very clear. So I had the idea of wrapping my index into struct to make it clearer while retaining the performance, somthing like that:
public readonly struct Point
{
public readonly int index;
public readonly DelaunayTriangulation delaunay
public Point(int index, DelaunayTriangulation delaunay)
{
this.index = index;
this.delaunay = delaunay;
}
public int GetIncomingHalfEdgeCount() => delaunay.pointsEdgeStartCount[index * 2 + 1];
public HalfEdge GetIncomingHalfEdge(int i)
{
return new HalfEdge(
delaunay,
delaunay.pointsIncomingHalfEdgeIndexes[delaunay.pointsEdgeStartCount[index * 2] + i]
);
}
//... other methods
}
Then I can just do so:
int count = p.GetIncomingHalfEdgeCount();
for (int i = 0; i < count; i++)
{
var e = p.GetIncomingHalfEdge(i);
}
However it was kind of killing my performance, being a lot slower (around 10 times) on a benchmark I did, iterating over all the points and iterating over all their incoming half-edge. I guess because storing a reference to the delaunay triangulaiton in each point struct was an obvious waste and slowed down all the operations involving points, having twice the amount of data to move.
I could make the DelaunayTriangulation a static class but it was not practical for other reasons, so I did that:
public readonly struct Point
{
public readonly int index;
public Point(int index) => this.index = index;
public int GetIncomingHalfEdgeCount(DelaunayTriangulation delaunay) => delaunay.pointsEdgeStartCount[index * 2 + 1];
public HalfEdge GetIncomingHalfEdge(DelaunayTriangulation delaunay, int i)
{
return new HalfEdge(
delaunay.pointsIncomingHalfEdgeIndexes[delaunay.pointsEdgeStartCount[index * 2] + i]
);
}
//... other methods
}
I can just do so:
int count = p.GetIncomingHalfEdgeCount(delaunay);
for (int i = 0; i < count; i++)
{
var e = p.GetIncomingHalfEdge(delaunay, i);
}
It was quite a lot faster, but still 2.5 times slower than the first method using simple int. I wondered if it could be because I was getting int in the first method while I got HalfEdge struct in the other methods (A struct similar to the Point struct, contains only an index as data and a couple of methods), and difference between plain int and the faster struct vanished when I used the e int to instantiate a new HalfEdge struct. Though I am not sure why is that so costly.Weirder still, I explored for clarity sake the option of wrinting the method inside the Delaunay class instead of the Point struct:
// In the DelaunayTriangulation class:
public int GetPointIncomingHalfEdgeCount(Point p) => pointsEdgeStartCount[p.index * 2 + 1];
public HalfEdge GetPointIncomingHalfEdge(Point p, int i)
{
return new HalfEdge(
pointsIncomingHalfEdgeIndexes[pointsEdgeStartCount[p.index * 2] + i]
);
}
And I used it like this:
int count = delaunay.GetPointIncomingHalfEdgeCount(p);
for (int i = 0; i < count; i++)
{
var e = delaunay.GetPointIncomingHalfEdge(p, i);
}
And it was 3 times slower than the previous method! I have no idea why.
I tried to use disassembly to see what machine code was generated but I failed to do so (I am working with Unity3D). Am I condemned to rely on plain int in arrays and sane variable naming and to renounce on trying to have some compile-time type checking (is this int really a point index ?)
I am not even bringing up other questions such as, why it is even slower when I try to use IEnumerable types with yields like so:
public IEnumerable<int> GetPointIncomingHalfEdges(Point p)
{
int start = pointsEdgeStartCount[p.index * 2]; // this should be a slight optimization right ?
int count = pointsEdgeStartCount[p.index * 2 + 1];
for (int i = 0; i < count; i++)
{
yield pointsIncomingHalfEdgeIndexes[start + i];
}
}
I have added a compiler directive for aggressive inlining and it seems to make up for the discrepencies in time! For some reason the compiler fails to inline correctly for:
var e = delaunay.GetPointIncomingHalfEdge(p, i);
While it managed to do so with
var e = p.GetIncomingHalfEdge(delaunay, i);
Why ? I do not know. However It would be far easier if I was able to see how the code is compiled and I could not find how to do that. I will search that, maybe open another question and if I find a better explaination I will come back!
I have a HashSet<int[]> foo where the int[] represents the coordinates of a point in a plane. The value at position 0 represents the x and the value at position 1 represents the y. I want to override the Equals and GetHashCode methods to be able to remove an element (the point represented as an array of size two) if its internal values are equals to a given one.
Already tried:
public override int GetHashCode(){
return this.GetHashCode();
}
public override bool Equals(object obj){
if (obj == null || ! (obj is int[]))
return false;
HashSet<int[]> item = obj as HashSet<int[]>;
return item == this;
}
In my class Maze.
Thanks in advance.
EDIT
I found a way to do that
class SameHash : EqualityComparer<int[]>
{
public override bool Equals(int[] i1, int[] i2)
{
return i1[0] == i2[0] && i1[1] == i2[1];
}
public override int GetHashCode(int[] i)
{
return base.GetHashCode();
}
}
It may seems like you solved what you asked for, but there is something important that should be pointed out. When you implemented the EqualityComparer<int[]> you coded the GetHashCode(int[] i) as return base.GetHashCode(); which is not correct even when it works. I took the time to provide you with the code below for you to see the results of your implementation and I also gave you a possible solution.
Copy this code and run it in a Console Project. Comment your line of code, uncomment the line right below it and run it again. You will see the difference!
Summarizing, when you return base.GetHashCode() you are returning the same hash code for every item. This causes collisions inside the hash set for all insertions ending up in a behavior as slow as if you were using a List<int[]> and you were asking if it contains an element before inserting it. That is why you will see that by using the function I provided you and for the range of numbers I'm generating you will be able to insert up to one million times in less than 1 sec. However, using yours, no matter the range, it spends 1 sec in around ten thousand insertions. This happens because for all n insertions there are collisions and the resulting time complexity is O(n^2) when the expected for a HashSet and an even distributed Hash Function is O(n).
Check this out:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace hashExample
{
class Program
{
static void Main(string[] args)
{
List<int[]> points = new List<int[]>();
Random random = new Random();
int toInsert = 20000;
for (int i = 0; i < toInsert; i++)
{
int x = random.Next(1000);
int y = random.Next(1000);
points.Add(new int[]{ x,y });
}
HashSet<int[]> set = new HashSet<int[]>(new SameHash());
Stopwatch clock = new Stopwatch();
clock.Start();
foreach (var item in points)
{
set.Add(item);
}
clock.Stop();
Console.WriteLine("Elements inserted: " + set.Count + "/" + toInsert);
Console.WriteLine("Time taken: " + clock.ElapsedMilliseconds);
}
public class SameHash : EqualityComparer<int[]>
{
public override bool Equals(int[] p1, int[] p2)
{
return p1[0] == p2[0] && p1[1] == p2[1];
}
public override int GetHashCode(int[] i)
{
return base.GetHashCode();
//return i[0] * 10000 + i[1];
//Notice that this is a very basic implementation of a HashCode function
}
}
}
}
The only way I found it possible was by creating a class MyPair instead of using an array (int[]) like you did. Notice that I used X*10000 + Y in the GetHashCode() function but you can change the constant value in order to get a better HashCode for every item or you can create you own. I just provided this one as a simple example and because is an easy way of having different hashCodes when the bounds for X and Y are relative small (less than the root of Int.MaxValue).
Here you have the working code:
using System;
using System.Collections.Generic;
using System.Linq;
namespace hash
{
public class MyPair
{
public int X { get; set; }
public int Y { get; set; }
public override int GetHashCode()
{
return X * 10000 + Y;
}
public override bool Equals(object obj)
{
MyPair other = obj as MyPair;
return X == other.X && Y == other.Y;
}
}
class Program
{
static void Main(string[] args)
{
HashSet<MyPair> hash = new HashSet<MyPair>();
MyPair one = new MyPair { X = 10, Y = 2 };
MyPair two = new MyPair { X = 1, Y = 24 };
MyPair three = new MyPair { X = 111, Y = 266 };
MyPair copyOfOne = new MyPair { X = 10, Y = 2 };
Console.WriteLine(hash.Add(one));
Console.WriteLine(hash.Add(two));
Console.WriteLine(hash.Add(three));
Console.WriteLine(hash.Add(copyOfOne));
}
}
}
I'm trying to sort a list but it does not sort the list right.
internal class GraphUtils{
internal static List<Edge_t> kruskal2(List<Edge_t> e)
{
e.Sort(new KruskalComparer());
printEdgeArray(e,e.Count);
// Do stuff
}
static void printEdgeArray(List<Edge_t> e, int cnt)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cnt; i++)
{
sb.Append(e[i].weight).Append(",");
}
ConsoleLog.Log(sb.ToString());
}
}
internal class KruskalComparer : IComparer<Edge_t>
{
public int Compare(Edge_t a, Edge_t b)
{
if (a.weight+TerrConstants.Eps > b.weight) return -1;
if (a.weight < b.weight+TerrConstants.Eps) return 1;
return 0;
}
}
class Edge_t
{
internal Vertex_t V1;
internal Vertex_t V2;
internal float weight;
}
When kruskal2 is called, The sorted array is printed on console. But the result is wrong. It's not sorted by weight of Edge_t.
75.01,78.01,76.51,75.51,75.51,75.01,75.01,75.01,74.51,73.01,71.01,71.01,71.01,71.01,71.01,72.51,71.01,71.01,71.01,71.51,71.51,71.01,79.01,63.01,63.01,59.01,47.01,59.51,47.01,59.01,42.01,47.01,42.01,47.01,47.01,47.01,47.01,47.01,40.01,40.51,40.51,39.51,40.01,39.01,39.01,24.51,38.51,38.51,38.01,37.51,24.51,24.51,24.51,24.51,24.51,24.51,24.51,24.51,40.51,39.01,2.01,2.01,
I'm using Unity3d and the platform is mono 2.5.6.
Why is the result not sorted?
EDIT:
TerrConstants.Eps is 1e-6f and it is added to the numbers to make some equality margin. so if the difference is less than TerrConstants.Eps*2 the two weights are considered as equals.
It's probably something wrong with your eps constant.
The following compare function should work.
if (Math.Abs(b.weight - a.weight) <= eps)
return 0;
return b.weight.CompareTo(a.weight);
I have a requirement where:
1. I need to store objects of any type in list
2. Avoid casting calls as much as possible
To that end I tried to come up with something. No matter what I tried I could not get rid of boxing\unboxing. I wanted to know whether any of you have come across something that will achieve it.
The class I have created is mostly useless unless you are dealing with small collections because in terms of memory and performance it takes 1.5 times ArrayList. I am trying to find ways to improve at least one of them as well (preferably performance).
Any feedback is appreciated.
public class Castable
{
Object _o;
public override bool Equals(object obj) { return base.Equals(obj); }
public override int GetHashCode() { return base.GetHashCode(); }
public bool Equals<T>(T obj)
{
T v1 = (T)this._o;
//T v2 = obj;
//var v2 = obj; // Convert.ChangeType(obj, obj.GetType());
// This doesn't work.. (Cannot convert T to Castable
//var v2 = Convert.ChangeType(this.GetType() == obj.GetType() ?
//((Castable)obj)._o.GetType(), obj.GetType());
//if (((T)this._o) != obj) //<== why this doesn't work?
//if (v1 == obj) //<== "Operator '==' cannot be applied to operands of type 'T' and 'T'"
if(v1.Equals(obj))
{
return true;
}
return false;
}
public bool Equals(Castable obj)
{
var v = Convert.ChangeType(obj._o, obj._o.GetType());
return Equals(v);
}
public static bool operator ==(Castable a, Castable b)
{
return a.Equals(b);
}
public static bool operator !=(Castable a, Castable b)
{
return !a.Equals(b);
}
#region HOW CAN WE USE GENRIC TYPE FOR == and != OPERATOR?
public static bool operator ==(Castable a, object b)
{
return a.Equals(b);
}
public static bool operator !=(Castable a, object b)
{
return !a.Equals(b);
}
#endregion
public void Set<T>(T t) { _o = t; }
public T Get<T>() { return (T)_o; }
public static long TestLookup(IList list, int elements, int lookups)
{
object value;
Stopwatch watch = new Stopwatch();
watch.Start();
for (long index = 0; index < lookups; ++index)
{
value = list[random.Next(0, elements - 1)];
}
watch.Stop();
return watch.ElapsedMilliseconds;
}
public static long TestCompare(IList list, int elements, int lookups)
{
//object value;
bool match;
Stopwatch watch = new Stopwatch();
watch.Start();
for (long index = 0; index < lookups; ++index)
{
match = random.Next() == (int)list[random.Next(0, elements - 1)];
}
watch.Stop();
return watch.ElapsedMilliseconds;
}
public static long TestCompareCastable(IList<Castable> list, int elements, int lookups)
{
//object value;
bool match;
Stopwatch watch = new Stopwatch();
watch.Start();
for (long index = 0; index < lookups; ++index)
{
match = list[random.Next(0, elements - 1)] == random.Next(); //most of the times 1.4 times
//match = list[random.Next(0, elements - 1)].Equals(random.Next()); // may be 1.3 times ArrayList
}
watch.Stop();
return watch.ElapsedMilliseconds;
}
public static void Test(int elements, int lookups, int times)
{
List<int> intList = new List<int>();
List<Castable> castableList = new List<Castable>();
ArrayList intArrayList = new ArrayList();
if (Stopwatch.IsHighResolution)
Console.WriteLine("We have a high resolution timer available");
long frequency = Stopwatch.Frequency;
Console.WriteLine(" Timer frequency in ticks per second = {0}", frequency);
for (int index = 0; index < elements; ++index)
{
intList.Add(random.Next());
intArrayList.Add(random.Next());
Castable c = new Castable();
c.Set(random.Next());
castableList.Add(c);
}
long ms = 0;
string result = "";
string ratios = "";
for (int time = 0; time < times; ++time)
{
ms = TestLookup(intList, elements, lookups);
result += "intList Lookup Time " + ms.ToString() + " MS\n";
ms = TestLookup(castableList, elements, lookups);
result += "intArrayList Lookup Time " + ms.ToString() + " MS\n";
ms = TestLookup(intArrayList, elements, lookups);
result += "castableList Lookup Time " + ms.ToString() + " MS\n";
ms = TestCompare(intList, elements, lookups);
result += "intList Compare Time " + ms.ToString() + " MS\n";
long msarraylist = ms = TestCompare(intArrayList, elements, lookups);
result += "intArrayList Compare Time " + ms.ToString() + " MS\n";
ms = TestCompareCastable(castableList, elements, lookups);
result += "castableList Compare Time " + ms.ToString() + " MS\n";
ratios += String.Format("round: {0}, ratio: {1}\n", time, (float)ms / msarraylist);
}
//MessageBox.Show(result);
MessageBox.Show(ratios);
int i = 10;
Castable o1 = new Castable();
o1.Set(i);
int j = 10;
Castable o2 = new Castable();
o2.Set(j);
if (!o1.Equals(10))
{
Console.WriteLine("unequal");
}
if (!o1.Equals(o2))
{
Console.WriteLine("unequal");
}
if (o1 != j)
{
Console.WriteLine("unequal");
}
int x = o1.Get<int>();
}
}
EDIT
In short I am trying to achieve:
#winSharp93: yes, in short:
List GenericGenericCollection = new List ();
GenericGenericCollection.Add(new string("a sonnet");
GenericGenericCollection.Add(42);
GenericGenericCollection.Add(new MyOwnCustomType);
EDIT AGAIN
There are two ways I found:
1. In .NET 4, a new 'dynamic' keyword is introduced. If you replace the line Object _o; with dynamic _o; you can use the code as it is. The problem is although dynamic supposed to be dynamic type, performance is just like boxing..
The performance can be improved by adding implicit (I prefer) or explicit casting operator instead of relying on generic == operator.
Based on http://igoro.com/archive/fun-with-c-generics-down-casting-to-a-generic-type/ I added following class. This takes care of boxing and performance - with following class performance is little better than ArrayList of int or Castable. Of course it has long way to go when List<int> compared.
The only problem, from my point of view is, once object is assigned to plain Any object to get concrete type embedded inside AnyInternal<T>. Neither I could find a way to have method T Get(). Even keyword dynamic fails at runtime at statment:
Any.AnyInternal<dynamic> any = (Any.AnyInternal<dynamic>)anyInstanceContainingAnyInternalForInt;
//too bad I can't seal Any after AnyInternal<T> has derived from it.
public abstract class Any
{
public static implicit operator int(Any any)
{
return Any.ToType<int>(any).Data;
}
public static AnyInternal<T> ToType<T>(Any any)
{
return ((AnyInternal<T>)any);
}
public class AnyInternal<T> : Any
{
private T _data;
public T Data { get { return _data; } }
public AnyInternal(T data)
{
_data = data;
}
}
}
Use the generic List<T> (inside System.Collections.Generic) instead of ArrayList.
There won't happen any boxing / unboxing for value types.
I have a method called "GetValue()" which is supposed to return the value "A", "B", "C" or "D" on each method call.
I want this method to return the value "A" in 30% of the method calls and the value "B" in 14% of the method calls, the value "C" 31%.. and so on...
Wich is the best way to distribute theese values smoothly, I do not want the method to return the value "A" xxx times in a row becouse the value "A" are farest from it's requested outcome percentage.
Please, all answeres are appreciated.
You can use the Random class to achieve this:
private static Random Generator = new Random();
public string GetValue()
{
var next = Generator.Next(100);
if (next < 30) return "A";
if (next < 44) return "B";
if (next < 75) return "C";
return "D";
}
Update
For a more generic random weighted value store, the following may be a good starting point:
public class WeightedValueStore<T> : IDisposable
{
private static readonly Random Generator = new Random();
private readonly List<Tuple<int, T>> _values = new List<Tuple<int, T>>();
private readonly ReaderWriterLockSlim _valueLock = new ReaderWriterLockSlim();
public void AddValue(int weight, T value)
{
_valueLock.EnterWriteLock();
try
{
_values.Add(Tuple.Create(weight, value));
}
finally
{
_valueLock.ExitWriteLock();
}
}
public T GetValue()
{
_valueLock.EnterReadLock();
try
{
var totalWeight = _values.Sum(t => t.Item1);
var next = Random.Next(totalWeight);
foreach (var tuple in _values)
{
next -= tuple.Item1;
if (next < 0) return tuple.Item2;
}
return default(T); // Or throw exception here - only reachable if _values has no elements.
}
finally
{
_valueLock.ExitReadLock();
}
}
public void Dispose()
{
_valueLock.Dispose();
}
}
Which would then be useable like so:
public string GetValue()
{
using (var valueStore = new WeightedValueStore<string>())
{
valueStore.AddValue(30, "A");
valueStore.AddValue(14, "B");
valueStore.AddValue(31, "C");
valueStore.AddValue(25, "D");
return valueStore.GetValue();
}
}
Use Random.
Take care of the seed. See this link.
Example:
// You can provide a seed as a parameter of the Random() class.
private static Random RandomGenerator = new Random();
private static string Generate()
{
int value = RandomGenerator.Next(100);
if (value < 30)
{
return "A";
}
else if (value < 44)
{
return "B";
}
else
{
return "C";
}
}
If you want that distribution by average, you can just pick a random number and check it.
Random rnd = new Random();
int value = rnd.Next(100); // get a number in the range 0 - 99
if (value < 30) return "A";
if (value < 30+14) return "B";
if (value < 30+14+31) return "C";
return "D";
Note that you should create the random generator once, and reuse it for subsequent calls. If you create a new one each time, they will be initialised with the same random sequence if two method calls come too close in time.
If you want exactly that distribution for 100 items, then you would create an array with 100 items, where 30 are "A", 14 are "B", and so on. Shuffle the array (look up Fisher-Yates), and return one item from the array for each method call.
Let's say you have the arrays
String[] possibleOutcomes = new String[] { "A", "B", "C", "D" }
and
int[] possibleOutcomeProbabilities = new int[] { 30, 14, 31, 25 }
You can use the following strategy whenever you are required to output one of the outcomes:
Find the sum of all elements in possibleOutcomeProbabilities. Lets call this sum totalProbability.
Generate a random number between 1 and totalProbability. Lets call this randomly generated number outcomeBucket.
Iterate over possibleOutcomeProbabilities to determine which outcome outcomeBucket corresponds to. You then pick the corresponding outcome from possibleOutcomes.
This strategy will certainly not give you first 30% outcomes as A, next 14% as B, etc. However, as probability works, over a sufficiently large number of outcomes, this strategy will ensure that your possible outcomes are distributed as per their expected probabilities. This strategy gives you the advantage that outcome probabilities are not required to add up to 100%. You can even specify relative probabilities, such as, 1:2:3:4, etc.
If you are really worried about the fastest possible implementation for the strategy, you can tweak it as follows:
a. Calculate totalProbability only once, or when the probablities are changed.
b. Before calculating totalProbability, see if the elements in possibleOutcomeProbabilities have any common divisors and eliminate those. This will give you a smaller probability space to traverse each time.
try this:
Random r = new Random();
private string GetValue()
{
double d = r.Next();
if(d < 0.3)
return "A";
else if(d < 0.5)
return "B";
...etc.
}
EDIT: just make sure that the Random variable is created outside the function or you'll get the same value each time.
I would not recommend any hard-coded approach (it is hard to maintain and it's bad practice). I'd prefer a more generic solution instead.
enum PossibleOutcome { A, B, C, D, Undefined }
// sample data: possible outcome vs its probability
static readonly Dictionary<PossibleOutcome, double> probabilities = new Dictionary<PossibleOutcome, double>()
{
{PossibleOutcome.A, 0.31},
{PossibleOutcome.B, 0.14},
{PossibleOutcome.C, 0.30},
{PossibleOutcome.D, 0.25}
};
static Random random = new Random();
static PossibleOutcome GetValue()
{
var result = random.NextDouble();
var sum = 0.0;
foreach (var probability in probabilities)
{
sum += probability.Value;
if (result <= sum)
{
return probability.Key;
}
}
return PossibleOutcome.Undefined; // it shouldn't happen
}
static void Main(string[] args)
{
if (probabilities.Sum(pair => pair.Value) != 1.0)
{
throw new ApplicationException("Probabilities must add up to 100%!");
}
for (var i = 0; i < 100; i++)
{
Console.WriteLine(GetValue().ToString());
}
Console.ReadLine();
}