Creating adjacency list from 2D array of ints - breadth-first-search

I have run in to a roadblock when writing an algorithm to find:
a) the shortest bus route and
b) the route with the least switches.
I need to use BFS to solve it, but we are not given an adjacency list for each vertex, so I am confused as to how to make the adjacency list out of a 2D array of Integers, where each number represents a bus stop, and each row is its own route:
So, [1 2 3 4 5] is Route 1,
[6 7] is Route 2 etc.
Also, the first station of each route is the next station
the bus will reach from the last station of the route,
so each route goes in circles:
1 -> 2 -> 3 -> 4 -> 5 -> 1 -> 2 -> ...
1 2 3 4 5
6 7
8 7 4
2 6
So far what I have is this:
public void fillAdjacencyList(int[][] routes){
for(int i=0; i<routes.length; i++){
for(int j=0; j<routes[i].length; j++){
if(this.stop==routes[i][routes[i].length-1]){
BusStop temp=new BusStop(routes[i][0]);
this.next.add(temp);
}else{
if(routes[i][j]==this.stop){
BusStop temp=new BusStop(routes[i][j+1]);
this.next.add(temp);
}
}
}
}
this.visited='*';
}
The first vertex is initialized when i read the starting point from where I need to find the shortest bus route. Each vertex is defined as:
int stop;
ArrayList<BusStop> next;
char visited;
char created;
int[] line;
public BusStop(int st){
this.stop=st;
this.created='*';
}

The Python function below does the job. I made it in python so it's less verbose and (hopefully) easier to understand
def to_adj(routes):
adj = { }
for route in routes:
for stop in route:
if stop not in adj:
adj[stop] = []
for i in range(len(route)):
adj[route[i]].append(route[(i+1) % len(route)])
return adj

Related

How can I generate a unique, predictable, repeatable, non sequential alphanumeric identifier?

I have to generate identifiers composed of four alphanumerical characters, e.g. B41F.
I have the following requirements:
Each identifier must be unique (there is no central location to lookup existing identifiers)
The identifier must not be obviously sequential (e.g. 1A01, 1A02)
It must be predictable
It must be repeatable using solely the identifier index (on two different environment, the Nth identifier generated, which has index N, must be the same)
The problem is generic to any language. My implementation will be done in dart.
I think this could be done with a PRNG and some LUT, but I could not find any implementation or pseudo-code that respects requirement 4) without replaying the whole sequence. Also, some PRNG implementation have a random component that is not guaranteed to be repeatable over library update.
How can I achieve this? I'm looking for pseudo-code, code or hints.
You should not use a PRNG when identifiers must be unique. RNGs do not promise uniqueness. Some might have a long period before they repeat, but that's at their full bit-range, reducing it to a smaller number may cause conflicts earlier.
Your identifiers are really just numbers in base 36, so you need something like shuffle(index).toRadixString(36) to generate it.
The tricky bit is the shuffle function which must be a permutations of the numbers 0..36^4-1, one which looks random (non-sequential), but can be computed (efficiently?) for any input.
Since 36^4 is not a power of 2, most of the easy bit-shuffles likely won't work.
If you can live with 32^4 numbers only (2^20 ~ 1M) it might be easier.
Then you can also choose to drop O, I, 0 and 1 from the result, which might make it easier to read.
In that case, I'd do something primitive (not cryptographically secure at all), like:
// Represent 20-bit numbers
String represent(int index) {
RangeError.checkValueInInterval(index, 0, 0xFFFFF, "index");
var digits = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
return "${digits[(index >> 15) & 31]}${digits[(index >> 10) & 31]}"
"${digits[(index >> 5) & 31]}${digits[index & 31]}";
}
// Completely naive number shuffler for 20-bit numbers.
// All numbers made up on the spot.
int shuffle(int index) {
RangeError.checkValueInInterval(index, 0, 0xFFFFF, "index");
index ^= 0x35712;
index ^= index << 15;
index ^= index << 4;
index ^= index << 12;
index ^= index << 7;
index ^= index << 17;
return index & 0xFFFFF; // 20 bit only.
}
If you really want the full 36^4 range to be used, I'd probably do something like the shuffle, but in base-six arithmetic. Maybe:
String represent(int index) =>
RangeError.checkValueInInterval(index, 0, 1679615, "index")
.toRadixString(36).toUpperCase();
int shuffle(int index) {
RangeError.checkValueInInterval(index, 0, 1679615, "index");
const seed = [1, 4, 2, 5, 0, 3, 1, 4]; // seed.
var digits = List<int>.filled(8, 0);
for (var i = 0; i < 8; i++) {
digits[i] = index.remainder(6);
index = index ~/ 6;
}
void shiftAdd(List<int> source, int shift, int times) {
for (var n = digits.length - 1 - shift; n >= 0; n--) {
digits[shift + n] = (digits[shift + n] + source[n] * times).remainder(6);
}
}
shiftAdd(seed, 0, 1);
shiftAdd(digits, 3, 2);
shiftAdd(digits, 5, 1);
shiftAdd(digits, 2, 5);
var result = 0;
for (var i = digits.length - 1; i >= 0; i--) {
result = result * 6 + digits[i];
}
return result;
}
Again, this is something I made up on the spot, it "shuffles", but does not promise anything about the properties of the result, other than that they don't look sequential.

SystemVerilog constraint for mapping between two 2D arrays

There are two MxN 2D arrays:
rand bit [M-1:0] src [N-1:0];
rand bit [M-1:0] dst [N-1:0];
Both of them will be randomized separately so that they both have P number of 1'b1 in them and rest are 1'b0.
A third MxN array of integers named 'map' establishes a one to one mapping between the two arrays 'src' and 'dst'.
rand int [M-1:0] map [N-1:0];
Need a constraint for 'map' such that after randomization, for each element of src[i][j] where src[i][j] == 1'b1, map[i][j] == M*k+l when dst[k][l] == 1. The k and l must be unique for each non-zero element of map.
To give an example:
Let M = 3 and N = 2.
Let src be
[1 0 1
0 1 0]
Let dst be
[0 1 1
1 0 0]
Then one possible randomization of 'map' will be:
[3 0 1
0 2 0]
In the above map:
3 indicates pointing from src[0,0] to dst[1,0] (3 = 1*M+0)
1 indicates pointing from src[0,2] to dst[0,1] (1 = 0*M+1)
2 indicates pointing from src[1,1] to dst[0,2] (2 = 0*M+2)
This is very difficult to express as a SystemVerilog constraint because
there is no way to conditionally select elements of an array to be unique
You cannot have random variables as part of index expression to an array element.
Since you are randomizing src and dst separately, it might be easier to compute the pointers and then randomly choose the pointers to fill in the map.
module top;
parameter M=3,N=4,P=4;
bit [M-1:0] src [N];
bit [M-1:0] dst [N];
int map [N][M];
int pointers[$];
initial begin
assert( randomize(src) with {src.sum() with ($countones(item)) == P;} );
assert( randomize(dst) with {dst.sum() with ($countones(item)) == P;} );
foreach(dst[K,L]) if (dst[K][L]) pointers.push_back(K*M+L);
pointers.shuffle();
foreach(map[I,J]) map[I][J] = pointers.pop_back();
$displayb("%p\n%p",src,dst);
$display("%p",map);
end
endmodule

Multiplying a vector component with an array in ArrayFire

I'm getting an error while trying to multiply a vector component with an array (element-wise multiplication or broadcast). The docs show that this overloaded case for * should be fine:
AFAPI array operator* (const float &lhs, const array &rhs)
Multiplies two arrays or an array and a value. (const array&, const
array&)
But according to the error message below, perhaps vect(0) needs to be further flattened or reduced so that the sizes are consistent?
The error statement is clear:
Invalid dimension for argument 1 Expected: ldims == rides
Below is the code:
#include <arrayfire.h>
int main(int argc, char *argv[])
{
int device = argc > 1 ? atoi(argv[1]) : 0;
af::setDevice(device);
af::info();
int n = 3;
int N = 5;
// Create the arrays:
af::array matrix = af::constant(0,n,n,f32); // 3 x 3 float array of zeros
af::array vect = af::seq(1,N); // A col vector of floats: {1.0, ... ,5.0}
// Show the arrays:
af_print(matrix);
af_print(vect);
// Print a single component of the vector:
af_print(vect(0));
// This line produces the error (see below):
af_print(vect(0) * matrix); // Why doesn't this work?
// But somthing like this is fine:
af_print(1.0 * matrix);
return 0;
}
Producing the output:
ArrayFire v3.3.2
ATI Radeon HD 6750M
matrix [3 3 1 1]
0.0000 0.0000 0.0000
0.0000 0.0000 0.0000
0.0000 0.0000 0.0000
vect [5 1 1 1]
1.0000
2.0000
3.0000
4.0000
5.0000
vect(0) [1 1 1 1]
1.0000
The dims() output of af_print() for the matrix = [3 3 1 1], and vect(0) = [1 1 1 1], make me suspicious, but I'm not sure how to flatten further. One would think this example to be a common way of using the ArrayFire API.
The error exception that is thrown is:
libc++abi.dylib: terminating with uncaught exception of type
af::exception: ArrayFire Exception (Invalid input size:203): In
function getOutDims In file src/backend/ArrayInfo.cpp:173
Invalid dimension for argument 1 Expected: ldims == rides
In function af::array af::operator*(const af::array &, const af::array
&)
Adding a use-case to clarify:
In practice I am constructing a final array by summation of coeff(k) * (a 2-d slice of a 3-d array Z):
for (int j = 0; j<indx.dims(0); ++j)
final += coeff(indx(j)) * Z(af::span,af::span,indx(j));
I'll look into using a gfor but initially just wanted to get the correct numerical output. Note also that the vector: index is predefined, e.g., say index = {1, 2, 4, 7, ...} and the elements are not necessarily in sequence; this allows the selection of specific terms.
ArrayFire does not implicitly do vector array-scalar array element-wise operation (the case you say is failing). Only vector array-value ones are supported implicitly.
To do what you are doing, you will need to use the tile() function as shown below.
af_print(tile(vect(0), matrix.dims()) * matrix);
Since the dimension being tiled is 1, tile will be used as a JIT function. There is no extra memory used here. The entire computation is done in a single kernel. Hence no performance hit either.
Since OP added a usecase since the last answer, this is how you write a fully vectorized version in arrayfire.
array coeffs = moddims(coeff(indx), 1, 1, coeff.elements());
array final = sum(Z(span, span, indx) * tile(coeffs, Z.dims(0), Z.dims(1)), 2);

Golden Ratio Fibonacci Hell

In one of my java programs I am trying to read a number and then use the golden ratio (1.618034) to find the next smallest fibonacci number its index. For example, if I enter 100000 I should get back "the smallest fibonacci number which is greater than 100000 is the 26th and its value is 121393".
The program should also calculate a fibonacci number by index (case 1 in the code below) which I have coded so far, but I can't figure out how to solve the problem described above (case 2). I have a horrible teacher and I don't really understand what I need to do. I am not asking for the code, just kind of a step by step what I should do for case 2. I can not use recursion. Thank you for any help. I seriously suck at wrapping my head around this.
import java.util.Scanner;
public class Fibonacci {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
System.out.println("This is a Fibonacci sequence generator");
System.out.println("Choose what you would like to do");
System.out.println("1. Find the nth Fibonacci number");
System.out.println("2. Find the smallest Fibonacci number that exceeds user given value");
System.out.println("3. Find the two Fibonacci numbers whose ratio is close enough to the golden number");
System.out.print("Enter your choice: ");
int choice = scan.nextInt();
int xPre = 0;
int xCurr = 1;
int xNew = 0;
switch (choice)
{
case 1:
System.out.print("Enter the target index to generate (>1): ");
int index = scan.nextInt();
for (int i = 2; i <= index; i++)
{
xNew = xPre + xCurr;
xPre = xCurr;
xCurr = xNew;
}
System.out.println("The " + index + "th number Fibonacci number is " + xNew);
break;
case 2:
System.out.print("Enter the target value (>1): ");
int value = scan.nextInt();
}
}
}
First, you should understand what this golden ration story is all about. The point is, Fibonacci numbers can be calced recursively, but there's also a formula for the nth Fibonacci number:
φ(n) = [φ^n - (-φ)^(-n)]/√5
where φ = (√5 + 1)/2 is the Golden Ratio (approximately 1.61803). Now, |(-φ)^(-1)| < 1 which means that you can calc φ(n) as the closest integer to φ^n/√5 (unless n = 1).
So, calc √5, calc φ, then learn how to get an integer closest to the value of a real variable and then calc φ(n) using the φ^n/√5 formula (or just use the "main" [φ^n - (-φ)^(-n)]/√5 formula) in a loop and in that loop compare φ(n) with the number that user input. When φ(n) exceeds the user's number, remember n and φ(n).

Scaling a number between two values

If I am given a floating point number but do not know beforehand what range the number will be in, is it possible to scale that number in some meaningful way to be in another range? I am thinking of checking to see if the number is in the range 0<=x<=1 and if not scale it to that range and then scale it to my final range. This previous post provides some good information, but it assumes the range of the original number is known beforehand.
You can't scale a number in a range if you don't know the range.
Maybe what you're looking for is the modulo operator. Modulo is basically the remainder of division, the operator in most languages is is %.
0 % 5 == 0
1 % 5 == 1
2 % 5 == 2
3 % 5 == 3
4 % 5 == 4
5 % 5 == 0
6 % 5 == 1
7 % 5 == 2
...
Sure it is not possible. You can define range and ignore all extrinsic values. Or, you can collect statistics to find range in run time (i.e. via histogram analysis).
Is it really about image processing? There are lots of related problems in image segmentation field.
You want to scale a single random floating point number to be between 0 and 1, but you don't know the range of the number?
What should 99.001 be scaled to? If the range of the random number was [99, 100], then our scaled-number should be pretty close to 0. If the range of the random number was [0, 100], then our scaled-number should be pretty close to 1.
In the real world, you always have some sort of information about the range (either the range itself, or how wide it is). Without further info, the answer is "No, it can't be done."
I think the best you can do is something like this:
int scale(x) {
if (x < -1) return 1 / x - 2;
if (x > 1) return 2 - 1 / x;
return x;
}
This function is monotonic, and has a range of -2 to 2, but it's not strictly a scaling.
I am assuming that you have the result of some 2-dimensional measurements and want to display them in color or grayscale. For that, I would first want to find the maximum and minimum and then scale between these two values.
static double[][] scale(double[][] in, double outMin, double outMax) {
double inMin = Double.POSITIVE_INFINITY;
double inMax = Double.NEGATIVE_INFINITY;
for (double[] inRow : in) {
for (double d : inRow) {
if (d < inMin)
inMin = d;
if (d > inMax)
inMax = d;
}
}
double inRange = inMax - inMin;
double outRange = outMax - outMin;
double[][] out = new double[in.length][in[0].length];
for (double[] inRow : in) {
double[] outRow = new double[inRow.length];
for (int j = 0; j < inRow.length; j++) {
double normalized = (inRow[j] - inMin) / inRange; // 0 .. 1
outRow[j] = outMin + normalized * outRange;
}
}
return out;
}
This code is untested and just shows the general idea. It further assumes that all your input data is in a "reasonable" range, away from infinity and NaN.

Resources