How to calculate the mode of a series in Fortran - fortran

How can I calculate the mode of a series using Fortran?
For example:
1,2,2,3,3,3,4,4,5
Mode = 3

If your numbers are sorted (as they appear to be), the pseudo-code is simple:
set maxval to -1
set maxcount to -1
set count to -1
set lastval to list[0] - 1
for every val in list:
if val is not equal to lastval:
if count is greater than maxcount:
set maxval to lastval
set maxcount to count
set count to 0
set lastval to val
set count to count plus one
if maxcount is not equal to -1:
print "mode is " maxval " with count of " maxcount
Keep in mind that this will return only the first mode if there is more than one.

You can find already made code out there, if you need it and it is not just an exercize; e.g.
Mode at wiki rosettacode.org. If it is an exercize, try first to follow the algorithm given in the other answer.

Related

Finding the permutation that satisfy given condition

I want to find out the number of all permutation of nnumber.Number will be from 1 to n.The given condition is that each ithposition can have number up to Si,where Si is given for each position of number.
1<=n<=10^6
1<=si<=n
For example:
n=5
then its all five element will be
1,2,3,4,5
and given Si for each position is as:
2,3,4,5,5
It shows that at:
1st position can have 1 to 2that is 1,2 but can not be number among 3 to 5.
Similarly,
At 2nd position can have number 1 to 3 only.
At 3rd position can have number 1 to 4 only.
At 4th position can have number 1 to 5 only.
At 5th position can have number 1 to 5 only.
Some of its permutation are:
1,2,3,4,5
2,3,1,4,5
2,3,4,1,5 etc.
But these can not be:
3,1,4,2,5 As 3 is present at 1st position.
1,2,5,3,4 As 5 is present at 3rd position.
I am not getting any idea to count all possible number of permutations with given condition.
Okay, if we have a guarantee that numbers si are given in not descending order then looks like it is possible to calculate the number of permutations in O(n).
The idea of straightforward algorithm is as follows:
At step i multiply the result by current value of si[i];
We chose some number for position i. As long as we need permutation, that number cannot be repeated, so decrement all the rest si[k] where k from i+1 to the end (e.g. n) by 1;
Increase i by 1, go back to (1).
To illustrate on example for si: 2 3 3 4:
result = 1;
current si is "2 3 3 4", result *= si[0] (= 1*2 == 2), decrease 3, 3 and 4 by 1;
current si is "..2 2 3", result *= si[1] (= 2*2 == 4), decrease last 2 and 3 by 1;
current si is "....1 2", result *= si[2] (= 4*1 == 4), decrease last number by 1;
current si is "..... 1", result *= si[3] (= 4*1 == 4), done.
Hovewer this straightforward approach would require O(n^2) due to decreasing steps. To optimize it we can easily observe that at the moment of result *= si[i] our si[i] was already decreased exactly i times (assuming we start from 0 of course).
Thus O(n) way:
unsigned int result = 1;
for (unsigned int i = 0; i < n; ++i)
{
result *= (si[i] - i);
}
for each si count the number of element in your array such that a[i] <= si using binary search, and store the value to an array count[i], now the answer is the product of all count[i], however we have decrease the number of redundancy from the answer ( as same number could be count twice ), for that you can sort si and check how many number is <= s[i], then decrease that number from each count,the complexity is O(nlog(n)), hope at least I give you an idea.
To complete Yuriy Ivaskevych answer, if you don't know if the sis are in increasing order, you can sort the sis and it will also works.
And the result will be null or negative if the permutations are impossible (ex: 1 1 1 1 1)
You can try backtracking, it's a little hardcore approach but will work.
try:
http://www.thegeekstuff.com/2014/12/backtracking-example/
or google backtracking tutorial C++

How do i solve these variations of the 0-1 knapsack algorithm?

The knapsack can carry a maximum weight , say max_wt ; has n items with a given weightwt[] and a valueval[].I have two questions ( both seperate from each other ) :
What is the maximum value we can carry if there was a second limit to the volume we could carry , vol[ ] ?
What are the number of ways to carry a total of exactly z(< n) items such that their sum of values is divisible by a number , say 8 ?
My Attempt
For the first question i refered this stackoverflow post , but the only answer i could understand was one where the two constraints were merged ,but the run time complexity of that would be quite big i guess...what i was thinking was making a dp[i][j][k] , where i is the number of items selected , j is the max-wt selected at that point , k is the max-vol selected at that point and then my core of the code looked like
for(i=0 ; i < n ; i++) \\ n is no. of items
for(j=0 ; j < n ; j++)
for(k=0 ; k < n ; k++)
dp[i][j][k] = max( dp[i-1][j][k] , val[i] + dp[i-1][j-wt[j]][k-vol[k]]) ;
, this seems alright , but gives me wrong answer ... i cant guess why :(
I can't start to think of the second problem, my friend did it by taking three states dp[i][j][k] where i and j are just same as first question(the usual ones) while 'k' keeps track of the total items selected , this idea isnt getting in my head . Plus , what will a state store , it usually stores max value possible till given state in classical knapsack problems , here i guess a state will store total combinations divisible by 8 till that state , but i cant convert this into code .
p.s please try providing a solution with bottom up approach to the second question , i am very new to dynamic programming . ;)
Two-dimensional knapsack problem
let n be the number of items
let val[i] be the value of the i-th item
let w[i] be the weight of the i-th item
let v[i] be the volume of i-th item
let T[i,j,k] be the best value out of the first i items and having exactly weight j and volume k. T can be defined in some other way but this definition gives a short formula.
Finding best value
T[0,j,k] = 0
T[i,j,k] = T[i-1,j,k], when j<w[i] or k<v[i], otherwise:
T[i,j,k] = max( T[i-1,j,k] , T[i-1,j-w[i],k-i] + val[i] )
best possible value would be max T[n,j,k] for all j and k
Implementation notes
initialize base cases first for all j and k
loop i from 1 to n and be consistent with 1-based arrays indexes
loop j from 1 to max possible weight which is the sum of all weights, e.g. w[1]+w[2]+...w[n]
loop k from 1 to max possible volume
Counting number of ways to get an exact value with an exact number of items
let S[i,j,k,l] be the number of ways in which the first i items can be arranged with exactly weight j, value k, and l items.
S[0,j,k,l] = 0, except S[0,0,0,0] = 1
S[i,j,k,l] = S[i-1,j,k,l] + S[i-1,j-w[i],k-val[i],l-1]
number of ways to get exactly value y using exactly z items is the sum of T[n,j,y,z] for all j
Observations
There are many ways to look at these problems and to define the states T and S. This is but one of them. Implementations can also differ. The thumb-rule for dimensions is that another constraint in the sack or dimension in the items means another dimension in the formula. The thumb-rule for counting ways is that you add up instead of finding max.

Using for loops and nested lists in python

I am trying to add each row of nested loop independently in order to find averages. I am missing a detail which may or may not derail my whole code.The code should compute the average of a given row of scores but drops the lowest grade.
def printAverages():
scores = [[100,100,1,100,100],
[20,50,60,10,30],
[0,10,10,0,10],
[0,100,50,20,60]]
total = 0
minValue = 100
counter = -1
for row in scores:
counter = counter + 1
for n in scores[0]:
total = total+n
if minValue > n:
minValue = n
total = total - minValue
print("Average for row",counter,"is",total)
total = 0
How do i make it so for n in score [0] takes the average of each row instead of only computing the average of the first row? I know that scores[0] commands the program to only read the first row, I just don't know how to change it.
Thank you
Remember, the XY problem.
# Sum of a list of numbers divided by the number of numbers in the list
def average(numbers):
return sum(numbers)/len(numbers)
# This is your data
scores = [[100,100,1,100,100],
[20,50,60,10,30],
[0,10,10,0,10],
[0,100,50,20,60]]
# enumerate() allows you to write FOR loops naming both the list element and its index
for (i, row) in enumerate(scores):
print("Average for row ", i, "is ", average(row))
Keep in mind that Python supports functional programming and encourages the programmer to write pure functions when possible!
the statement for n in scores[0]: will only go through the first column.
What you want it to say is for n in row:. That will have it go through each row, one row per loop of the outer loop

How do I find the mode of a sorted array?

I need to write a function to find the mode of a array. I'm not good at coming up with algorithms however and I'm hoping someone else knows how to do this.
I know the size of the array and the values in each element, and I have the array sorted from least to greatest.
array would be passed to the mode function like
mode = findMode(arrayPointer, sizePointer);
UPDATE:
After reading the comments I've tried this
int findMode(int *arrPTR, const int *sizePTR)
{
int most_found_element = arrPTR[0];
int most_found_element_count = 0;
int current_element = arrPTR[0];
int current_element_count = 0;
int count;
for (count = 0; count < *sizePTR; count++)
{
if(count == arrPTR[count])
current_element_count++;
else if(current_element_count > most_found_element)
{
most_found_element = current_element;
most_found_element_count = current_element_count;
}
current_element = count;
current_element_count=1;
}
return most_found_element;
}
I'm still having problems grasping this algorithm though if anyone can sort me out.
I've never used vectors so don't really understand the other examples.
You have almost everything.
You can take advantage of the fact that the array is sorted.
Just go through the array keeping track of both the current equal consecutive numbers, and the greatest number of equal consecutive numbers you have found until that point (and which number produced it). In the end you will have the greatest number of equal consecutive numbers and which number produced it. That will be the mode.
Note: For a solution which does not require the array to be sorted, see for example one based in the histogram approach in a related question.
set most_found_element to the first element in the array
set most_found_element_count to zero
set current_element to the first element of the array
set current_element_count to zero
for each element e in the array
if e is the same as the current_element
increase current_element_count by one
else
if current_element_count is greater than most_found_element_count
set most_found_element to the current_element
set most_found_element_count to current_element_count
set current_element to e
set current_element_count to one
if current_element_count is greater than most_found_element_count
set most_found_element to the current_element
set most_found_element_count to current_element_count
print most_found_element and most_found_element_count
I thought the names would explain it, but here we go:
When we start, no element has been found the most times
so the "high-score" count is zero.
Also, the "current" value is the first, but we haven't looked at it yet
so we've seen it zero times so far
Then we go through each element one by one
if it's the same as "current" value,
then add this to the number of times we've seen the current value.
if we've reached the next value, we've counted all of the "current" value.
if there was more of the current value than the "high-score"
then the "high-score" is now the current value
and since we reached a new value
the new current value is the value we just reached
Now that we've seen all of the elements, we have to check the last one
if there was more of the current value than the "high-score"
then the "high-score" is now the current value
Now the "high-score" holds the one that was in the array the most times!
Also note: my original algorithm/code had a bug, we have to do an extra check of "current" after the loop ends, as it never finds "the one after the last".
Hints:
Q: How do you define the mode?
A: The number whose count is greatest within the array.
Q: How do you count numbers in an ordered array?
A: Iterate through the array, and while the next item is equal to the previous, increment the count for that value.
Q: If the count of the previous value is less than the count of the current value, then can the previous value be the mode?
A: No
If the input array is sorted, here is the same approach as described in other answers but implemented in a different way, a better and easy to understand way.
Run a loop over the input array.
Keep global mode value and mode count.
Run a sliding window till you find equal elements.
If local equal element count is greater than global mode count, then update global mode and mode count.
Here is working and tested code in C++.
int mode(vector<int> a, int N)
{
int mode = a[0];
int mode_count = 1;
int i = 0;
while (i < N - 1) {
int cur = a[i];
int cur_count = 1;
while (a[i] == a[i + 1]) {
i++;
cur_count++;
}
if (cur_count > mode_count) {
mode_count = cur_count;
mode = a[i];
}
i++;
}
return mode;
}

Using empty Boost accumulators

I am curious, what average is obtained from this code snippet? The accumulator is intended to be empty.
boost::accumulators::accumulator_set<
int,
boost::accumulators::features<boost::accumulators::tag::mean>
> Accumulator;
int Mean = boost::accumulators::mean(Accumulator);
The average is non-zero when I test it. Is there some way I can tell that the average was taken for an empty data set? Why is the resulting value for "Mean" non-zero?
I was looking around in the documentation for the accumulator library, but was unable to find an answer to this question.
Any value would be a valid mean for an empty set of values. That is x * 0 = 0 holds for any x.
You could add a count feature to your accumulator_set and query it to see if its 0.
You don't need to add count feature since mean accumulator is based on count and sum accumulators
from boost User's Guide:
mean depends on the sum and count accumulators ... The result of the mean accumulator is merely the result of the sum accumulator divided by the result of the count accumulator.
so you just need to validate that count is bigger then 0:
bool isEmpty = boost::accumulators::count(Accumulator) == 0;