Fastest way to sort an Array c# - c#

Hi this is my problem I have an array of points P(x,y) and I need to sort these points from the furthest to the closest, respect to the barycenter of a Polygon, this what I have done (I know this is a bad solution ) how can I do a better and aboveall faster solution?
List<C2DPoint> OrderedGripperPoints = new List<C2DPoint> { };
while(myGripperPoints.Count!=0)
{
double dist=-1;
int index=-1;
for(int k=0;k<myGripperPoints.Count;k++)
{
if(myGripperPoints[k].Distance(WorkScrap.GetCentroid())>=dist)
{
index = k;
dist = myGripperPoints[k].Distance(WorkScrap.GetCentroid());
}
}
OrderedGripperPoints.Add(myGripperPoints[index]);
myGripperPoints.RemoveAt(index);
}
Thanks for your answers...

Use Linq to order points.
using System.Linq;
var sortedList = myGripperPoints.OrderBy(p => p.Distance(WorkScrap.GetCentroid())).ToList();

Consider the following code:
Point Class (assumed class definition)
class Point
{
public int X { get; set;}
public int Y { get; set;}
}
Point EqualityComparer
class PointEqualityComparer : IEqualityComparer<Point>
{
public bool Equals(Point p1, Point p2) { return p1.X == p2.X && p1.Y == p2.Y; }
public int GetHashCode(Point p) { return p.X.GetHashCode() *31 + p.Y.GetHashCode()*23; }
}
Create a Dictionary with Point as Key and Distance as value (assuming integer):
Dictionary<Point,int> pointDictionary =
new Dictionary<Point, int>(new PointEqualityComparer());
Add Points as follows:
Point p = new Point {X = <value>, Y = <value>};
pointDictionary.Add(p,p.Distance(WorkScrap.GetCentroid()));
Order by Distance as follows:
pointDictionary.OrderByDescending(x => x.Value).ToList();
Ordering is done by Distance in Descending order as expected
Result would be List<KeyValuePair<Point,int>>, where elements are in Descending order

Related

Find middle point of most populated area

I hope you have a nice day, so here is my problem: I'm trying to find the middle point of most populated positions (X/Y) on a map but i'm stuck and i can't find a good and effective way to do it.
To find this position i've access to an collection of entities (and these entities have a Position property (which is a Vector2D) and map size
public readonly struct Vector2D
{
private static readonly double Sqrt = Math.Sqrt(2);
private static readonly Random Random = new Random();
public static Vector2D Zero { get; } = new Vector2D();
public int X { get; }
public int Y { get; }
public Vector2D(int x, int y)
{
X = x;
Y = y;
}
public Vector2D GetDistanceTo(Vector2D vector2D) => new Vector2D(Math.Abs(vector2D.X - X), Math.Abs(vector2D.Y - Y));
public int GetDistance(Vector2D destination)
{
int x = Math.Abs(X - destination.X);
int y = Math.Abs(Y - destination.Y);
int min = Math.Min(x, y);
int max = Math.Max(x, y);
return (int)(min * Sqrt + max - min);
}
public bool IsInRange(Vector2D position, int range)
{
int dx = Math.Abs(X - position.X);
int dy = Math.Abs(Y - position.Y);
return dx <= range && dy <= range && dx + dy <= range + range / 2;
}
public override string ToString() => $"{X}/{Y}";
}
That's the only thing i've tried
public Vector2D FindMostPopulatedPosition()
{
IEnumerable<Vector2D> positions = Entities.Select(x => x.Position);
return new Vector2D((int)positions.Average(x => x.X), (int)positions.Average(x => x.Y));
}
Here is some example images
Red dot: All entities
Blue dot: The position i'm looking for
Thanks for reading (and for your help)

How to quicksort pairs of numbers(int and double)

I created the pair class and array class, but I'm lost on how to implement the quicksort algorithm.
I want to do it if ints are same then I should sort by double. I was able to implement quicksort with one value per index of array, but with this I just can't find any resources.
Maybe you guys have some resources or maybe you had the same problem?
By the way I'm trying to implement it with c#.
This is my pair class:
class Pair
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
And my data array class
class MyDataArray : DataArray
{
Pair[] data;
int operations = 0;
public MyDataArray(int n, int seed)
{
data = new Pair[n];
Random rand = new Random(seed);
for (int i = 0; i < n; i++)
{
data[i] = new Pair(rand.Next(1,100), rand.NextDouble());
}
}
public override int integer(int index)
{
return data[index].integer;
}
public override double doubl(int index)
{
return data[index].doubl;
}
public override void Swap(int i, int j)
{
Pair temp = data[i]; // c3 1
data[i] = data[j]; // c3 1
data[j] = temp; // c3 1
}
Your Pair class could implement IComparable<T>, and your quick sort algorithm could be implemented using the CompareTo method.
The IComparable<T> interface:
Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering or sorting its instances.
You can see the documentation on the CompareTo method to see what the return values mean.
public class Pair : IComparable<Pair>
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int CompareTo(Pair other)
{
if (other == null)
{
return 1;
}
int result = integer.CompareTo(other.integer);
if (result == 0)
{
result = doubl.CompareTo(other.doubl);
}
return result;
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
If you prefer to use the comparison operators, you can implement them in terms of the CompareTo method. The documentation I liked has examples on how to do that.
//sort for integer
var SortedIntegerList = data.OrderBy(x=>x.integer);
//sort for double
var SortedDoubleList = data.OrderBy(x=>x.doubl);
OrderBy for objects uses Quicksort - What Sorting Algorithm Is Used By LINQ "OrderBy"? - so you can use that.
To avoid creating IComparer<Pair> interface you can construct it using Comparer<T>.Create from just comparison delegate:
var sorted = source.OrderBy(x => x, Comparer<Pair>.Create(
(p1, p2) => p1.Integer() - p2.Integer() != 0 ?
p1.Integer() - p2.Integer() :
Math.Sign(p1.Doubl() - p2.Doubl()))).ToList();

Is it possible to initalize a nested property when setting the parent?

I'd like to know if the following is possible and if it would have any performance benefits.
Given this structure;
public class X
{
[JsonIgnore]
public List<Y> Y { get; set; }
}
public class Y
{
[JsonIgnore]
public List<Z> Z { get; set; }
}
public class Z
{
...
}
short version
Can I initialize X.Y.Z in one line?
Working (foreach) version;
X x = null;
var dbitem = db.SingleOrDefault(...);
if (dbitem != null)
{
x = new X
{
Y = dbX.dbY.Select(a =>
JsonConvert.DeserializeObject<Y>(a.json)).ToList()
};
x.Y.ForEach(a =>
a.Z = dbX.dbY.Single(b => b.id == a.id)
.dbZ.Select(q => JsonConvert.DeserializeObject<Z>(q.json)).ToList());
}
Experimental
Create Y and Z in one go, no need to query .Single(b => b.id == a.id)
x = new X
{
Y = dbX.dbY.Select(a =>
JsonConvert.DeserializeObject<Y>(a.json).Z.AddRange(
a.dbZ.Select(b =>
JsonConvert.DeserializeObject<Z>(b.json)).ToList()))
};
Get dbY items that are associated with the dbX item (FK)
Deserialize all dbY items to object Y
Object Y has List property which I want to initalize at the level of Y. I want to do this because at that point I have a reference to all Z objects (by FK).
Step 3 is where I don't know what to do. How to intialize those Z objects from that reference?
If the question is unclear or title doesn't reflect question please let me know.

overloading operator c# Vector

So, I am trying to override the "-" operator in c# to be able to subtract 2 vectors, but my class cannot implement Vector.
namespace Vectors
{
class VectorUtilv
{
private Point _p;
private Point _p2;
private Vector _v;
public Vector V
{
get { return _v; }
set { _v = value; }
}
public Point AddVector(Vector v)
{
_p.X = (_p.X + v.X);
_p2.Y = (_p.Y + v.Y);
return _p2;
}
// This is where I am trying to override but I cant add the v.X or
// the v.Y because it is not a vector. If i cast it as a vector the
// override doesn't work.
//////////////////////////////////////////////////////////////////
public static VectorUtilv operator -(Vector a, Vector b)
{
Vector v = new Vector();
v.X = a.X - b.X;
v.Y = a.Y - b.Y;
return v;
}
}
}
Any idea how I can remedy this issue?
Because you are Trying to define Operator for Class. At least one of its Parameters should be used in Operator with Type of your Class. for example you cant have class Car and define Operator witch only Gets int.
You can't override the operator for existing classes.only your own classes.
If you cant Modify Vector Class then you should declare your own class named Vector. or use the Type of your class for operator.
so you can have
class VectorUtilv
{
private Point _p;
private Point _p2;
private Vector _v;
public static VectorUtilv operator -(VectorUtilv a, VectorUtilv b)
{
//...
}
}
or
class Vecotr
{
private Point _p;
private Point _p2;
private Vector _v;
public static Vecotr operator -(Vecotr a, Vecotr b)
{
//...
}
}
But if you use solution 2. then you need to use qualifiers when using Vector.
System.Windows.Vector // is in Windows assembly
Vector // is your class
You can only override an operator in its own class.
Move all of that code to the Vector class.
In your vector class, override the '-' operator in it
public class Vector
{
public int X { get; set; }
public int Y { get; set; }
public static Vector operator -(Vector a, Vector b)
{
Vector v = new Vector();
v.X = a.X - b.X;
v.Y = a.Y - b.Y;
return v;
}
}
Then, you can uses it like that
Vector v1 = new Vector { X = 5, Y = 9};
Vector v2 = new Vector { X = 3, Y = 4 };
Vector vr = v1 - v2;
Console.WriteLine("Resultant Vector X: {0} & Y:{1}", vr.X, vr.Y);
I hope it will help you.
Thanks for the great responses. I wish I would I have checked before I figured it out. Would have saved me lots of time. I ended up doing pretty much exactly as you all said. Here is what I have.
public static VectorUtil operator -(VectorUtil aHeroPoint, VectorUtil bEnemyPoint) {
VectorUtil v = new VectorUtil();
v.Vec = new Vector(( aHeroPoint._p.X - bEnemyPoint._p.X),( aHeroPoint._p.Y - bEnemyPoint._p.Y));
return v;
}

C# Abstract Class Operator Overload

I have an abstract class, Vector, which I would like to overload the operators +,-,*, etc.
I want any derived classes to be able to use these, and get an object back with the same type as the calling object.
I tried with generics, (as follows, in brief), but I couldn't find a legal way to do it:
public static T operator +<T>( T V1, T V2) where T : Vector
{
//some calculation
return new T(args);
}
I then tried to do it just using the base class:
public static Vector operator+(Vector V1, Vector V2)
{
if (V1.Dimension != V2.Dimension)
throw new VectorTypeException("Vector Dimensions Must Be Equal");
double[] ArgList = new double[V1.Dimension];
for (int i = 0; i < V1.Dimension; i++) { ArgList[i] = V1[i] + V2[i]; }
return (Vector)Activator.CreateInstance(V1.GetType(), new object[] { ArgList});
}
If this method is passed in two child objects, it should perform the operation on them, and return a new object of the same heritage.
The problem I ran into with this is that I cannot enforce that all such child classes must have a constructor with the appropriate signature, and I can't call the base constructor to make the object.
What are ways to either (a) Make either of these work, or (b) do this elegantly in another way?
You could declare instance-level abstract methods which your subclass can override:
public abstract class Vector
{
protected abstract Vector Add(Vector otherVector);
public static Vector operator +(Vector v1, Vector v2)
{
return v1.Add(v2);
}
}
public class SubVector : Vector
{
protected override Vector Add(Vector otherVector)
{
//do some SubVector addition
}
}
Might run into some issues especially with multiple subclasses (Will SubVector have to know how to add with SomeOtherSubVectorClass? What if you add ThirdVectorType class?) and perhaps handling null cases. Also, making sure that SubVector.Add behaves the same as SomeOtherSubVectorClass.Add when it comes to commutative operations.
EDIT: based on your other comments, you could so something like:
public class Vector2D : Vector
{
public double X { get; set; }
public double Y { get; set; }
protected override Vector Add(Vector otherVector)
{
Vector2D otherVector2D = otherVector as Vector2D;
if (otherVector2D != null)
return new Vector2D() { X = this.X + otherVector2D.X, Y = this.Y + otherVector2D.Y };
Vector3D otherVector3D = otherVector as Vector3D;
if (otherVector3D != null)
return new Vector3D() { X = this.X + otherVector3D.X, Y = this.Y + otherVector3D.Y, Z = otherVector3D.Z };
//handle other cases
}
}
public class Vector3D : Vector
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
protected override Vector Add(Vector otherVector)
{
Vector2D otherVector2D = otherVector as Vector2D;
if (otherVector2D != null)
return new Vector3D() { X = this.X + otherVector2D.X, Y = this.Y + otherVector2D.Y, Z = this.Z };
Vector3D otherVector3D = otherVector as Vector3D;
if (otherVector3D != null)
return new Vector3D() { X = this.X + otherVector3D.X, Y = this.Y + otherVector3D.Y, Z = this.Z + otherVector3D.Z };
//handle other cases
}
}
EDITx2:
Given your latest comment, perhaps your should just maintain an internal array/matrix and just do generic matrix math. Your subclasses can expose X/Y/Z property wrappers against the array indicies:
public class Vector
{
protected double[] Values;
public int Length { get { return Values.Length; } }
public static Vector operator +(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
//perform generic matrix addition/operation
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
//or use some factory/service to give you a Vector2D, Vector3D, or VectorND
return new Vector() { Values = newValues };
}
}
}
public class Vector2D : Vector
{
public double X
{
get { return Values[0]; }
set { Values[0] = value; }
}
public double Y
{
get { return Values[1]; }
set { Values[1] = value; }
}
}
public class Vector3D : Vector
{
public double X
{
get { return Values[0]; }
set { Values[0] = value; }
}
public double Y
{
get { return Values[1]; }
set { Values[1] = value; }
}
public double Z
{
get { return Values[2]; }
set { Values[2] = value; }
}
}
EDITx3: Based on your latest comment, I guess you could implement operator overloads on each subclass, do the shared logic in a static method (say in the base Vector class), and somewhere do a switch/case check to provide a specific subclass:
private static Vector Add(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
//perform generic matrix addition/operation
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
//or use some factory/service to give you a Vector2D, Vector3D, or VectorND
switch (newValues.Length)
{
case 1 :
return new Vector1D() { Values = newValues };
case 2 :
return new Vector2D() { Values = newValues };
case 3 :
return new Vector3D() { Values = newValues };
case 4 :
return new Vector4D() { Values = newValues };
//... and so on
default :
throw new DimensionOutOfRangeException("Do not support vectors greater than 10 dimensions");
//or you could just return the generic Vector which doesn't expose X,Y,Z values?
}
}
}
Then your subclasses would have:
public class Vector2D
{
public static Vector2D operator +(Vector2D v1, Vector2D v2)
{
return (Vector2D)Add(v1, v2);
}
}
public class Vector3D
{
public static Vector3D operator +(Vector3D v1, Vector3D v2)
{
return (Vector3D)Add(v1, v2);
}
}
Some duplication, but I don't see a way around it off the top of my head to allow the compiler to do this:
Vector3 v1 = new Vector3(2, 2, 2);
Vector3 v2 = new Vector3(1, 1, 1);
var v3 = v1 + v2; //Vector3(3, 3, 3);
Console.WriteLine(v3.X + ", " + v3.Y + ", " + v3.Z);
or for other dimensions:
Vector2 v1 = new Vector2(2, 2);
Vector2 v2 = new Vector2(1, 1);
var v3 = v1 + v2; //Vector2(3, 3, 3);
Console.WriteLine(v3.X + ", " + v3.Y); // no "Z" property to output!
What about having an abstract method called Add() that operator+ just acts as a wrapper for? ie, "return v1.Add(v2)". This would also enable you to define interfaces which non-Vector classes can constrain their code to, enabling to perform math-like operations (since generic code can't see/touch operators like +, -, etc for any type).
The only constructor you can code with in a generic method is the default (ie, parameter-less) constructor, which you have to specify in the generic constraints for the method/type.
Five years later I had the exact same problem, only I was calling them Ntuples, not vectors. Here is what I did:
using System;
using System.Collections.Generic;
public class Ntuple{
/*parent class
has an array of coordinates
coordinate-wise addition method
greater or less than in dictionary order
*/
public List<double> Coords = new List<double>();
public int Dimension;
public Ntuple(List<double> Input){
Coords=Input;
Dimension=Input.Count;
}//instance constructor
public Ntuple(){
}//empty constructor, because something with the + overload?
public static Ntuple operator +(Ntuple t1, Ntuple t2)
{
//if dimensions don't match, throw error
List<double> temp = new List<double>();
for (int i=0; i<t1.Dimension; i++){
temp.Add(t1.Coords[i]+t2.Coords[i]);
}
Ntuple sum = new Ntuple(temp);
return sum;
}//operator overload +
public static bool operator >(Ntuple one, Ntuple other){
//dictionary order
for (int i=0; i<one.Dimension; i++){
if (one.Coords[i]>other.Coords[i]) {return true;}
}
return false;
}
public static bool operator <(Ntuple one, Ntuple other){
//dictionary order
for (int i=0; i<one.Dimension; i++){
if (one.Coords[i]<other.Coords[i]) {return true;}
}
return false;
}
}//ntuple parent class
public class OrderedPair: Ntuple{
/*
has additional method PolarCoords, &c
*/
public OrderedPair(List<double> Coords) : base(Coords){}
//instance constructor
public OrderedPair(Ntuple toCopy){
this.Coords=toCopy.Coords;
this.Dimension=toCopy.Dimension;
}
}//orderedpair
public class TestProgram{
public static void Main(){
List<double> oneCoords=new List<double>(){1,2};
List<double> otherCoords= new List<double>(){2,3};
OrderedPair one = new OrderedPair(oneCoords);
OrderedPair another = new OrderedPair(otherCoords);
OrderedPair sum1 = new OrderedPair(one + another);
Console.WriteLine(one.Coords[0].ToString()+one.Coords[1].ToString());
Console.WriteLine(sum1.Coords[0].ToString()+sum1.Coords[1].ToString());
bool test = one > another;
Console.WriteLine(test);
bool test2 = one < another;
Console.WriteLine(test2);
}
}
}//namespace ntuples

Categories