Can counting sort sort decimal values? - sorting

Can Counting Sort sort decimal values? I'm just started learning java recently and I'm unsure. Does anyone know if it can or not?

Counting Sort only works because you know exactly how many elements there are in the array, and because each index in an array represents an integer of the same value. The array [1, 2, 0, 2, 1] can be represented as [1, 2, 2] in the middle stage of the sort. There is one 0, two 1s, and two 2s.
This is not possible in the same way with decimals. If you could ensure a certain level of precision I suppose you could add a slot for each potential value. For example, if all the decimals were rounded to the nearest tenth you would need at 10 slots for each whole number plus 1 slot for 0: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0
// the original array
[0.1, 1.1, 0.7, 1.4, 0.5, 0.7]
// after the counting step
// 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
[ 0 1 0 0 0 1 0 2 0 0
// 1.1 1.2 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9
1 0 0 0 1 0 0 0 0 0 ]
// when expanded to the sorted array
[0.1, 0.5, 0.7, 0.7, 1.1, 1.4]
So for a sort with a max value of N, the size of the counting array (K) would be N * 10. So k = 10N. This is obviously not true counting sort, since the counting step would be more complex since each value cannot be so easily mapped to an index.
So while theoretically possible and would have the same time complexity, it would not be a "true" counting sort while also taking up FAR more memory space to be practical, especially when sorting large number ranges with high precision, and being less flexible than other sorting algorithms. You would be better off using most any other sorting algorithm.

Related

Clustering points to reach global minimum

For a number of points, for example, 100 points, each two has a 'connection' (a number), the goal of the algorithm is to split those points into a given number of clusters (like 5 clusters), minimized the total connections insides clusters.
input:
A matrix with shape n * n, the matrix[i][j] describe the connection between point i and j (the matrix should be symmetry matrix). The cluster number m.
output:
m clusters for n points. And the total connections inside clusters are minimized.
T= ∑(C⊆m)∑(i,j⊆C)M_ij
(Goal is to minimize T above)
For example: 5 points with the matrix
1 2 3 4 5
1 0.1 0.1 0.3 0.5 0.7
2 0.1 0.1 0.7 0.9 1.1
3 0.3 0.7 0.5 0.1 0.2
4 0.5 0.9 0.1 0.3 0.5
5 0.7 1.1 0.2 0.5 0.1
To split into 2 clusters, the splitting
Cluster 1: {1,2}
Cluster 2: {3,4,5}
has the total internal connection of T = C1 + C2 = M12 + M34 + M35 + M45 = 0.1 + 0.1 + 0.2 + 0.5 = 0.9
The splitting
Cluster 1: {1,3,4}
Cluster 2: {2,5}
Has the total internal connection T = C1 + C2 = M13 + M14 + M34 + M25 = 0.3 + 0.5 + 0.1 + 1.1 = 2.0
The goal is to find the lowest internal connection
This is easy when n and m is small, just loop all possible case to find the global minimum. but when n and m become bigger, iteration is not possible.
I have tried Kernighan–Lin algorithm to solve this problem. Initialize with random splitting, then defined two behavior, inserting the point into another cluster, and swap two points in two clusters, each time to find the behavior that can lower the total connections insides clusters mostly. Applied this behavior, then re-calculate again, until no more insertion/swapping can lower the total connections. (Greedy algorithm Strategy).
However it can only reach local minimum, with different initialization, the results also are different. Is there a standard way to solve this problem to reach the global minimum?
The problem is supposedly NP hard, so either you use a local optimum,or you have to try all O(k^n) possibilities.
You can use a local optimum to bound your search, but there is no guarantee that this helps much.

How to create a uniformly random matrix in Julia?

l want to get a matrix with uniformly random values sampled from [-1,2]
x= rand([-1,2],(3,3))
3x3 Array{Int64,2}:
-1 -1 -1
2 -1 -1
-1 -1 -1
but it takes into consideration just -1 and 2, and I'm looking for continuous values for instance -0.9 , 0.75, -0.09, 1.80.
How can I do that?
Note: I am assuming here that you're looking for uniform random variables.
You can also use the Distributions package:
## Pkg.add("Distributions") # If you don't already have it installed.
using Distributions
rand(Uniform(-1,2), 3,3)
I do quite like isebarn's solution though, as it gets you thinking about the actual properties of the underlying probability distributions.
for random number in range [a,b]
rand() * (b-a) + a
and it works for a matrix aswell
rand(3,3) * (2 - (-1)) - 1
3x3 Array{Float64,2}:
1.85611 0.456955 -0.0219579
1.91196 -0.0352324 0.0296134
1.63924 -0.567682 0.45602
You need to use a FloatRange{Float64} with the dessired step:
julia> rand(-1.0:0.01:2.0, 3, 3)
3x3 Array{Float64,2}:
0.79 1.73 0.95
0.73 1.4 -0.46
1.42 1.68 -0.55

in matlab generate n random numbers between 0 and 1 that sum of them is less equal than one

I want to generate n random numbers between 0 and 1 that sum of them is less equal than one.
Sum(n random number between 0 and 1) <= 1
n?
For example: 3 random number between 0 and 1:
0.2 , 0.3 , 0.4
0.2 + 0.3 + 0.4 = 0.9 <=1
It sounds like you would need to generate the numbers separately while keeping track of the previous numbers. We'll use your example:
Generate the first number between 0 and 1 = 0.2
1.0 - 0.2 = 0.8: Generate the next number between 0 and 0.8 = 0.3
0.8 - 0.3 = 0.5: Generate the next number between 0 and 0.5 = 0.4

Shrink range of numbers

Lets say I have a random number, that goes from 0.0 to 1.0, and I want to reduce its "range", to, lets say 0.25 to 0.75 respecting its harmony.
What would be the pseudo code for this?
Examples:
0.0 in the [0.0, 1.0] range would be 0.25 in the [0.25, 0.75] range
0.5 would still be 0.5
Thanks.
You have a random number r.
First you shrink the range: r = r * (0.75-0.25).
Now it's in the range [0, 0.5]. Then you shift the range: r = r + 0.25.
Now it's in the range [0.25, 0.75].

Scale a list of numbers from -1.0 to 1.0

This should be an easy one.
I have a list of numbers. How do I scale list's values, between -1.0 and 1.0 in order for min = -1 and max = 1.0?
Find the min and the max
then for each number scale x to 2 * (x - min)/( max - min) - 1
Just to check --
min scales to -1
and max scales to 1
If it is a long list precomputing c = 2/(max - min) and scaling with c * x - 1 is a good idea.
This is a signed normalization
1 - get the Minimum and Maximum value on the list (MinVal,MaxVal)
2 - convert each number using this expressions
signedNormal = (((originalNumber - Minimum) / (Maximum - Minimum)) * 2.0) - 1.0
I deliberately made this inefficient in order to be clear - more efficient would be
double min = myList.GetMinimum();
double max = myList.GetMaximum();
double signedRangeInverse = 1.0 / (max - min);
for(int i = 0;i < myList.NumberOfItems();i++)
myList[i] = (((myList[i] - min) * signedRangeInverse) * 2.0) - 1
No point in recalculating range each time
No point in dividing range, mult is faster
If you want 0 to still equal 0 in the final result:
Find the number with the largest magnitude. This will either map to 1 or -1.
Work out what you need to multiply it by to make it 1 or -1.
Multiply all the numbers in the collection by that factor.
E.g
[ -5, -3, -1, 0, 2, 4]
Number with largest magnitude is -5. We can get that to equal -1 by multiplying by 0.2 (-1 / -5). (Beware of divide by 0s if your numbers are all 0s.)
So multiply all the elements by 0.2. This would give:
[-1, -0.6, -0.2, 0, 0.4, 0.8]
Although note that
[ -5, -5, -5 ] -> [ -1, -1, -1 ]
and
[ 5, 5, 5 ] -> [ 1, 1, 1 ]
and
[ 0, 0, 0 ] -> [ 0, 0, 0 ]
That may or may not be what you want. Thanks to #Hammerite for prompting me on that one with his very helpful comment :)

Resources