Swift slower than Flutter for select sort algorithm - swift

I implemented select sort in Flutter and in SwiftUI. I made the implementations as similar as possible.
Swift:
func selectSort(list: inout [Double]) -> [Double] {
for i in 0..<list.count {
var minElPos = i;
for j in (minElPos + 1)..<list.count {
if list[j] < list[minElPos] {
minElPos = j;
}
}
// swap
let temp = list[i];
list[i] = list[minElPos];
list[minElPos] = temp;
}
return list;
}
// Measuring time
func generateRandomList(size: Int) -> [Double] {
var res = Array<Double>(repeating: 0.0, count: size)
for i in 0..<size {
res[i] = Double.random(in: 0...1)
}
return res;
}
var arrayToTest: [Double] = generateRandomList(size: 8000);
let startingPoint = Date()
selectSort(list: &arrayToTest);
let time = startingPoint.timeIntervalSinceNow * -1;
Flutter:
class SelectSort {
static List<double> call(List<double> list) {
for(int i = 0; i < list.length - 1; i++) {
int minElPos = i;
for(int j = minElPos + 1; j < list.length; j++) {
if(list[j] < list[minElPos]) {
minElPos = j;
}
}
// swap
double temp = list[i];
list[i] = list[minElPos];
list[minElPos] = temp;
}
return list;
}
}
// Measuring time
class Utils {
static List<double> generateRandomList(int nbOfElements) {
var random = new Random();
List<double> res = List(nbOfElements);
for (var i = 0; i < nbOfElements; i++) {
res[i] = random.nextDouble();
}
return res;
}
}
List<double> arrayToTest = Utils.generateRandomList(8000);
final stopwatch = Stopwatch()..start();
SelectSort.call(arrayToTest);
stopwatch.stop();
int time = stopwatch.elapsedMilliseconds;
I measured the execution time for an array of random numbers. The array size is 8000. Flutter needs 0.053s and SwiftUI needs 0.141s. Does anyone have a clue why flutter as a hybrid framework has better performance than a native solution?
Both apps were run in release mode on a physical device.

Related

Vehicle routing problem with dependent dimension constraints (Google ORTools)

I'm very new to OR-Tools and I'm trying to solve a modified VRP with capacity constraints from Google's guide.
In my problem vehicles transport multiple types of items. Some types can be transported together and others cannot.
What I tried
In the following code the types are A and B (they should not be transported together).
First I defined the two callbacks for demands and added the dimensions to the routing model
int demandACallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) => {
var fromNode = manager.IndexToNode(fromIndex);
return demandsA[fromNode];
});
int demandBCallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) => {
var fromNode = manager.IndexToNode(fromIndex);
return demandsB[fromNode];
});
routing.AddDimensionWithVehicleCapacity(demandACallbackIndex, 0,
capacitiesA,
true,
"CapacityA");
routing.AddDimensionWithVehicleCapacity(demandBCallbackIndex, 0,
capacitiesB,
true,
"CapacityB");
Then I retrieved the dimensions and added constraints to routing.solver() for every node
var capacityADimension = routing.GetDimensionOrDie("CapacityA");
var capacityBDimension = routing.GetDimensionOrDie("CapacityB");
for (int i = 0; i < noDeliveries; i++) {
var index = manager.NodeToIndex(i);
routing.solver().Add(capacityADimension.CumulVar(index) * capacityBDimension.CumulVar(index) == 0);
}
When I run the solver (with two vehicles) these constraints seem to be ignored (one vehicle remains parked while the other does all the work even though it shouldn't transport both types of items).
Is this even possible with OR-Tools? If yes, what did I do wrong?
Full code
public SimpleVehicleRoutingSolutionDto SolveVehicleRoutingWithItemConstraints(long[,] distances, long[] capacitiesA, long[] capacitiesB, long[] demandsA, long[] demandsB, int depot)
{
int noVehicles = capacitiesA.Length;
int noDeliveries = deliveriesA.Length;
RoutingIndexManager manager =
new RoutingIndexManager(noDeliveries, noVehicles, depot);
RoutingModel routing = new RoutingModel(manager);
int transitCallbackIndex = routing.RegisterTransitCallback((long fromIndex, long toIndex) => {
var fromNode = manager.IndexToNode(fromIndex);
var toNode = manager.IndexToNode(toIndex);
return distances[fromNode, toNode];
});
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
int demandACallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) => {
// Convert from routing variable Index to demand NodeIndex.
var fromNode = manager.IndexToNode(fromIndex);
return demandsA[fromNode];
});
int demandBCallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) => {
// Convert from routing variable Index to demand NodeIndex.
var fromNode = manager.IndexToNode(fromIndex);
return demandsB[fromNode];
});
routing.AddDimensionWithVehicleCapacity(demandACallbackIndex, 0,
capacitiesA,
true,
"CapacityA");
routing.AddDimensionWithVehicleCapacity(demandBCallbackIndex, 0,
capacitiesB,
true,
"CapacityB");
var capacityADimension = routing.GetDimensionOrDie("CapacityA");
var capacityBDimension = routing.GetDimensionOrDie("CapacityB");
for (int i = 0; i < noDeliveries; i++) {
var index = manager.NodeToIndex(i);
routing.solver().Add(capacityADimension.CumulVar(index) * capacityBDimension.CumulVar(index) == 0);
}
RoutingSearchParameters searchParameters =
operations_research_constraint_solver.DefaultRoutingSearchParameters();
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
searchParameters.LocalSearchMetaheuristic = LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch;
searchParameters.TimeLimit = new Duration { Seconds = 1 };
Assignment solution = routing.SolveWithParameters(searchParameters);
var ret = new SimpleVehicleRoutingSolutionDto();
long totalDistance = 0;
for (int i = 0; i < noVehicles; ++i)
{
var vecihle = new VehiclePathDto { Index = i };
long routeDistance = 0;
var index = routing.Start(i);
while (routing.IsEnd(index) == false)
{
long nodeIndex = manager.IndexToNode(index);
vecihle.Waypoints.Add(new WaypointDto { Index = nodeIndex });
var previousIndex = index;
index = solution.Value(routing.NextVar(index));
routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
}
vecihle.Distance = routeDistance;
ret.Vehicles.Add(vecihle);
totalDistance += routeDistance;
}
ret.TotalDistance = totalDistance;
return ret;
}
And the input:
long[,] dist = {
{ 0, 5, 6 },
{ 5, 0, 3 },
{ 6, 3, 0 }
};
long[] capA = { 5, 5 };
long[] capB = { 5, 5 };
long[] demA = { 0, 1, 0 };
long[] demB = { 0, 0, 1 };
var routingSolution = vehicleRouting.SolveVehicleRoutingWithItemConstraints(dist, capA, capB, demA, demB, 0);
I fixed the problem.
The issue was that the number of nodes was 3 (noDeliveries), however the number of indices was 6, so I only set the constraint on half of them.
Fixed code:
for (int i = 0; i < manager.GetNumberOfIndices(); i++) {
routing.solver().Add(capacityADimension.CumulVar(i) * capacityBDimension.CumulVar(i) == 0);
}
EDIT:
Even better if constraints are set only for the route end node, since the CumulVar value is strictly increasing.
for (int j = 0; j < noVehicles; j++) {
var index = routing.End(j);
routing.solver().Add(capacityADimension.CumulVar(index) * capacityBDimension.CumulVar(index) == 0);
}

In Flutter and if the number after decimal point is equal 0 convert the number to int

This is a function if the endValueFixed is equal for example 12.0 I want to print the number without zero so I want it to be 12.
void calculateIncrease() {
setState(() {
primerResult = (startingValue * percentage) / 100;
endValue = startingValue + primerResult;
endValueFixe`enter code here`d = roundDouble(endValue, 2);
});
}
This may be an overkill but it works exactly as you wish:
void main() {
// This is your double value
final end = 98.04;
String intPart = "";
String doublePart = "";
int j = 0;
for (int i = 0; i < end.toString().length; i++) {
if (end.toString()[i] != '.') {
intPart += end.toString()[i];
} else {
j = i + 1;
break;
}
}
for (int l = j; l < end.toString().length; l++) {
doublePart += end.toString()[l];
}
if (doublePart[0] == "0" && doublePart[1] != "0") {
print(end);
} else {
print(end.toString());
}
}
You may use this code as a function and send whatever value to end.
if (endValueFixed==12) {
print('${endValueFixed.toInt()}');
}
conditionally cast it to an int and print it then :)

How to change the audio sample rate in Unity?

The default audio sample rate is 48000. Is it possible to change it to other values like 44100?
I log the value of AudioSettings.outputSampleRate and it shows 48000. But it doesn't seem possible to change that value.
Here is the code to change sample rate of Unity's AudioClip:
Most simple, but very rough
Averaging approach, but channels are get mixed
Averaging approach for each channel (best quality)
public static AudioClip SetSampleRateSimple(AudioClip clip, int frequency)
{
if (clip.frequency == frequency) return clip;
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var samplesLength = (int)(frequency * clip.length) * clip.channels;
var samplesNew = new float[samplesLength];
var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesLength, clip.channels, frequency, false);
for (var i = 0; i < samplesLength; i++)
{
var index = (int) ((float) i * samples.Length / samplesLength);
samplesNew[i] = samples[index];
}
clipNew.SetData(samplesNew, 0);
return clipNew;
}
public static AudioClip SetSampleRateAverage(AudioClip clip, int frequency)
{
if (clip.frequency == frequency) return clip;
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var samplesNewLength = (int) (frequency * clip.length) * clip.channels;
var samplesNew = new float[samplesNewLength];
var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesNewLength, clip.channels, frequency, false);
var index = 0;
var sum = 0f;
var count = 0;
for (var i = 0; i < samples.Length; i++)
{
var index_ = (int)((float)i / samples.Length * samplesNewLength);
if (index_ == index)
{
sum += samples[i];
count++;
}
else
{
samplesNew[index] = sum / count;
index = index_;
sum = samples[i];
count = 1;
}
}
clipNew.SetData(samplesNew, 0);
return clipNew;
}
public static AudioClip SetSampleRate(AudioClip clip, int frequency)
{
if (clip.frequency == frequency) return clip;
if (clip.channels != 1 && clip.channels != 2) return clip;
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var samplesNewLength = (int) (frequency * clip.length) * clip.channels;
var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesNewLength, clip.channels, frequency, false);
var channelsOriginal = new List<float[]>();
var channelsNew = new List<float[]>();
if (clip.channels == 1)
{
channelsOriginal.Add(samples);
channelsNew.Add(new float[(int) (frequency * clip.length)]);
}
else
{
channelsOriginal.Add(new float[clip.samples]);
channelsOriginal.Add(new float[clip.samples]);
channelsNew.Add(new float[(int) (frequency * clip.length)]);
channelsNew.Add(new float[(int) (frequency * clip.length)]);
for (var i = 0; i < samples.Length; i++)
{
channelsOriginal[i % 2][i / 2] = samples[i];
}
}
for (var c = 0; c < clip.channels; c++)
{
var index = 0;
var sum = 0f;
var count = 0;
var channelSamples = channelsOriginal[c];
for (var i = 0; i < channelSamples.Length; i++)
{
var index_ = (int) ((float) i / channelSamples.Length * channelsNew[c].Length);
if (index_ == index)
{
sum += channelSamples[i];
count++;
}
else
{
channelsNew[c][index] = sum / count;
index = index_;
sum = channelSamples[i];
count = 1;
}
}
}
float[] samplesNew;
if (clip.channels == 1)
{
samplesNew = channelsNew[0];
}
else
{
samplesNew = new float[channelsNew[0].Length + channelsNew[1].Length];
for (var i = 0; i < samplesNew.Length; i++)
{
samplesNew[i] = channelsNew[i % 2][i / 2];
}
}
clipNew.SetData(samplesNew, 0);
return clipNew;
}

Scala , java "for" in scala

I don't know how convert java "continue" to scala.
I can use marker from bool + break, but its bad idea
Google did not help :(
It's my first program in scala... yep.. it's horrible
sort java
def sort(in: Array[Int], a:Int, b:Int)
{
var i,j,mode;
double sr=0;
if (a>=b) return; // size =0
for (i=a; i<=b; i++) sr+=in[i];
sr=sr/(b-a+1);
for (i=a, j=b; i <= j;)
{
if (in[i]< sr) { i++; continue; } // left > continue
if (in[j]>=sr) { j--; continue; } // right, continue
int c = in[i]; in[i] = in[j]; in[j]=c;
i++,j--; // swap and continue
}
if (i==a) return;
sort(in,a,j); sort(in,i,b);
}
sort scala...
def SortMerger(in:List[Int], a:Int, b:Int):Unit = {
var i = 0;
var j = 0;
var mode = 0;
var sr = 0.0;
if(a>=b) return;
i=a
while(i<=b)
{
sr+=in.ElementOf(i);
i += 1
}
sr=sr/(b-a+1)
i=a
j=b
while(i<=j)
{
if(in.ElementOf(i)<sr) {
i += 1;
// where continue??? ><
}
}
return
}
Scala has no continue statement, but what you are trying to do can be done with a simple if/else structure.
while(i<=j)
{
if(in(i) < sr) {
i += 1
} else if (in(j) >= sr) {
j -= 1
} else {
int c = in(i)
in(i) = in(j)
in(j) = c
i += 1
j -= 1
}
}
Note that the type of in here should be Array, not List

Stochastic universal sampling

I need a sus implementation in c# for finding candidate individuals in a population this is what i have so far but im not sure if it is correct.
public void sus(IEnumerable<TimeTable>population)
{
var ag = population.Sum(i => normalize((double) i.Fitness, true));
var mark = rnMutate.NextDouble();
var index = 0;
foreach (var candidate in population)
{
var cu = population.Sum(i => normalize((double)i.Fitness, false)) / ag * 5;
while (cu > mark + index)
{
Survivors.Add(candidate);
index++;
}
}
}
public double normalize(double fitness, bool natural)
{
if (natural)
return fitness;
return fitness == (double)FitnessLBound ? double.PositiveInfinity : 1 / fitness;
}
private IEnumerable<TimeTable> StochasticSample(IEnumerable<TimeTable> population, int size)
{
var t = population.Sum(it => it.Fitness);
var temp = new List<TimeTable>();
var ptr = rnMutate.NextDouble();
var sum = 0M;
for (int i = 0; i < size; i++)
{
for (sum += ExpValue(i, t); sum > (decimal) ptr; ptr++)
{
temp.Add(population.ElementAt(i));
--size;
}
}
return temp;
}
private decimal ExpValue(decimal fitness, decimal sum)
{
return decimal.Divide(fitness, sum);
}