Computational complexity of generating a random vector

I’m new to the concept of computational complexity and trying to understand the topic in depth. I went through some references mentioned by some old questions, however, I had this question and not sure if my understanding is correct. I want to know the complexity of generating a random vector of size $N$. Is it $mathcal{O}(N)$ cause I’m generating $N$ random numbers and the complexity of generating each one of them is $mathcal{O}(1)$ or is it simply $mathcal{O}(1)$?

pr.probability – The mean value of the reconstruction complexity of a random sequence

This problem is motivated by the problem of reconstructing a genome from the family of its short subwords.

Given a word $w$ and a positive integer $k$, let $M_k(w)$ be the family of all subwords of length $k$ and $mu_{k,w}:M_k(w)to omega$ be the function assigning to each subword $vin M_k(w)$ the number of subwords of $w$ that are equal to $v$.

For example, for the word $w=mathover!flow$ we have
$$M_2(w)={ma,at,th,ho,ov,ve,er,rf,fl,lo,ow}$$ and
$$M_3(w)={mat,ath,tho,hov,ove,ver,erf,rfl,flo,low}$$ and $mu_{k,w}equiv 1$ is the constant unit functions on $M_k(w)$ for $kin{2,3}$.

Definition. The reconstruction complexity of a word $w$ is the smallest $k$ such that for any word $u$, the equality $mu_{k,w}=mu_{k,u}$ implies $w=u$.

For example, the word $mathover!flow$ has reconstruction complexity 2.

Problem. What is the mean value of the reconstruction complexity of a random word of length $n$ in a finite alphabet $A$? We assume that each word appears with equal probability $1/|A|^n$.

I am especially interested in case $|A|=4$ (because DNA-sequences are written in such an alphabet).

Computer experiments show that a random word in 4-letter alphabet of length about 1500 (a typical length of a short gene) has reconstruction complexity about 10, and the complexity slightly grows with growth of $n$. For $n=3000$ it is near 12. So, what are lower and upper bounds for the reconstruction complexity of a random word? Maybe it is $O(ln n)$?

Complexity in time and memory for graph search algorithm

I am working on an assignment where I have to write an algorithm to detect all vertices that lie in a cycle in a graph and then calculate its complexity. I have come up with an algorithm in pseudocode. My approach is to ‘delete’ all vertices that have only one connecting edge until no vertexes are left that have only one connecting edge. The remaining vertices, if any, are part of a cycle.

The graph is undirected.

/*
// vertices is an array containing every vertex
// e.g. vertices = (0,1,2,3,...)
*/
vertices()

/*
// edges is a two dimensional array defining each edge
// by the two vertices it connects
// e.g. edges = ((0,1),(2,3),(4,1),...)
*/
edges()

verticesInCycle = cycleDetection(vertices, edges, vertices)

verticesNotInCycle = vertices

foreach (verticesInCycle as vertexIC) {
    if (verticesNotInCycle.contains(vertexIC)) {
        verticesNotInCycle.remove(vertexIC);
    }
}


/*
// vertices() = vertices to test
// edges() = edges to test them against
// verticesLeft() = all untested vertices that are left
*/
function cycleDetection(vertices(), edges()), verticesLeft()) {
    recur = false
    nextVertices()

    foreach (vertices as vertex) {
        count = 0
        connectingEdge = null

        foreach (edges as edge) {
            if (vertex == edge(0) || vertex == edge(1)) {
                count++

                if (count > 1) {
                    break
                } else {
                    connectingEdge = edge
                }
            }
        }

        if (count == 1) {
            edges.remove(connectingEdge)
            verticesLeft.remove(vertex)

            if (connectingEdge(0) == vertex) {
                nextVertices.add(connectingEdge(1))
            } else {
                nextVertices.add(connectingEdge(0))
            }

            recur = true
        }
    }

    if (recur) {
        cycleDetection(nextVertices, edges, verticesLeft)
    } else {
        return verticesLeft
    }
}

Example Run

Example graph

10  6
  / 
  1   5
  |   |
  2   4-7
  | /
  8 3
   
    9

Initial call of cycleDetection

x   o
  / 
  o   o
  |   |
  o   o-x
  | /
  o o
   
    x

First recursive call

    o
   / 
  o   o
  |   |
  o   o
  | /
  x o


Second recursive call

    o
   / 
  o   o
  |   |
  o   o
    /
    o


Done!

Now I am calculating the complexity (time and memory)

I calculated that the complexity is approximately O(1.4(V*E)), where N is the number of vertices and E the number of edges.

This is based on the time (or iterations) because the maximum number of iterations (vertices and edges to check) is approximately 1.4(n*e), where n is the number of vertices and e the number of edges.

The worst case, which requires the most iterations, is a line of connected vertices with a cycle at one end.

o
|
| o-o-o-o-o-o-o-o-o-o
|/
o

In this case the complexity is the number of vertices n times the number of edges e multiplied by approximately 1.4. Initially all edges need to be iterated for every vertex but subsequently only the remaining edges need to be iterated for one vertex at a time. In the end about a fourth of n*e needs to be iterated through after the initial iteration of all edges for every vertex.

Memory usage

Memory usage is directly dependant on the amount of recursive calls, with the first call needing the most memory. Every call of cycleDetection uses v + e + vL memory, v + e + vL being the size of the three arrays passed as parameters.

The worst case for memory usage is a line of connected vertices with a cycle at one end (as above). In this case the amount of recursive calls required is v - 2, where v is the number of vertices given that v > 2. So memory complexity is approximately O(3) work memory.

A. I am unsure if my time complexity is formulated right? It doesn’t need to be spot on but I also saw that you can leave out the multiplier and write something like O(VxE**2).

B. I am pretty sure my memory complexity is wrong? I have read this and formulated my complexity accordingly based on the fact that I have three variables that I am passing to my function with every recursive call.

complexity theory – Finding a kernel for d-Bounded degree deletion

In $d$ Bounded degree deletion problem, we are given an undirected graph $G$ and a positive integer $k$, and the task is to find at most $k$ such vertices whose removal decreases the the maximum vertex degree of the graph to at most $d$.

The question is to how to find a polynomial kernel (in $k$ and $d$) for this problem.

I seem to be able to get the only reduction rule that if any vertex has degree $ > k+d$, it has to be there in the deletion set (if the answer to instance is yes). Because if it isn’t, then at least $k+1$ of its neighbors have to be in deletion set. I can’t seem to move beyond this point.

The exercise is from this book (exercise $2.9$).

I am also aware that we can remove edges between vertices with degree $< d$, and find solution in the modified graph (hint from the book). But I am not sure how it will be useful, in getting a bound over number of vertices/edges in $k$ and $d$.

I would appreciate only hints if possible (something maybe beyond the book hints).

PS: for $d=0$ this reduces to vertex cover problem.

computational complexity – Fast division by 3 or 5

There was a question about this topic posted on StackExchange 12 years ago, see here. Basically, it says that there is nothing better than the 3000 years-old technique, and the suggestion in modern times is to “let the compiler do its job”.

Well, here is what mine is doing. Divide the following integer by 3:

222730506728397170591387079211836683557072632289734369842905278066498119541270318525897952142956554114412930297037751282

The result is this:

74243502242799056863795693070612227852360000000000000000000000000000000000000000000000000000000000000000000000000000000

Obviously it is totally wrong, despite using the BigNum library in Perl. I know you can compute the multiplication $3x$ very fast: $3x = 2x + x = (x$ << $1) + x$ using the bit shifting operator. But what about the division?

I came up with the following rudimentary algorithm, but I am wondering if there is a faster solution.

Algorithm

Let $x$ be the number to be divided by $3$. Pre-compute $3^k$ and $2cdot 3^k$ for $k=0,cdots,n$ with $n=lfloorlog_3 xrfloor$. In other words, $n$ is the largest integer such that $3^nleq x$. Very useful step, since I have a bunch of large integers (all equal to zero modulo $3$) that I need to divide by $3$ and by any power of $3$ that is also a divisor. Here I assume $x$ is the largest of the integers that I am dealing with. Then the initialization step consists of:

  • $z leftarrow x$
  • $d_{n+1} leftarrow 0$
  • $nleftarrow n+1$

The loop consists of:

  • $y=z-d_n 3^n$
  • If $2cdot 3^{n-1} < y$ then $d_{n-1}=2$ else if $3^{n-1} <
    y$
    then $d_{n-1}=1$ else $d_{n-1}=0$.
  • $z leftarrow y$
  • $nleftarrow n-1$

Repeat the loop until $n=0$.

The sequence $d_1,cdots,d_n$ is the digits of $x/3$ in base $3$. If $3$ divides $x$ then $d_0=0$. Thus
$$frac{x}{3}=sum_{k=1}^nd_{k}3^{k-1}.$$

Note that $2cdot 3^{k} = 3^{k}$ << $1$ (faster than the multiplication by $2$). In the final sum, use pre-computed values for $d_k 3^{k-1}$.

nt.number theory – nth prime number with constant time complexity

Thanks for contributing an answer to MathOverflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

Use MathJax to format equations. MathJax reference.

To learn more, see our tips on writing great answers.

time complexity – Modification to the Algorithm merge sort

I was trying to solve this problem but I’m struggling in the time complexity
Can u help me please:
Consider the following modification to the Algorithm mergesort. We apply
the algorithm on the input array A(1..n) and continue the recursive calls
until the size of a substance becomes relatively small, say m or less. At
this point, we switch to Algorithm insertion sort and apply it on the
small instance. So, the first test of the modified algorithm will look like
the following:
if high − low + 1 ≤ m then insertion sort(A(low..high)).
What is the largest value of m in terms of n such that the running time
of the modified algorithm will still be Θ(n log n)? You may assume for
simplicity that n is a power of 2

time complexity – Two increasing functions from the set of positive integers to the set of positive integers such that neither f (n) is O(g(n)) nor g(n) is O(f (n))

Here is the question again : Give an example of two increasing functions f (n) and g(n) from the set of positive integers to the set of positive integers such that neither f (n) is O(g(n)) nor g(n) is O(f (n)).

I tried with several functions such as sine and cosine, but they are not increasing functions but Oscillatory. Then I tried x + sinx and x + cosx. However for sufficiently large coefficients c and n0, they also fail two satisfy the criteria. I am starting to doubt if such pairs of functions even exist !?

complexity – Why am I getting complex errors even with simple C++ code?

I started to play with C++ recently. One of the difficulties I have quite often is when the compiler tells that there is an issue with the types: more often than not, those compiler errors look extremely cryptic to me. Here’s an example:

Smooth.h:63:15: error: invalid user-defined conversion from ‘Smooth<T, S>::sum(std::size_t) (with T = short unsigned int; long unsigned int S = 20; std::size_t = long unsigned int)::<lambda(short unsigned int, short unsigned int)>’ to ‘short unsigned int (*)(short unsigned int, short unsigned int)

When I worked with C#, I remember there was a way to get quite complicated errors by combining generics, i.e. use generics as parameters of other generics, possibly at more than two levels, but one had to write really WTF code for that, such as:

Action<IEnumerable<Tuple<int?, Func<int?, ICollection<int>, bool>>>

In C++, however, I do have those cryptic errors with code I would consider rather simple itself. So what is happening?

  • Is it a skill to understand the errors given by the compiler?
  • Or I shouldn’t get those complicated errors in the first place, and their presence indicates that I’m doing something wrong?

As requested in the comments, here’s the corresponding source code, at least the relevant part. Context: the code is intended to run on a microcontroller, so STL is not available, which makes it necessary to reinvent the wheel.

template <typename T, size_t S>
class Smooth {
    T sum(size_t of = S) {
        return this->reduce(
            T(),
            ()(T acc, T value) { return acc + value; },
            0,
            of);
    }

    T reduce(
            const T initial,
            T (*acc)(T, T),
            const size_t skip = 0,
            const size_t take = S) {
        ...
    }
};

The actual error was within return acc + value; and happens if T is not an integer, but, for instance, uint16_t. In this case, the lambda result is an integer, while T is expected. The fix consists of replacing the lambda by return static_cast<T>(acc + value);.