How do i do a recalculate algorithm in octave - matrix

i have to choose a random column in a random matrix , but sometimes the programs pick a random number that is bigger than the size of the matrix.
n = 3 + (10-3)*rand(1,1);
t = round(n);
x = randi(t,t);
u = 3 + (10-3)*rand(1,1);
f = round(u);
if f < n & f ~= 0
for k = 1:t
e(k,1) = x(k,f);
end
end
So i used a if to solve that problem ,but i dont know how to recalculate a random number when the proposition f < n & f ~= 0 is false. Please Help

Not 100% this is what you're trying to do, but:
t = randi( [3,10], 1 ); % select a random number 't' in the range 3:10
x = randi( t, t ); % create a t-by-t matrix of random values in the range 1:t
r = randi( t ); % select a random number in the range 1:t
c = x(:,r) % select the rth column from 'x'

Related

Find second minimum for each row of a matrix

I have a set i of customers and a set j of facilities. I have two binary variables: y ij which is 1 if client i is served by a primary facility, 0 otherwise; b ij is 1 if client i is served by a backup facility, 0 otherwise.
Given the starting matrix d:
-I must set y[i,j] = 1 based on the minimum distance of each row in the matrix (and this I have done);
I have to fix b[i,j] = 1 according to the second minimum distance of each row in the matrix (I don't know how to do this. I wrote max, but I don't have to do that). I've tried removing the first minimum from each row with the various pop, deleteat, splice, etc, but the solver gives me an error.
using JuMP
using Gurobi
using DelimitedFiles
import Random
import LinearAlgebra
import Plots
n = 3
m = 5
model = Model(Gurobi.Optimizer);
#variable(model, y[1:m,1:n] >= 0, Bin);
#variable(model, b[1:m,1:n] >= 0, Bin);
d = [
[80 20 40]
[71 55 24]
[56 47 81]
[10 20 30]
[31 41 21]
];
#PRIMARY ASSIGNMENTS
# 1) For each customer find the minimum d i-j and its position in matrix and create a vector V composed by all d i-j just founded
V = [];
for i = 1:m;
c = findmin(d[i,j] for j = 1:n);
push!(V,[c[1] ,c[2], i]);
end
println(V)
# 2) Sort vector's evelements from the smallest to the largest
S = sort(V)
println(S)
for i = 1:m
println(S[i][2])
println(S[i][3])
end
# 3) Fix primary assingnments for the first 50% of customers
for i = 1:3
fix(y[S[i][3], S[i][2]], 1.0, force = true);
end
# SECONDARY ASSIGNMENTS
# 1) For each customer find the second minimum d i-j and its position in matrix and create a vector W composed by all d i-j just founded
W = [];
for i = 1:m;
f = findmax(d[i,j] for j = 1:n);
push!(W,[f[1] ,f[2], i]);
end
println(W)
# 2) Sort vector's elements from the smallest to the largest
T = sort(W)
println(T)
for i = 1:3
println(T[i][2])
println(T[i][3])
end
# 3) Fix secondary assingnments for the first 50% of customers
for i = 1:3
fix(b[T[i][3], T[i][2]], 1.0, force = true);
end
optimize!(model)
I tried to find for each line the second minimum, but I could not.

Number of N-digit numbers that are divisible by given two numbers

One of my friends got this question in google coding contest. Here goes the question.
Find the number of N-digit numbers that are divisible by both X and Y.
Since the answer can be very large, print the answer modulo 10^9 + 7.
Note: 0 is not considered single-digit number.
Input: N, X, Y.
Constraints:
1 <= N <= 10000
1 <= X,Y <= 20
Eg-1 :
N = 2, X = 5, Y = 7
output : 2 (35 and 70 are the required numbers)
Eg-2 :
N = 1, X = 2, Y = 3
output : 1 (6 is the required number)
If the constraints on N were smaller, then it would be easy (ans = 10^N / LCM(X,Y) - 10^(N-1) / LCM(X,Y)).
But N is upto 1000, hence I am unable to solve it.
This question looks like it was intended to be more difficult, but I would do it pretty much the way you said:
ans = floor((10N-1)/LCM(X,Y)) - floor((10N-1-1)/LCM(X,Y))
The trick is to calculate the terms quickly.
Let M = LCM(X,Y), and say we have:
10a = Mqa + ra, and
10b = Mqb + rb
The we can easily calculate:
10a+b = M(Mqaqb + raqb + rbqa + floor(rarb/M)) + (rarb%M)
With that formula, we can calculate the quotient and remainder for 10N/M in just 2 log N steps using exponentiation by squaring: https://en.wikipedia.org/wiki/Exponentiation_by_squaring
Following python works for this question ,
import math
MOD = 1000000007
def sub(x,y):
return (x-y+MOD)%MOD
def mul(x,y):
return (x*y)%MOD
def power(x,y):
res = 1
x%=MOD
while y!=0:
if y&1 :
res = mul(res,x)
y>>=1
x = mul(x,x)
return res
def mod_inv(n):
return power(n,MOD-2)
x,y = [int(i) for i in input().split()]
m = math.lcm(x,y)
n = int(input())
a = -1
b = -1
total = 1
for i in range(n-1):
total = (total * 10)%m
b = total % m
total = (total*10)%m
a = total % m
l = power(10 , n-1)
r = power(10 , n)
ans = sub( sub(r , l) , sub(a,b) )
ans = mul(ans , mod_inv(m))
print(ans)
Approach for this question is pretty straight forward,
let, m = lcm(x,y)
let,
10^n -1 = m*x + a
10^(n-1) -1 = m*y + b
now from above two equations it is clear that our answer is equal to
(x - y)%MOD .
so,
(x-y) = ((10^n - 10^(n-1)) - (a-b)) / m
also , a = (10^n)%m and b = (10^(n-1))%m
using simple modular arithmetic rules we can easily calculate a and b in O(n) time.
also for subtraction and division performed in the formula we can use modular subtraction and division respectively.
Note: (a/b)%MOD = ( a * (mod_inverse(b, MOD)%MOD )%MOD

Speeding up program in matlab

I have 2 functions:
ccexpan - which calculates coefficients of interpolating polynomial of function f with N nodes in Chebyshew polynomial of the first kind basis.
csum - calculates value for arguments t using coefficients c from ccexpan (using Clenshaw algorithm).
This is what I have written so far:
function c = ccexpan(f,N)
z = zeros (1,N+1);
s = zeros (1,N+1);
for i = 1:(N+1)
z(i) = pi*(i-1)/N;
end
t = f(cos(z));
for k = 1:(N+1)
s(k) = sum(t.*cos(z.*(k-1)));
s(k) = s(k)-(f(1)+f(-1)*cos(pi*(k-1)))/2;
end
c = s.*2/N;
and:
function y = csum(t,c)
M = length(t);
N = length(c);
y = t;
b = zeros(1,N+2);
for k = 1:M
for i = N:-1:1
b(i) = c(i)+2*t(k)*b(i+1)-b(i+2);
end
y(k)=(b(1)-b(3))/2;
end
Unfortunately these programs are very slow, and also slightly inacurrate. Please give me some tips on how to speed them up, and how to improve accuracy.
Where possible try to get away from looping structures. At first blush, I would trade out your first for loop of
for i = 1:(N+1)
z(i) = pi*(i-1)/N;
end
and replace with
i=1:(N+1)
z = pi*(i-1)/N
I did not check the rest of you code but the above example will definitely speed up you code. And a second strategy is to combine loops when possible.
Martin,
Consider the following strategy.
% create hypothetical N and f
N = 3
f = #(x) 1./(1+15*x.*x)
% calculate z and t
i=1:(N+1)
z = pi*(i-1)/N
t = f(cos(z))
% make a column vector of k's
k = (1:(N+1))'
% do this: s(k) = sum(t.*cos(z.*(k-1)))
s1 = t.*cos(z.*(k-1)) % should be a matrix with one row for each row of k
% via implicit expansion
s2 = sum(s1,2) % row sum, i.e., one value for each row of k
% do this: s(k) = s(k)-(f(1)+f(-1)*cos(pi*(k-1)))/2
s3 = s2 - (f(1)+f(-1)*cos(pi*(k-1)))/2
% calculate c
c = s3 .* 2/N

What kind of algorithm would find a grid of squares in a reasonable time?

I found a result that there is a grid of size 9x13 with following properties:
Every cell contains a digit in base 10.
One can read the numbers from the grid by selecting a starting square, go to one of its 8 nearest grid, maintain that direction and concatenate numbers.
For example, if we have the following grid:
340934433
324324893
455423343
Then one can select the leftmost upper number 3 and select direction to the right and down to read numbers 3, 32 and 325.
Now one has to prove that there is a grid of size 9x13 where one can read the squares of 1 to 100, i.e. one can read all of the integers of the form i^2 where i=1,...,100 from the square.
The best grid I found on the net is of size 11x11, given in Solving a recreational square packing problem . But it looks like it is hard to modify the program to find integers in rectangular grid.
So what kind of algorithm would output a suitable grid in a reasonable time?
I just got a key error from this code:
import random, time, sys
N = 9
M = 13
K = 100
# These are the numbers we would like to pack
numbers = [str(i*i) for i in xrange(1, K+1)]
# Build the global list of digits (used for weighted random guess)
digits = "".join(numbers)
def random_digit(n=len(digits)-1):
return digits[random.randint(0, n)]
# By how many lines each of the numbers is currently covered
count = dict((x, 0) for x in numbers)
# Number of actually covered numbers
covered = 0
# All lines in current position (row, cols, diags, counter-diags)
lines = (["*"*N for x in xrange(N)] +
["*"*M for x in xrange(M)] +
["*"*x for x in xrange(1, N)] + ["*"*x for x in xrange(N, 0, -1)] +
["*"*x for x in xrange(1, M)] + ["*"*x for x in xrange(M, 0, -1)])
# lines_of[x, y] -> list of line/char indexes
lines_of = {}
def add_line_of(x, y, L):
try:
lines_of[x, y].append(L)
except KeyError:
lines_of[x, y] = [L]
for y in xrange(N):
for x in xrange(N):
add_line_of(x, y, (y, x))
add_line_of(x, y, (M + x, y))
add_line_of(x, y, (2*M + (x + y), x - max(0, x + y - M + 1)))
add_line_of(x, y, (2*M + 2*N-1 + (x + N-1 - y), x - max(0, x + (M-1 - y) - M + 1)))
# Numbers covered by each line
covered_numbers = [set() for x in xrange(len(lines))]
# Which numbers the string x covers
def cover(x):
c = x + "/" + x[::-1]
return [y for y in numbers if y in c]
# Set a matrix element
def setValue(x, y, d):
global covered
for i, j in lines_of[x, y]:
L = lines[i]
C = covered_numbers[i]
newL = L[:j] + d + L[j+1:]
newC = set(cover(newL))
for lost in C - newC:
count[lost] -= 1
if count[lost] == 0:
covered -= 1
for gained in newC - C:
count[gained] += 1
if count[gained] == 1:
covered += 1
covered_numbers[i] = newC
lines[i] = newL
def do_search(k, r):
start = time.time()
for i in xrange(r):
x = random.randint(0, N-1)
y = random.randint(0, M-1)
setValue(x, y, random_digit())
best = None
attempts = k
while attempts > 0:
attempts -= 1
old = []
for ch in xrange(1):
x = random.randint(0, N-1)
y = random.randint(0, M-1)
old.append((x, y, lines[y][x]))
setValue(x, y, random_digit())
if best is None or covered > best[0]:
now = time.time()
sys.stdout.write(str(covered) + chr(13))
sys.stdout.flush()
attempts = k
if best is None or covered >= best[0]:
best = [covered, lines[:N][:]]
else:
for x, y, o in old[::-1]:
setValue(x, y, o)
print
sys.stdout.flush()
return best
for y in xrange(N):
for x in xrange(N):
setValue(x, y, random_digit())
best = None
while True:
if best is not None:
for y in xrange(M):
for x in xrange(N):
setValue(x, y, best[1][y][x])
x = do_search(100000, M)
if best is None or x[0] > best[0]:
print x[0]
print "\n".join(" ".join(y) for y in x[1])
if best is None or x[0] >= best[0]:
best = x[:]
To create such a grid, I'd start with a list of strings representing the squares of the first K (100) numbers.
Reduce those strings as much as possible, where many are contained within others (for example, 625 contains 25, so 625 covers the squares of 5 and 25).
This should yield an initial list of 81 unique squares, requiring a minimum of about 312 digits:
def construct_optimal_set(K):
# compute a minimal solution:
numbers = [str(n*n) for n in range(0,K+1)]
min_numbers = []
# note: go in reverse direction, biggest to smallest, to maximize elimination of smaller numbers later
while len(numbers) > 0:
i = 0
while i < len(min_numbers):
q = min_numbers[i]
qr = reverse(min_numbers[i])
# check if the first number is contained within any element of min_numbers
if numbers[-1] in q or numbers[-1] in qr:
break
# check if any element of min_numbers is contained within the first number
elif q in numbers[-1] or qr in numbers[-1]:
min_numbers[i] = numbers[-1]
break
i += 1
# if not found, add it
if i >= len(min_numbers):
min_numbers.append(numbers[-1])
numbers = numbers[:-1]
min_numbers.sort()
return min_numbers
This will return a minimal set of squares, with any squares that are subsets of other squares removed. Extend this by concatenating any mostly-overlapping elements (such as 484 and 841 into 4841); I leave that as an exercise, since it will build familiarity with this code.
Then, you assemble these sort of like a cross-word puzzle. As you assemble the values, pack based on probability of possible future overlaps, by computing a weight for each digit (for example, 1's are fairly common, 9's are less common, so given the choice, you would favor overlapping 9's rather than 1's).
Use something like the following code to build a list of all possible values that are represented in the current grid. Use this periodically while building, in order to eliminate squares that are already represented, as well as to test whether your grid is a full solution.
def merge(digits):
result = 0
for i in range(len(digits)-1,-1,-1):
result = result * 10 + digits[i]
return result
def merge_reverse(digits):
result = 0
for i in range(0, len(digits)):
result = result * 10 + digits[i]
return result
# given a grid where each element contains a single numeric digit,
# return list of every ordering of those digits less than SQK,
# such that you pick a starting point and one of eight directions,
# and assemble digits until either end of grid or larger than SQK;
# this will construct only the unique combinations;
# also note that this will not construct a large number of values,
# since for any given direction, there are at most
# (sqrt(n*n + m*m))!
# possible arrangements, and there will rarely be that many.
def construct_lines(grid, k):
# rather than build a dictionary type, use a little more memory to use faster simple array indexes;
# index is #, and value at index indicates existence: 0 = does not exist, >0 means exists in grid
sqk = k*k
combinations = [0]*(sqk+1)
# do all horizontals, since they are easiest
for y in range(len(grid)):
digits = []
for x in range(len(grid[y])):
digits.append(grid[y][x])
# for every possible starting point...
for q in range(1,len(digits)):
number = merge(digits[q:])
if number <= sqk:
combinations[number] += 1
# now do all verticals
# note that if the grid is really square, grid[0] will give an accurate width of all grid[y][] rows
for x in range(len(grid[0])):
digits = []
for y in range(len(grid)):
digits.append(grid[y][x])
# for every possible starting point...
for q in range(1,len(digits)):
number = merge(digits[q:])
if number <= sqk:
combinations[number] += 1
# the longer axis (x or y) in both directions will contain every possible diagonal
# e.g. x is the longer axis here (using random characters to more easily distinguish idea):
# [1 2 3 4]
# [a b c d]
# [. , $ !]
# 'a,' can be obtained by reversing the diagonal starting on the bottom and working up and to the left
# this means that every set must be reversed as well
if len(grid) > len(grid[0]):
# for each y, grab top and bottom in each of two diagonal directions, for a total of four sets,
# and include the reverse of each set
for y in range(len(grid)):
digitsul = [] # origin point upper-left, heading down and right
digitsur = [] # origin point upper-right, heading down and left
digitsll = [] # origin point lower-left, heading up and right
digitslr = [] # origin point lower-right, heading up and left
revx = len(grid[y])-1 # pre-adjust this for computing reverse x coordinate
for deltax in range(len(grid[y])): # this may go off the grid, so check bounds
if y+deltax < len(grid):
digitsul.append(grid[y+deltax][deltax])
digitsll.append(grid[y+deltax][revx - deltax])
for q in range(1,len(digitsul)):
number = merge(digitsul[q:])
if number <= sqk:
combinations[number] += 1
number = merge_reverse(digitsul[q:])
if number <= sqk:
combinations[number] += 1
for q in range(1,len(digitsll)):
number = merge(digitsll[q:])
if number <= sqk:
combinations[number] += 1
number = merge_reverse(digitsll[q:])
if number <= sqk:
combinations[number] += 1
if y-deltax >= 0:
digitsur.append(grid[y-deltax][deltax])
digitslr.append(grid[y-deltax][revx - deltax])
for q in range(1,len(digitsur)):
number = merge(digitsur[q:])
if number <= sqk:
combinations[number] += 1
number = merge_reverse(digitsur[q:])
if number <= sqk:
combinations[number] += 1
for q in range(1,len(digitslr)):
number = merge(digitslr[q:])
if number <= sqk:
combinations[number] += 1
number = merge_reverse(digitslr[q:])
if number <= sqk:
combinations[number] += 1
else:
# for each x, ditto above
for x in range(len(grid[0])):
digitsul = [] # origin point upper-left, heading down and right
digitsur = [] # origin point upper-right, heading down and left
digitsll = [] # origin point lower-left, heading up and right
digitslr = [] # origin point lower-right, heading up and left
revy = len(grid)-1 # pre-adjust this for computing reverse y coordinate
for deltay in range(len(grid)): # this may go off the grid, so check bounds
if x+deltay < len(grid[0]):
digitsul.append(grid[deltay][x+deltay])
digitsll.append(grid[revy - deltay][x+deltay])
for q in range(1,len(digitsul)):
number = merge(digitsul[q:])
if number <= sqk:
combinations[number] += 1
number = merge_reverse(digitsul[q:])
if number <= sqk:
combinations[number] += 1
for q in range(1,len(digitsll)):
number = merge(digitsll[q:])
if number <= sqk:
combinations[number] += 1
number = merge_reverse(digitsll[q:])
if number <= sqk:
combinations[number] += 1
if x-deltay >= 0:
digitsur.append(grid[deltay][x-deltay])
digitslr.append(grid[revy - deltay][x - deltay])
for q in range(1,len(digitsur)):
number = merge(digitsur[q:])
if number <= sqk:
combinations[number] += 1
number = merge_reverse(digitsur[q:])
if number <= sqk:
combinations[number] += 1
for q in range(1,len(digitslr)):
number = merge(digitslr[q:])
if number <= sqk:
combinations[number] += 1
number = merge_reverse(digitslr[q:])
if number <= sqk:
combinations[number] += 1
# now filter for squares only
return [i for i in range(0,k+1) if combinations[i*i] > 0]
Constructing the grid will be computationally expensive overall, but you will only need to run the check function once for each possible placement, to select the best placement.
Optimize placement by finding the subset of overlapping areas where you can place a sequence of numbers - this should be tolerable in terms of time required, because you can cap the number of possible locations to check; e.g. you might cap it at 10 (again, find the optimal number experimentally), such that you test the first 10 possible placements against the function above to determine which placement, if any, adds the most possible squares. As you progress, you will have fewer possible locations in which to insert the numbers, so testing which placement is best becomes computationally less expensive at the same time that your search for possible placements becomes more expensive, balancing out each other.
This will not handle all combinations, and will not pack as tightly as trying every possible arrangement and computing how many squares are covered, so some might be missed, but compared to O((N*M)!), this algorithm will actually complete in your lifetime (I'd actually estimate a few minutes on a decent computer - more if you parallelize the check for placement).

Halton sequence extension

I am trying to fill an area defined by 2 intervals [a,b] x [c,d] with points uniformly distributed and I am implementing the Halton sequence. I am using the following code (which generates subunitary numbers).
The number I is input.
The number H is output.
for i = 1:N
H = 0
half = 1 / 2
I = rand() % MATLAB rand()
do while ( I is not zero )
digit = mod ( I, 2 )
H = H + digit * half
I = ( I - digit ) / 2
half = half / 2
end
x(i) = H
end
For the x-axis I use base 2 and for the y-axis I use base 3.
Because I divide by 2, 3 I seem to be unable to fill the whole [0,1] x [0,1] space completely. I have to fill [0,1] x [0,1] and I actually fill [0,0.5] x [0,0.35]. And when I try to extend the algorithm for [a,b] x [c,d] I get points in [a,b-0.5] x [c,d-1].
What can I do to fill the correct full intervals?

Resources