2016-06-23 10 views
0

Ich muss einen Algorithmus erstellen, der diese Eingabe nehmen muss: N, Bereich (rMax und rMin Wert) und Durchschnitt. Und in Abhängigkeit davon muss er N Werte (ein Array zum Beispiel) zurückgeben, deren Durchschnitt ein durchschnittlicher Eingabewert ist.Wie n Werte in einem bestimmten Bereich zu bestimmen, und deren Durchschnitt ist vorgegeben. (Javascript Algorithmus)

function createAverageValues(N,rMin,rMax,average){ 
    var averageValues = []; 
    var j = 0; 
    while(j<N){ 
     .... 
     .... 
     .... 
     averageValues.push(...); 
     j++; 
    }; 
    return averageValues; 
};  

Anforderungen:

  • N, rMin Rmax ganzzahlige Eingangswerte;
  • Rückgabewerte können auch Float-Werte mit zwei Dezimalstellen (x.xx) sein.
  • Wenn ich den Algorithmus mit den gleichen Eingabewerten verwende, können die zurückgegebenen Werte unterschiedlich sein. Aber ihr Durchschnitt muss immer der in der Eingabe angegebene sein;
  • Die zurückgegebenen Werte können auch mehrmals wiederholt werden. So kann auch mehrfach der gleiche Wert verwendet werden. Es ist mir nur wichtig, dass der Durchschnitt des zurückgegebenen Durchschnitts-Array das erforderliche ist.

Exemple 1


/** 
N of values: 4; 
Range: 3-7 (3 <= value <= 7); 
Average: 5; 

N = 4; 
rMin = 3; 
rMax = 7; 
average = 5; 
**/ 

var averageValues = createAverageValues(4,3,7,5); 

Eine mögliche Lösung wäre:

averageValues = [3,4,6,7]; 

Eine andere mögliche Lösung wäre:

averageValues = [6,4,4,6]; 

Etc ...

Exemple 2


/** 
N of values: 5; 
Range: 0-12 (0 <= value <= 12); 
Average: 6; 

N = 5; 
rMin = 0; 
rMax = 12; 
average = 6; 
**/ 

var averageValues = createAverageValues(5,0,12,6); 

Eine mögliche Lösung wäre:

averageValues = [12,4,10,0,4]; 

Eine andere mögliche Lösung wäre:

averageValues = [10,8,11,0,1]; 

...

Exemple 3


/** 
N of values: 3; 
Range: 9-15 (9 <= value <= 15); 
Average: 12; 

N = 3; 
rMin = 9; 
rMax = 15; 
average = 12; 
**/ 

var averageValues = createAverageValues(3,9,15,12); 

Eine mögliche Lösung wäre:

averageValues = [10,14,12]; 

Eine andere mögliche Lösung wäre:

averageValues = [11,11,14]; 

würde Eine andere mögliche Lösung sein: mir einen Jab es

averageValues = [9.50,14.75,11.75]; 

Etc ...

+0

Im zweiten Beispiel löst 5 nicht 4? – achref

+0

Gibt es eine Anforderung, dass der Durchschnittswert nicht n-mal verwendet wird? –

+0

Ist es erforderlich, dass die Zahlen ganze Zahlen sind? –

Antwort

0

Lassen nehmen. Ich will nur den Algorithmus skizzieren, die Sie verwenden können:

Probleme läuft darauf hinaus unten an:

avg = (a + b + ....)/N

Als avg und N gegeben Sie brauchen Um herauszufinden, was alle Werte Sie brauchen, so dass: avg * N = (a + b + ....)

Wie wir wissen, sollte es N Begriffe geben, die zu avg * N summieren sollten. Wir können die Rekursion/dynamische Programmierung verwenden, um die Zahlen zu finden, die summieren sich zu Durchschnitt *

Es ist das selbe wie Teilmenge Summenproblem, wo anstatt der Zahlen Sie einen Bereich gegeben haben.

+0

Vielen Dank für Ihren Vorschlag. Ich testete mit einem Subset-Summen-Algorithmus, das Problem ist, dass ich manchmal Dutzende von Zahlen haben könnte, und in diesem Fall dauert es eine lange Zeit. Während ich eine schnellere Lösung brauche. Aber dank deiner Antwort wurde ich inspiriert, [meinen Algorithmus] zu erstellen (http://stackoverflow.com/a/38146136/5811628) :) – astrovicApps

0

Nach mehreren Versuchen, habe ich einen Algorithmus, der in akzeptabler Weise und schnell mein Problem :)

// It create an of values, in the range [_rMin , _rMax], each of which differs from the next 0.1 
 
function createRangeValues(_rMin, _rMax) { 
 
\t var rangeValues = []; 
 
\t var value = _rMin; 
 
\t while (value < _rMax) { 
 
\t \t rangeValues.push(value); 
 
\t \t value = ((value * 10) + 1)/10; 
 
\t \t console.log("value ---> " + value); 
 
\t }; 
 
\t return rangeValues; 
 
}; 
 

 
// shuffle array http://stackoverflow.com/a/2450976/5811628 
 
function shuffle(array) { 
 
\t var currentIndex = array.length, 
 
\t  temporaryValue, 
 
\t  randomIndex; 
 

 
\t // While there remain elements to shuffle... 
 
\t while (0 !== currentIndex) { 
 

 
\t \t // Pick a remaining element... 
 
\t \t randomIndex = Math.floor(Math.random() * currentIndex); 
 
\t \t currentIndex -= 1; 
 

 
\t \t // And swap it with the current element. 
 
\t \t temporaryValue = array[currentIndex]; 
 
\t \t array[currentIndex] = array[randomIndex]; 
 
\t \t array[randomIndex] = temporaryValue; 
 
\t } 
 

 
\t return array; 
 
} 
 

 
function calculateNewRangeValue(rangeValues, sumRangeValues, averageValuesSum, rMin, rMax){ 
 
\t // Now I modify each value on rangeValues, in such a way that 
 
\t // their average is equal to desired avg. 
 
\t // The modified value must however be a value in the range. 
 
\t var newRangeValues = []; 
 
\t for (var i in rangeValues) { 
 
\t \t var value = parseFloat(rangeValues[i]/sumRangeValues * averageValuesSum).toFixed(2); 
 
\t \t if((value >= rMin) && value <= rMax){ 
 
\t \t \t newRangeValues.push(value); 
 
\t \t }else{ 
 
\t \t \t console.log(value +" is out range " + rMin + " - " + rMax + ". Create a new createRangeValues()"); 
 
\t \t \t return false; 
 
\t \t }; 
 
\t }; \t 
 
\t return newRangeValues; 
 
}; 
 

 
function createAverageValues(X, N, rMin, rMax, avg) { \t 
 
\t var averageValues = []; 
 
\t // Calculate the sum of the average values 
 
\t // avg = averageValuesSum/N ===> averageValuesSum = avg*N; 
 
\t var averageValuesSum = parseInt(avg) * parseInt(N); 
 
\t console.log("averageValuesSum ---> " + averageValuesSum); 
 
\t 
 
\t // Array of values, in the range [rMin , rMax]. That means: rangeValues = [rMin, rMin+0.1, rMin+0.2, ...., rMax] 
 
\t var rangeValues = createRangeValues(rMin, rMax); 
 
\t console.log("rangeValues ---> " + rangeValues); 
 
\t \t 
 
\t for (var k = 0; k < X; k++) { \t \t \t \t 
 
\t \t // Create a shuffled array of rangeValues 
 
\t \t var rangeValuesShuffled = shuffle(rangeValues); 
 
\t \t // I need only N values 
 
\t \t rangeValuesShuffled = rangeValuesShuffled.slice(0, N); 
 
\t \t console.log(k + ") shuffled rangeValuesShuffled ---> " + rangeValuesShuffled); 
 
\t \t 
 
\t \t // Calculate the sum of the N values \t \t 
 
\t \t var sumRangeValues = 0; 
 
\t \t for (var i in rangeValuesShuffled) { 
 
\t \t \t sumRangeValues = sumRangeValues + rangeValuesShuffled[i]; 
 
\t \t }; 
 
\t \t console.log(k + ") sumRangeValues ---> " + sumRangeValues); 
 
\t \t 
 
\t \t // Calculate new rangeValues 
 
\t \t var newRangeValues = calculateNewRangeValue(rangeValuesShuffled, sumRangeValues, averageValuesSum, rMin, rMax); 
 
\t \t 
 
\t \t if(!newRangeValues){ \t \t \t 
 
\t \t \t // I found a value out of range, therefore 
 
\t \t \t // repeat the cycle with other values 
 
\t \t \t k--; 
 
\t \t }else{ 
 
\t \t \t console.log("new rangeValues, in which the avg is " + avg + " ---> " + newRangeValues); \t \t 
 
\t \t \t // This is not needed, but I use it only to check if the average 
 
\t \t \t // of the values of the new array, is really equal to the desired avg 
 
\t \t \t var newRangeValuesSum = 0; 
 
\t \t \t for (var i in newRangeValues) { 
 
\t \t \t \t newRangeValuesSum = parseFloat(newRangeValuesSum) + parseFloat(newRangeValues[i]); 
 
\t \t \t }; 
 
\t \t \t console.log(k +") new rangeValuesSum ---> " + parseFloat(newRangeValuesSum).toFixed(2) + " ---> so avg is: " + parseFloat(newRangeValuesSum).toFixed(2)/N); 
 
\t \t \t console.log("********\n\n\n"); \t \t 
 
\t \t \t \t \t 
 
\t \t \t averageValues.push(newRangeValues); 
 
\t \t \t 
 
\t \t \t // Write results 
 
\t \t \t document.write("<br> averageValues["+k+"] ---> <br>" + averageValues[k].join("; ")); 
 
\t \t \t document.write("<br> averageValuesSum["+k+"] ---> " + parseFloat(newRangeValuesSum).toFixed(2) + " ===> so avg is: " + parseFloat(parseFloat(newRangeValuesSum).toFixed(2)/N).toFixed(2)+"<br><br>"); 
 
\t \t }; 
 
\t }; \t 
 
\t 
 
\t return averageValues; 
 
}; 
 

 
/** 
 
// HOW TO USE IT 
 
// createAverageValues(X, N, rMin, rMax, avg); 
 

 
X = Number of array of N values; 
 
N = Number of values for each array; 
 
rMin = min value of the range; 
 
rMax = max value of the range; 
 
avg = average of each array values 
 

 
For example if I want 8 array of 10 values included in a range between 3 and 9, in which the average is 7: 
 
createAverageValues(8, 10, 3, 9, 7); 
 

 
**/ 
 

 
var averageValues = createAverageValues(8, 10, 3, 9, 7); 
 
console.log("********\n\n\n averageValues:"); 
 
console.log(averageValues); \t
die N Werte rechts