How can I generate 3d integer coordinates in order of distance from an origin - coordinates

I want to generate a sequence of coordinates in order of distance from the origin. The sequence will obviously be infinite so just generating them all and sorting by distance will not work for me.
For those points that are the same distance I don't care about the order.
For example, here's some points, with their distance from the origin up to two steps away.
# d² = 0
(0,0,0)
# d² = 1
(0,0,-1)
(0,-1,0)
(-1,0,0)
(1,0,0)
(0,1,0)
(0,0,1)
# d² = 2
(0,-1,-1)
(-1,0,-1)
(1,0,-1)
(0,1,-1)
(-1,-1,0)
(1,-1,0)
(-1,1,0)
(1,1,0)
(0,-1,1)
(-1,0,1)
(1,0,1)
(0,1,1)
# d² = 3
(-1,-1,-1)
(1,-1,-1)
(-1,1,-1)
(1,1,-1)
(-1,-1,1)
(1,-1,1)
(-1,1,1)
(1,1,1)
# d² = 4
(0,0,-2)
(0,-2,0)
(-2,0,0)
(2,0,0)
(0,2,0)
(0,0,2)
# d² = 5
(0,-1,-2)
(-1,0,-2)
(1,0,-2)
(0,1,-2)
(0,-2,-1)
(-2,0,-1)
(2,0,-1)
(0,2,-1)
(-1,-2,0)
(1,-2,0)
(-2,-1,0)
(2,-1,0)
(-2,1,0)
(2,1,0)
(-1,2,0)
(1,2,0)
(0,-2,1)
(-2,0,1)
(2,0,1)
(0,2,1)
(0,-1,2)
(-1,0,2)
(1,0,2)
(0,1,2)
# d² = 6
(-1,-1,-2)
(1,-1,-2)
(-1,1,-2)
(1,1,-2)
(-1,-2,-1)
(1,-2,-1)
(-2,-1,-1)
(2,-1,-1)
(-2,1,-1)
(2,1,-1)
(-1,2,-1)
(1,2,-1)
(-1,-2,1)
(1,-2,1)
(-2,-1,1)
(2,-1,1)
(-2,1,1)
(2,1,1)
(-1,2,1)
(1,2,1)
(-1,-1,2)
(1,-1,2)
(-1,1,2)
(1,1,2)
# d² = 8
(0,-2,-2)
(-2,0,-2)
(2,0,-2)
(0,2,-2)
(-2,-2,0)
(2,-2,0)
(-2,2,0)
(2,2,0)
(0,-2,2)
(-2,0,2)
(2,0,2)
(0,2,2)
# d² = 9
(-1,-2,-2)
(1,-2,-2)
(-2,-1,-2)
(2,-1,-2)
(-2,1,-2)
(2,1,-2)
(-1,2,-2)
(1,2,-2)
(-2,-2,-1)
(2,-2,-1)
(-2,2,-1)
(2,2,-1)
(-2,-2,1)
(2,-2,1)
(-2,2,1)
(2,2,1)
(-1,-2,2)
(1,-2,2)
(-2,-1,2)
(2,-1,2)
(-2,1,2)
(2,1,2)
(-1,2,2)
(1,2,2)
# d² = 12
(-2,-2,-2)
(2,-2,-2)
(-2,2,-2)
(2,2,-2)
(-2,-2,2)
(2,-2,2)
(-2,2,2)
(2,2,2)

Starting from a solution aaa, then aab, then abc, you can retrieve all other "permutations" like aba, baa, -a-a-b, and so on. So you can keep a < b < c, positive numbers.
Geometrically : one eighth triangle on a globe. For a circle x²+y² one would iterate in a quarter over x and let y be retrieved from r² - x². Happens here to given an a.
Unfortunately the coding is too much to me for answering on a sunny Sunday.
(= hard enough).
Schematically in pseudo-code:
int distance = -1;
int a;
int b;
int c;
PermutationIterator perm = ...
Point next() {
if (perm.atEnd()) { // Initially true.
perm.nextDistance();
++distance;
a = distance;
b = a;
c = a;
// Will return Point(a, a, a);
}
return perm.nextPerm();
}

Related

route optimization with precedences between pairs of nodes

For my routing application I have multiple pairs of nodes which must be visited. The order the nodes in each pair is not important, but both nodes in each pair must be visited after each other. Also, I have a max_travel_distance constraint per vehicle and it is not required to visit all nodes if no optimal solution exist. Meaning that if one node in a pair needs to be dropped, both nodes in the pair must be dropped.
For instance I have three pairs: [A,B], [C,D], [E,F], two valid solutions for two vehicles could be:
(if all node pair can be covered)
1) 0->A->B->C->D->0
2) 0->F->E->0
or
(if only [A,B] is within max_travel_distance)
1) 0->A->B->0
2) 0->0
From the pickup and deliveries example I see how I can make sure that both nodes in a pair always is included in the solution. The problem is that I dont see how I can enforce a constraint so that the two nodes from the same pair always is visited directly after each other, and that the order does not matter (A->B and B->A are both ok)
import math
from ortools.constraint_solver import pywrapcp
from ortools.constraint_solver import routing_enums_pb2
def calc_dmat(pairs, depot = [0,0]):
# Distance matrix
ncol = len(pairs)*2
nodes = [depot] + [p for pair in Pairs for p in pair]
dmat = [[math.dist(c,r) for c in nodes] for r in nodes]
return dmat
# Nodes and pairs
A = [1,1] # Coordinate
B = [1,5]
C = [3,1]
D = [3,8]
E = [6,3]
F = [6,19]
Pairs = [
[A,B],
[C,D],
[E,F]
]
data = {}
data["distance_matrix"] = calc_dmat(Pairs)
data["depot"] = 0
data["num_vehicles"]=2
data["pickups_deliveries"] = [
[1,2],
[3,4],
[5,6]
]
def print_solution(data, manager, routing, solution):
if solution is None:
print("No solution")
return
print(f'Objective: {solution.ObjectiveValue()}')
# Display dropped nodes.
dropped_nodes = 'Dropped nodes:'
for node in range(routing.Size()):
if routing.IsStart(node) or routing.IsEnd(node):
continue
if solution.Value(routing.NextVar(node)) == node:
dropped_nodes += ' {}'.format(manager.IndexToNode(node))
print(dropped_nodes)
max_route_distance = 0
max_route_time = 0
for vehicle_id in range(data['num_vehicles']):
index = routing.Start(vehicle_id)
plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
route_distance = 0
route_time = 0
while not routing.IsEnd(index):
plan_output += ' {} -> '.format(manager.IndexToNode(index))
previous_index = index
index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(
previous_index, index, vehicle_id)
plan_output += '{}\n'.format(manager.IndexToNode(index))
plan_output += 'Distance of the route: {}m\n'.format(route_distance)
print(plan_output)
max_route_distance = max(route_distance, max_route_distance)
max_route_time = max(route_time, max_route_time)
print('Maximum of the route distances: {}m'.format(max_route_distance))
print('Maximum of the route time: {}m'.format(max_route_time))
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
data['num_vehicles'], data['depot'])
routing = pywrapcp.RoutingModel(manager)
def distance_callback(from_index, to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data["distance_matrix"][from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Add Distance constraint.
dimension_name = 'Distance'
routing.AddDimension(
transit_callback_index,
0,
18,
True,
dimension_name)
distance_dimension = routing.GetDimensionOrDie(dimension_name)
# Define Transportation Requests.
for request in data['pickups_deliveries']:
pickup_index = manager.NodeToIndex(request[0])
delivery_index = manager.NodeToIndex(request[1])
routing.AddPickupAndDelivery(pickup_index, delivery_index)
routing.solver().Add(
routing.VehicleVar(pickup_index) == routing.VehicleVar(
delivery_index))
routing.solver().Add(
distance_dimension.CumulVar(pickup_index) <=
distance_dimension.CumulVar(delivery_index))
# Omit some nodes
for node in range(1,len(data["distance_matrix"])):
routing.AddDisjunction([manager.NodeToIndex(node)], 13)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION)
# Solve the problem.
solution = routing.SolveWithParameters(search_parameters)
# Print solution on console.
print_solution(data, manager, routing, solution)
Output:
*Objective: 25
Dropped nodes:
Route for vehicle 0:
0 -> 3 -> 1 -> 2 -> 4 -> 0
Distance of the route: 9m
Route for vehicle 1:
0 -> 5 -> 6 -> 0
Distance of the route: 16m
Maximum of the route distances: 16m
Maximum of the route time: 0m*
I don't see how I can add a constraint making sure both nodes from the same node is picked successively and independently of the order. A solution to this would be highly appreciated.
Set a dimension representing rank (transit is always 1)
Link the vehicle variables of the two nodes in a pair to be equal
Add each one in a disjunction of size 1 (maybe both in a unique disjunction of size 2)
Add a precedence on the cumul variables of the 2 elements of a pair
Here is another approach.
Create 2 fake nodes 'a->b' and 'b->a', do not create the nodes a and b.
Distance from any node c to 'a->b' is distance c to a. Distance from 'a->b' to any node d is distance from b to d.
Same thing for b->a.
Add 'a->b' and 'b->a' in a disjunction.
And solve.

Unpacking a vector into an array of a certain bit width

Suppose I have a vector of bits. I'd like to convert it into an array of n bit values, where n is a variable (not a parameter). Can I achieve this using the streaming operators? I tried this (right now I'm just trying a value of 3, but eventually '3' should be variable):
module tb;
bit [51:0] vector = 'b111_110_101_100_011_010_001_000;
byte vector_byte[];
initial begin
$displayb(vector);
vector_byte = {<<3{vector}};
foreach(vector_byte[i])
$display("%0d = %0b", i, vector_byte[i]);
end
endmodule
What I was expecting was:
vector_byte = '{'b000, 'b001, 'b010 ... 'b111};
However, the output I got was:
# vsim -voptargs=+acc=npr
# run -all
# 00000000000000000000000000000000111110101100011010001000
# 0 = 101
# 1 = 111001
# 2 = 1110111
# 3 = 0
# 4 = 0
# 5 = 0
# 6 = 0
# exit
Am I just using the streaming operators wrong?
The streaming operators only work with contiguous streams. You need 5'b00000 inserted into each byte.
module tb;
bit [51:0] vector = 'b111_110_101_100_011_010_001_000;
int W = 3;
byte vector_byte[];
initial begin
vector_byte = new[$bits(vector)/3];
$displayb(vector);
foreach(vector_byte[i]) begin
vector_byte[i] = vector[i*W+:8] & (1<<W)-1; // mask W is in range 1-8
$display("%0d = %0b", i, vector_byte[i]);
end
end
endmodule

Calculating Factorials using QBasic

I'm writing a program that calculates the Factorial of 5 numbers and output the results in a Tabular form but I keep getting Zeros.
Factorial Formula:. n! = n×(n-1)!
I tried:
CLS
DIM arr(5) AS INTEGER
FOR x = 1 TO 5
INPUT "Enter Factors: ", n
NEXT x
f = 1
FOR i = 1 TO arr(n)
f = f * i
NEXT i
PRINT
PRINT "The factorial of input numbers are:";
PRINT
FOR x = 1 TO n
PRINT f(x)
NEXT x
END
and I'm expecting:
Numbers Factorrials
5 120
3 6
6 720
8 40320
4 24
You did some mistakes
FOR i = 1 TO arr(n)
where is n defined
you also never stored actual values into arr
PRINT f(x)
here you take from array f that is also not defined in your code
Possible solution to calculate arrays of factorials:
CLS
DIM arr(5) AS INTEGER
DIM ans(5) AS LONG
FOR x = 1 TO 5
INPUT "Enter Factors: ", arr(x)
f& = 1
FOR i = 1 TO arr(x)
f& = f& * i
NEXT i
ans(x) = f&
NEXT x
PRINT
PRINT "The factorial of input numbers are:";
PRINT
PRINT "Numbers", "Factorials"
FOR x = 1 TO 5
PRINT arr(x), ans(x)
NEXT x
END
I don't have a BASIC interpreter right in front of me, but I think this is what you're looking for:
CLS
DIM arr(5) AS INTEGER
DIM ans(5) AS LONG 'You need a separate array to store results in.
FOR x = 1 TO 5
INPUT "Enter Factors: ", arr(x)
NEXT x
FOR x = 1 to 5
f& = 1
FOR i = 1 TO arr(x)
f& = f& * i
NEXT i
ans(x) = f&
NEXT x
PRINT
PRINT "The factorial of input numbers are:";
PRINT
PRINT "Numbers", "Factorials"
FOR x = 1 TO 5
PRINT STR$(arr(x)), ans(x)
NEXT x
END
Just a comment though: In programming, you should avoid reusing variables unless you are short on memory. It can be done right, but it creates many opportunities for hard to find bugs in larger programs.
Possible solution to calculate arrays of factorials and square roots:
CLS
PRINT "Number of values";: INPUT n
DIM arr(n) AS INTEGER
DIM ans(n) AS LONG
FOR x = 1 TO n
PRINT "Enter value"; x;: INPUT arr(x)
f& = 1
FOR i = 1 TO arr(x)
f& = f& * i
NEXT i
ans(x) = f&
NEXT x
PRINT
PRINT "The factorial/square root of input numbers are:";
PRINT
PRINT "Number", "Factorial", "Squareroot"
FOR x = 1 TO n
PRINT arr(x), ans(x), SQR(arr(x))
NEXT x
END

Find two maximum points

I have a two arrays that I plot: A a 1x101 vector and B the same
A = [0.140673450903833 0.143148937279028 0.145430952171596 0.147474938627147 0.149581060870114 0.151187105347571 0.152646348246015 0.153892222566265 0.154913060187075 0.155701930397674 0.156253328260122 0.156562551841967 0.156625533585493 0.156438787610539 0.155999394209637 0.155304997895017 0.154353810555534 0.153144616301392 0.151676776486360 0.149950234280632 0.147965519042205 0.145723755995511 0.143229676241241 0.140476287800831 0.137475884805212 0.134228713435530 0.130738812449387 0.127010778531129 0.123049766057659 0.118861478234099 0.114452155847321 0.109828564345449 0.104997979409803 0.0999681710919947 0.0947473865690700 0.0893443315667412 0.0837681505026921 0.0780284054055798 0.0721350536699391 0.0660984247128685 0.0599291956061627 0.0536383657701255 0.0472372308396036 0.0407373558685518 0.0341505481893574 0.0274888307202605 0.0207644183921863 0.0139897104812690 0.00717740846258673 0.000358034181698980 0.00651349557333709 0.0133637955715171 0.0202018404602034 0.0270147225489001 0.0337898204971252 0.0405146415132138 0.0471768260462406 0.0537641715916784 0.0602646603043279 0.0666664873507057 0.0729580891146200 0.0791281709097673 0.0851657340195109 0.0910601019446384 0.0968009457657087 0.102378308539557 0.107782628657363 0.113004762097380 0.118036003510261 0.122868106079509 0.127493300104313 0.131904310257409 0.136094371477732 0.140057243469708 0.143787223810476 0.147279159770258 0.150528459504324 0.153531108836772 0.156280444813554 0.158783035106175 0.161027296288627 0.163014562505352 0.164743731117677 0.166214276765471 0.167426257040343 0.168380310331524 0.169077651806683 0.169520068571722 0.169709914896378 0.169650109087113 0.169344135453180 0.168796059816963 0.168010582212876 0.166993205517562 0.165750858213848 0.164295206012858 0.162692813100379 0.160590402150861 0.158550181408264 0.156271984944015 0.153800366335689]
B = [-2 -1.96000000000000 -1.92000000000000 -1.88000000000000 -1.84000000000000 -1.80000000000000 -1.76000000000000 -1.72000000000000 -1.68000000000000 -1.64000000000000 -1.60000000000000 -1.56000000000000 -1.52000000000000 -1.48000000000000 -1.44000000000000 -1.40000000000000 -1.36000000000000 -1.32000000000000 -1.28000000000000 -1.24000000000000 -1.20000000000000 -1.16000000000000 -1.12000000000000 -1.08000000000000 -1.04000000000000 -1 -0.960000000000000 -0.920000000000000 -0.880000000000000 -0.840000000000000 -0.800000000000000 -0.760000000000000 -0.720000000000000 -0.680000000000000 -0.640000000000000 -0.600000000000000 -0.560000000000000 -0.520000000000000 -0.480000000000000 -0.440000000000000 -0.400000000000000 -0.360000000000000 -0.320000000000000 -0.280000000000000 -0.240000000000000 -0.200000000000000 -0.160000000000000 -0.120000000000000 -0.0800000000000001 -0.0400000000000000 0 0.0400000000000000 0.0800000000000001 0.120000000000000 0.160000000000000 0.200000000000000 0.240000000000000 0.280000000000000 0.320000000000000 0.360000000000000 0.400000000000000 0.440000000000000 0.480000000000000 0.520000000000000 0.560000000000000 0.600000000000000 0.640000000000000 0.680000000000000 0.720000000000000 0.760000000000000 0.800000000000000 0.840000000000000 0.880000000000000 0.920000000000000 0.960000000000000 1 1.04000000000000 1.08000000000000 1.12000000000000 1.16000000000000 1.20000000000000 1.24000000000000 1.28000000000000 1.32000000000000 1.36000000000000 1.40000000000000 1.44000000000000 1.48000000000000 1.52000000000000 1.56000000000000 1.60000000000000 1.64000000000000 1.68000000000000 1.72000000000000 1.76000000000000 1.80000000000000 1.84000000000000 1.88000000000000 1.92000000000000 1.96000000000000 2];
Plotting these two plot(B,A) I get this
with two maximum points at B = -1.52 and B = +1.52
I want to add automatically a point as marker in the two maximum values, a horizontal line above the highest point and a two way row pointing from the line to the second peak like this
I tried to sort A and find the position of the two maximum
[val ind] = sort(A,'descend');
max_values = val(1:2)
index = ind(1:2)
r_max = A(ind(1:2))
but the second peak is not the the second position of val because I get this sort:
Columns 1 through 13
0.1697 0.1697 0.1695 0.1693 0.1691 0.1688 0.1684 0.1680 0.1674 0.1670 0.1662 0.1658 0.1647
Columns 14 through 26
0.1643 0.1630 0.1627 0.1610 0.1606 0.1588 0.1586 0.1566 0.1566 0.1564 0.1563 0.1563 0.1563
The first value 0.1697 (in this case) is the correct one, but the second peak is not in the second position but at the 22nd position.
Looking at the plot, how can I get easily the two maximum points?
Once I know the two coordinates I can easily add all the objects that I need.
Using findpeaks (requires Signal Processing Toolbox), yline (introduced in R2018b) and annotation :
A = [0.140673450903833 0.143148937279028 0.145430952171596 0.147474938627147 0.149581060870114 0.151187105347571 0.152646348246015 0.153892222566265 0.154913060187075 0.155701930397674 0.156253328260122 0.156562551841967 0.156625533585493 0.156438787610539 0.155999394209637 0.155304997895017 0.154353810555534 0.153144616301392 0.151676776486360 0.149950234280632 0.147965519042205 0.145723755995511 0.143229676241241 0.140476287800831 0.137475884805212 0.134228713435530 0.130738812449387 0.127010778531129 0.123049766057659 0.118861478234099 0.114452155847321 0.109828564345449 0.104997979409803 0.0999681710919947 0.0947473865690700 0.0893443315667412 0.0837681505026921 0.0780284054055798 0.0721350536699391 0.0660984247128685 0.0599291956061627 0.0536383657701255 0.0472372308396036 0.0407373558685518 0.0341505481893574 0.0274888307202605 0.0207644183921863 0.0139897104812690 0.00717740846258673 0.000358034181698980 0.00651349557333709 0.0133637955715171 0.0202018404602034 0.0270147225489001 0.0337898204971252 0.0405146415132138 0.0471768260462406 0.0537641715916784 0.0602646603043279 0.0666664873507057 0.0729580891146200 0.0791281709097673 0.0851657340195109 0.0910601019446384 0.0968009457657087 0.102378308539557 0.107782628657363 0.113004762097380 0.118036003510261 0.122868106079509 0.127493300104313 0.131904310257409 0.136094371477732 0.140057243469708 0.143787223810476 0.147279159770258 0.150528459504324 0.153531108836772 0.156280444813554 0.158783035106175 0.161027296288627 0.163014562505352 0.164743731117677 0.166214276765471 0.167426257040343 0.168380310331524 0.169077651806683 0.169520068571722 0.169709914896378 0.169650109087113 0.169344135453180 0.168796059816963 0.168010582212876 0.166993205517562 0.165750858213848 0.164295206012858 0.162692813100379 0.160590402150861 0.158550181408264 0.156271984944015 0.153800366335689];
B = [-2 -1.96000000000000 -1.92000000000000 -1.88000000000000 -1.84000000000000 -1.80000000000000 -1.76000000000000 -1.72000000000000 -1.68000000000000 -1.64000000000000 -1.60000000000000 -1.56000000000000 -1.52000000000000 -1.48000000000000 -1.44000000000000 -1.40000000000000 -1.36000000000000 -1.32000000000000 -1.28000000000000 -1.24000000000000 -1.20000000000000 -1.16000000000000 -1.12000000000000 -1.08000000000000 -1.04000000000000 -1 -0.960000000000000 -0.920000000000000 -0.880000000000000 -0.840000000000000 -0.800000000000000 -0.760000000000000 -0.720000000000000 -0.680000000000000 -0.640000000000000 -0.600000000000000 -0.560000000000000 -0.520000000000000 -0.480000000000000 -0.440000000000000 -0.400000000000000 -0.360000000000000 -0.320000000000000 -0.280000000000000 -0.240000000000000 -0.200000000000000 -0.160000000000000 -0.120000000000000 -0.0800000000000001 -0.0400000000000000 0 0.0400000000000000 0.0800000000000001 0.120000000000000 0.160000000000000 0.200000000000000 0.240000000000000 0.280000000000000 0.320000000000000 0.360000000000000 0.400000000000000 0.440000000000000 0.480000000000000 0.520000000000000 0.560000000000000 0.600000000000000 0.640000000000000 0.680000000000000 0.720000000000000 0.760000000000000 0.800000000000000 0.840000000000000 0.880000000000000 0.920000000000000 0.960000000000000 1 1.04000000000000 1.08000000000000 1.12000000000000 1.16000000000000 1.20000000000000 1.24000000000000 1.28000000000000 1.32000000000000 1.36000000000000 1.40000000000000 1.44000000000000 1.48000000000000 1.52000000000000 1.56000000000000 1.60000000000000 1.64000000000000 1.68000000000000 1.72000000000000 1.76000000000000 1.80000000000000 1.84000000000000 1.88000000000000 1.92000000000000 1.96000000000000 2];
plot(B,A)
% Find peaks.
[maxValuesY,isMaxY]=findpeaks(A);
maxValuesX = B(isMaxY);
% Plot horizontal line.
yline(maxValuesY(2));
% Create arrow.
ar = annotation('arrow');
ar.Parent = gca;
ar.X = [maxValuesX(1), maxValuesX(1)];
ar.Y = [maxValuesY(2), maxValuesY(1)];
ar.Color = 'black';
ar.HeadLength = 3;
Thanks to marsei for tip on the position of annotation.
If you specifically have such plots, you can go with the following solution, which just excludes n neighbours around the first found maximum.
% Input (copy from above...)
A = [ .. ];
B = [ .. ];
% Index of max value.
[max_val, max_idx] = max(A);
% Find second max value by excluding n neighbourhood.
n = 10;
AA = A;
AA(max_idx - n : max_idx + n) = [];
sec_max_val = max(AA);
sec_max_idx = find(A == sec_max_val);
% Output.
figure(1);
hold on;
% Graph.
plot(B, A);
% Black line.
plot([B(1) B(end)], [max_val max_val], 'k');
% Black arrow.
p1 = [B(sec_max_idx) B(sec_max_idx)];
p2 = [max_val sec_max_val];
dp = p2 - p1;
quiver(p1(1), p2(1), p1(2) - p1(1), p2(2) - p2(1), 0, 'k');
hold off;
You'll get such an output:

SystemVerilog array random seed of Shuffle function

I get the same output everytime I run the code below.
module array_shuffle;
integer data[10];
initial begin
foreach (data[x]) begin
data[x] = x;
end
$display("------------------------------\n");
$display("before shuffle, data contains:\n");
foreach (data[x]) begin
$display("data[%0d] = %0d", x, data[x]);
end
data.shuffle();
$display("------------------------------\n");
$display("after shuffle, data contains:\n");
foreach (data[x]) begin
$display("data[%0d] = %0d", x, data[x]);
end
end
endmodule
Output:
------------------------------
before shuffle, data contains:
data[0] = 0
data[1] = 1
data[2] = 2
data[3] = 3
data[4] = 4
data[5] = 5
data[6] = 6
data[7] = 7
data[8] = 8
data[9] = 9
------------------------------
after shuffle, data contains:
data[0] = 8
data[1] = 6
data[2] = 7
data[3] = 9
data[4] = 5
data[5] = 0
data[6] = 1
data[7] = 4
data[8] = 2
data[9] = 3
Is there a way to seed the randomization of the shuffle function?
Shuffle returns the same result every time because you probably run the simulator with the same seed. This is the intended behavior, because when you run a simulation and find a bug, you want to be able to reproduce it, regardless of any design (and to some extent testbench) changes. To see a different output, try setting the seed on the simulator command line. For Incisive this is:
irun -svseed 1 // sets the seed to 1
irun -svseed random // will set a random seed
It's also possible to manipulate the seed of the random number generator using set_randstate, but I wouldn't mess with that.