How to convert two arrays into adjacency list? Python - graph

Can I convert the two arrays start,end into an adjacency list? or a 2d array so something like edge of a graph?
from typing import List
def max_network_rank(starts: List[int], ends: List[int], n: int) -> int:
adj = [0] * (n + 1)
for a, b in zip(starts, ends):
adj[a] += 1
adj[b] += 1
max_rank = 0
for a, b in zip(starts, ends):
max_rank = max(max_rank, adj[a] + adj[b] - 1)
return max_rank

Related

Goldbach graph using sagemath

I'm learning SageMath (uses Python 3)
and playing with the Goldbach conjecture.
I wrote this function (it works!):
def Goldbach(n):
if n % 2 != 0 or n <= 2:
show("No és parell")
else:
for i in srange(n):
if is_prime(i):
for j in srange(n):
if is_prime(j) and i + j == n:
a = [i, j]
show(a)
return
Now I'm trying (no idea) to do the following plot:
Denoting by r(2k) the number of Goldbach partitions of 2k,
the conjecture affirms that r(2k) > 0 if k > 1.
I have to do a graph of points (k, r(2k)), k > 2.
How could I do it?
First of all, let us get some better implementation in Sage
of the routine counting the number r(K) (for K > 2 some even integer) of the solutions for p + q = 2k, p, q prime numbers.
We count both solutions (p, q) and (q, p) when they differ.
def r(K):
if K not in ZZ or K <= 2 or K % 2:
return None
if K == 4:
return 1
count = 0
for p in primes(3, K):
for q in primes(3, K + 1 - p):
if p + q == K:
count += 1
return count
goldbach_points = [(K, r(K)) for K in range(4, 100,2)]
show(points(goldbach_points))
This gives:

Counting how many times an equation is true for items from an array

I have an array containing integers from 1 to 1000. I'm trying to count how many times this equation is true A + B + C + D = E where A <= B <= C <= D and A, B, C, D, E are all items from the array. Could you guys suggest any solutions?
The array contains all integers from 1 to 1000, so 1, 2, 3, 4, .. , 999, 1000. The numbers A - D can be the same number from the array.
You need to calculate number of integer partitions for every value E in range 1..1000 into 4 parts.
Python function countparts to calculate number of such partitions.
def cp(n, k, m):
if k == 0:
if n == 0:
return 1
else:
return 0
res = 0
for i in range(min(n + 1, m + 1)):
res += cp(n - i, k - 1, i)
return res
def countparts(n, k):
return cp(n - k, k, n - k + 1)
print(countparts(8, 4))
>> 5 (1115, 1124, 1133, 1223, 2222)
But it works slowly for large arguments.
Also at this page I found formula to get needed values fast:
P(i) = round((i**3 + 3*i*i - 9*i*(i % 2))/144)

Graphmath.Vector2 get nearest from a list of vectors

I'm actually using Graphmath.Vector2.near(a, b, r) to detect if 2 vectors are in range.
What if i've got a list of b and i need to fetch 5 closest vectors to a?
That module doesn't export any distance calculation function but it's trivial to recreate:
def distance({x, y}, {u, v}) do
dx = x - u
dy = y - v
:math.sqrt(dx * dx + dy * dy)
end
Now you can sort a list by its distance to the point and take the first 5 like this:
point = {1, 2}
list = [{3, 4}, {5, 6}, ...]
nearest =
list
|> Enum.sort_by(&distance(&1, point))
|> Enum.take(5)

ZeroDivisionError: Inverse does not exist

The problem is 2 is non invertible at Integer Mode Ring (6). I would like to divide the result into 2 as an ordinary integer. In another word, I like to escape from integer mode ring's trap and bring the result to ordinary integer and then divide it into 2.
def fast_exponentiation(c, L, q):
Zq = IntegerModRing(q) # create Z_q
g2 = c
result = 1
while True:
y = L % 2
result = Zq(result) * Zq(g2 ** y)
g2 = Zq(g2 * g2)
L = L >> 1
if L == 0:
break
return result
e = fast_exponentiation(2, 4, 6)
print e / 2
If you want to turn e into an Integer again, you have a few options: call Integer (the target object), or ZZ or IntegerRing, the target parent.
sage: e
1
sage: parent(e)
Ring of integers modulo 6
sage: ZZ(e)
1
sage: parent(ZZ(e))
Integer Ring
And so:
sage: e = ZZ(e)
sage: e/2
1/2
sage: e//2
0
or whatever else you'd like.

how to compute the original vector from a distance matrix?

I have a small question about vector and matrix.
Suppose a vector V = {v1, v2, ..., vn}. I generate a n-by-n distance matrix M defined as:
M_ij = | v_i - v_j | such that i,j belong to [1, n].
That is, each element M_ij in the square matrix is the absolute distance of two elements in V.
For example, I have a vector V = {1, 3, 3, 5}, the distance matrix will be
M=[
0 2 2 4;
2 0 0 2;
2 0 0 2;
4 2 2 0; ]
It seems pretty simple. Now comes to the question. Given such a matrix M, how to obtain the initial V?
Thank you.
Based on some answer for this question, it seems that the answer is not unique. So, now suppose that all the initial vector has been normalized to 0 mean and 1 variance. The question is: Given such a symmetric distance matrix M, how to decide the initial normalized vector?
You can't. To give you an idea of why, consider these two cases:
V1 = {1,2,3}
M1 = [ 0 1 2 ; 1 0 1 ; 2 1 0 ]
V2 = {3,4,5}
M2 = [ 0 1 2 ; 1 0 1 ; 2 1 0 ]
As you can see, a single M could be the result of more than one V. Therefore, you can't map backwards.
There is no way to determine the answer uniquely, since the distance matrix is invariant to adding a constant to all elements and to multiplying all the values by -1. Assuming that element 1 is equal to 0, and that the first nonzero element is positive, however, you can find an answer. Here is the pseudocode:
# Assume v[1] is 0
v[1] = 0
# e is value of first non-zero vector element
e = 0
# ei is index of first non-zero vector element
ei = 0
for i = 2...n:
# if all vector elements have been 0 so far
if e == 0:
# get the current distance from element 1 and its index
# this new element may still be 0
e = d[1,i]
ei = i
v[i] = e
elseif d[1,i] == d[ei,i] + v[ei]: # v[i] <= v[1]
# v[i] is to the left of v[1] (assuming v[ei] > v[1])
v[i] = -d[1,i]
else:
# some other case; v[i] is to the right of v[1]
v[i] = d[1,i]
I don't think it is possible to find the original vector, but you can find a translation of the vector by taking the first row of the matrix.
If you let M_ij = | v_i - v_j | and you translate all v_k for k\in [1,n] you will get
M_ij = | v-i + 1 - v_j + 1 |
= | v_i - v_j |
Hence, just take the first row as the vector and find one initial point to translate the vector to.
Correction:
Let v_1 = 0, and let l_k = | v_k | for k\in [2,n] and p_k the parity of v_k
Let p_1 = 1
for(int i = 2; i < n; i++)
if( | l_i - l_(i+1) | != M_i(i+1) )
p_(i+1) = - p_i
else
p_(i+1) = p_i
doing this for all v_k for k\in [2,n] in order will show the parity of each v_k in respect to the others
Then you can find a translation of the original vector with the same or opposite direction
Update (For Normalized vector):
Let d = Sqrt(v_1^2 + v_2^2 + ... + v_n^2)
Vector = {0, v_1 / d, v_2 / d, ... , v_n / d}
or
{0, -v_1 / d, -v_2 / d, ... , -v_n / d}

Resources