Simple Cyclomatic Complexity Calulations - cyclomatic-complexity

I found this site claiming that Cyclomatic Complexity = ( 2 + ifs + loops +cases - return ) and I also found out that Cyclomatic Complexity can be calculate by the number of conditional statement + 1 which is basically the same.
Now the above states that for each case in a switch add +1 to Cyclomatic Complexity, what happens if I have a return statement in each case?
For example would the CC of the below code still be 4 or 2?
function(someVal) {
switch (someVal) {
case 1: return something;
case 2: return something;
case 3: return something;
doSomething();
break;
default:
doSomethingElse();
break;
}
}

Cyclomatic complexity is the number of linearly independent paths through a program. In other words
how many distinct paths are there from the entry point to the exit point. This in turn is an indicator
as to how complex the underlying program is and gives a lower bound for the number of test cases you would need to get full
path coverage of the module (here full path coverage means executing every line of code at least once).
There are several approaches to calculating the number of paths through a program, most based on graph theory. Many of these have
been summarized into simple counting rules such as the one you are using.
Now to answer your specific question. What is the cyclomatic complexity of your program? Consider the program structure chart:
How many paths are there through this chart? Using the edge numbers we have the following paths:
1, 2
1, 3, 4
1, 3, 5, 6, 7
1, 3, 5, 8, 9
There are 4 linearly independent paths through this program. Cyclomatic complexity is 4.
There are other ways to come up with the same result assuming a structured program (no crossing lines in the structure chart):
edges - nodes + 2 = 9 - 7 + 2 = 4
Number of enclosed spaces in the structure chart plus 1 (3 + 1 = 4)
The original definition of Cyclomatic complexity is: v(G) = E - N + 2P. Where E = Edges, N = Nodes and P = number of modules (graphs). Since
we genearlly apply Cyclomatic complexity to single modules, P is almost always 1.

Related

solved - Find column wise max elements from a matrix subject to maximization constraints

I have a N x N square matrix A consisting of random positive numbers. I have a function that needs to be maximized (for simplicity, consider it sums all the input) whose inputs are one element from each column of the matrix. The constraint is that the position of each of those inputs should be different. For example with N=5
A =
0.43207 0.53996 0.68063 0.70952 0.6297
0.9656 0.72609 0.88174 0.50072 0.41381
0.47571 0.99827 0.061184 0.93099 0.88015
0.98318 0.42879 0.56813 0.3835 0.0039668
0.30498 0.30033 0.76003 0.80426 0.84147
best =
4 3 2 1 5
bestA =
0.98318 0.99827 0.88174 0.70952 0.84147
For now I am checking all possible combinations. But as the matrix size increases, e.g. N=10, search space becomes 10! which too expensive for my requirements. I tried to sort the matrix and look for patterns, but I am stuck in cases where there are repetitions which can be seen in this case after sorting.
>> [Asorted,I] = sort(A,1,'descend')
Asorted =
0.98318 0.99827 0.88174 0.93099 0.88015
0.9656 0.72609 0.76003 0.80426 0.84147
0.47571 0.53996 0.68063 0.70952 0.6297
0.43207 0.42879 0.56813 0.50072 0.41381
0.30498 0.30033 0.061184 0.3835 0.0039668
I =
4 3 2 3 3
2 2 5 5 5
3 1 1 1 1
1 4 4 2 2
5 5 3 4 4
Is there any algorithm or any kind of intuition I can follow?
I am using MATLAB, but you can use any popular programming language to explain.
Edit: The matrix is already given and it is generated randomly. The main objective is to maximize the output of a given function which i have mentioned above and find what are those inputs for which the output is maximum.
Edit 2: A sample MATLAB code for above example
N=5;
A = rand(N,N)
combs = perms(1:N);
Sbest = -1;
for i=1:size(combs,1)
x = combs(i,:);
S = 0;
for i=1:N
S=S + A(x(i),i);
end
if S>Sbest
Sbest=S; best = x;
end
end
best
[Asorted,I] = sort(A,1,'descend')
Solution: As pointed out by #גלעד ברקן in the comments, this can be solved using Hungarian Algorithm. Some resources are here, matlab code
Regarding the algorithm, I suspect it might be necessary to go through all combinations to find the best, i.e., brute force. I am not sure if any graph theory algorithm is straightforwardly applicable to this problem, but perhaps some modified ones could work.
From the aspect of acceleration, maybe you can speed up by replacing the inner for loop with sum, i.e.,
for i=1:size(combs,1)
x = combs(i,:);
S = sum(A(((1:N)-1)*N + x));
if S > Sbest
Sbest=S;
best = x;
end
end

Is Recursion W/Memoization In Staircase Problem Bottom-Up?

Considering the classical staircase problem as "Davis has a number of staircases in his house and he likes to climb each staircase 1, 2, or 3 steps at a time. Being a very precocious child, he wonders how many ways there are to reach the top of the staircase."
My approach is to use memoization with recursion as
# TimeO(N), SpaceO(N), DP Bottom Up + Memoization
def stepPerms(n, memo = {}):
if n < 3:
return n
elif n == 3:
return 4
if n in memo:
return memo[n]
else:
memo[n] = stepPerms(n - 1, memo) + stepPerms(n - 2 ,memo) + stepPerms(n - 3 ,memo)
return memo[n]
The question that comes to my mind is that, is this solution bottom-up or top-down. My way of approaching it is that since we go all the way down to calculate the upper N values (imagine the recursion tree). I consider this bottom-up. Is this correct?
Recoursion strategies are as a general rule topdown approaches, whether they have memory or not. The underlaying algorithm design is dynamic programming, which traditionally built in a bottom-up fashion.
I noticed that you wrote your code in python, and python is generally not happy about deep recoursion (small amounts are okay, but performance quickly takes a hit and there is a maximum recousion depth of 1000 - unless it was changed since I read that).
If we make a bottom-up dynamic programmin version, we can get rid of this recousion, and we can also recognise that we only need constant amount of space, since we are only really interested in the last 3 values:
def stepPerms(n):
if n < 1: return n
memo = [1,2,4]
if n <= 3: return memo[n-1]
for i in range(3,n):
memo[i % 3] = sum(memo)
return memo[n-1]
Notice how much simpler the logic is, appart from the i is one less than the value, since the positions are starts a 0 instead of the count of 1.
In the top-down approach, the complex module is divided into submodules. So it is top down approach. On the other hand, bottom-up approach begins with elementary modules and then combine them further.
And bottom up approach of this solution will be:
memo{}
for i in range(0,3):
memo[i]=i
memo[3]=4
for i in range(4,n+1):
memo[i]=memo[i-1]+memo[i-2]+memo[i-3]

Algorithm for a stair climbing permutation

I've been asked to build an algorithm that involves a permutation and I'm a little stumped and looking for a starting place. The details are this...
You are climbing a staircase of n stairs. Each time you can either climb 1 or 2 steps at a time. How many distinct ways can you climb to the top?
Any suggestions how I can tackle this challenge?
You're wrong about permutations. Permutations involve orderings of a set. This problem is something else.
Problems involving simple decisions that produce another instance of the same problem are often solvable by dynamic programming. This is such a problem.
When you have n steps to climb, you can choose a hop of either 1 or 2 steps, then solve the smaller problems for n-1 and n-2 steps respectively. In this case you want to add the numbers of possibilities. (Many DPs are to find minimums or maximums instead, so this is a bit unusual.)
The "base cases" are when you have either 0 or 1 step. There's exactly 1 way to traverse each of these.
With all that in mind, we can write this dynamic program for the number of ways to climb n steps as a recursive expression:
W(n) = W(n - 1) + W(n - 2) if n > 1
1 n == 0, 1
Now you don't want to implement this as a simple recursive function. It will take time exponential in n to compute because each call to W calls itself twice. Yet most of those calls are unnecessary repeats. What to do?
One way to get the job done is find a way to compute the W(i) values in sequence. For a 1-valued DP it's usually quite simple, and so it is here:
W(0) = 1
W(1) = 1 (from the base case)
W(2) = W(1) + W(0) = 1 + 1 = 2
W(3) = W(2) + W(1) = 2 + 1 = 3
You get the idea. This is a very simple DP indeed. To compute W(i), we need only two previous values, W(i-1) and W(i-2). A simple O(n) loop will do the trick.
As a sanity check, look at W(3)=3. Indeed, to go up 3 steps, we can take hops of 1 then 2, 2 then 1, or three hops of 1. That's 3 ways!
Can't resist one more? W(4)=2+3=5. The hop sequences are (2,2), (2,1,1), (1,2,1), (1,1,2), and (1,1,1,1): 5 ways.
In fact, the chart above will look familiar to many. The number of ways to climb n steps is the (n+1)th Fibonacci number. You should code the loop yourself. If stuck, you can look up any of the hundreds of posted examples.
private static void printPath(int n,String path) {
if (n == 0) {
System.out.println(path.substring(1));
}
if (n-1 >=0) {
printPath(n-1,path + ",1");
}
if (n-2 >=0) {
printPath(n-2,path + ",2");
}
}
public static void main(String[] args) {
printPath(4,"");
}
Since it looks like a programming assignment, I will give you the steps to get you started instead of giving the actual code:
You can write a recursive function which keeps track of the step you are on.
If you have reached step n then you found one permutation or if you are past n then you should discard it.
At every step you can call the function by incrementing the steps by 1 and 2
The function will return the number of permutations possible once finished

Fast algorithm to optimize a sequence of arithmetic expression

EDIT: clarified description of problem
Is there a fast algorithm solving following problem?
And, is also for extendend version of this problem
that is replaced natural numbers to Z/(2^n Z)?(This problem was too complex to add more quesion in one place, IMO.)
Problem:
For a given set of natural numbers like {7, 20, 17, 100}, required algorithm
returns the shortest sequence of additions, mutliplications and powers compute
all of given numbers.
Each item of sequence are (correct) equation that matches following pattern:
<number> = <number> <op> <number>
where <number> is a natual number, <op> is one of {+, *, ^}.
In the sequence, each operand of <op> should be one of
1
numbers which are already appeared in the left-hand-side of equal.
Example:
Input: {7, 20, 17, 100}
Output:
2 = 1 + 1
3 = 1 + 2
6 = 2 * 3
7 = 1 + 6
10 = 3 + 7
17 = 7 + 10
20 = 2 * 10
100 = 10 ^ 2
I wrote backtracking algorithm in Haskell.
it works for small input like above, but my real query is
randomly distributed ~30 numbers in [0,255].
for real query, following code takes 2~10 minutes in my PC.
(Actual code,
very simple test)
My current (Pseudo)code:
-- generate set of sets required to compute n.
-- operater (+) on set is set union.
requiredNumbers 0 = { {} }
requiredNumbers 1 = { {} }
requiredNumbers n =
{ {j, k} | j^k == n, j >= 2, k >= 2 }
+ { {j, k} | j*k == n, j >= 2, k >= 2 }
+ { {j, k} | j+k == n, j >= 1, k >= 1 }
-- remember the smallest set of "computed" number
bestSet := {i | 1 <= i <= largeNumber}
-- backtracking algorithm
-- from: input
-- to: accumulator of "already computed" number
closure from to =
if (from is empty)
if (|bestSet| > |to|)
bestSet := to
return
else if (|from| + |to| >= |bestSet|)
-- cut branch
return
else
m := min(from)
from' := deleteMin(from)
foreach (req in (requiredNumbers m))
closure (from' + (req - to)) (to + {m})
-- recoverEquation is a function converts set of number to set of equation.
-- it can be done easily.
output = recoverEquation (closure input {})
Additional Note:
Answers like
There isn't a fast algorithm, because...
There is a heuristic algorithm, it is...
are also welcomed. Now I'm feeling that there is no fast and exact algorithm...
Answer #1 can be used as a heuristic, I think.
What if you worked backwards from the highest number in a sorted input, checking if/how to utilize the smaller numbers (and numbers that are being introduced) in its construction?
For example, although this may not guarantee the shortest sequence...
input: {7, 20, 17, 100}
(100) = (20) * 5 =>
(7) = 5 + 2 =>
(17) = 10 + (7) =>
(20) = 10 * 2 =>
10 = 5 * 2 =>
5 = 3 + 2 =>
3 = 2 + 1 =>
2 = 1 + 1
What I recommend is to transform it into some kind of graph shortest path algorithm.
For each number, you compute (and store) the shortest path of operations. Technically one step is enough: For each number you can store the operation and the two operands (left and right, because power operation is not commutative), and also the weight ("nodes")
Initially you register 1 with the weight of zero
Every time you register a new number, you have to generate all calculations with that number (all additions, multiplications, powers) with all already-registered numbers. ("edges")
Filter for the calculations: it the result of the calculation is already registered, you shouldn't store that, because there is an easier way to get to that number
Store only 1 operation for the commutative ones (1+2=2+1)
Prefilter the power operation because that may even cause overflow
You have to order this list to the shortest sum path (weight of the edge). Weight = (weight of operand1) + (weight of operand2) + (1, which is the weight of the operation)
You can exclude all resulting numbers which are greater than the maximum number that we have to find (e.g. if we found 100 already, anything greater that 20 can be excluded) - this can be refined so that you can check the members of the operations also.
If you hit one of your target numbers, then you found the shortest way of calculating one of your target numbers, you have to restart the generations:
Recalculate the maximum of the target numbers
Go back on the paths of the currently found number, set their weight to 0 (they will be given from now on, because their cost is already paid)
Recalculate the weight for the operations in the generation list, because the source operand weight may have been changed (this results reordering at the end) - here you can exclude those where either operand is greater than the new maximum
If all the numbers are hit, then the search is over
You can build your expression using the "backlinks" (operation, left and right operands) for each of your target numbers.
The main point is that we always keep our eye on the target function, which is that the total number of operation must be the minimum possible. In order to get this, we always calculate the shortest path to a certain number, then considering that number (and all the other numbers on the way) as given numbers, then extending our search to the remaining targets.
Theoretically, this algorithm processes (registers) each numbers only once. Applying the proper filters cuts the unnecessary branches, so nothing is calculated twice (except the weights of the in-queue elements)

loaded die algorithm

I want an algorithm to simulate this loaded die:
the probabilities are:
1: 1/18
2: 5/18
3: 1/18
4: 5/18
5: 1/18
6: 5/18
It favors even numbers.
My idea is to calculate in matlab the possibility of the above.
I can do it with 1/6 (normal die), but I am having difficulties applying it for a loaded die.
One way: generate two random numbers: first one is from 0 to 5 (0: odd, 1 - 5: even), which is used to determine even or odd. Then generate a second between 0 and 2, which determines exact number within its category. For example, if the first number is 3 (which says even) and second is 2 (which says the third chunk, 1-2 is a chunk, 3-4 is another chunk and 5-6 is the last chunk), the the result is 6.
Another way: generate a random number between 0 and 17, then you can simply / 6 and % 6 and use those two numbers to decide. For example, if /6 gives you 0, then the choice is between 1 and 2, then if % 6 == 0, the choice lands on 1, otherwise lands on 2.
In matlab:
ceil(rand*3)*2-(rand>(5/6))
The generic solution:
Use roulette wheel selection
n = generate number between 0 and sum( probabilities )
s = 0;
i = 0;
while s <= n do
i = i + 1;
s = s + probability of element i;
done
After the loop is done i will be the number of the chosen element. This works for any kind of skewed probability distribution, even when you have weights instead of a probability and want to skip normalizing.
In the concise language of J,
>:3(<([++:#])|)?18

Resources