func time_to_deadline(r *rand.Rand, desiredRate float64) (next_deadline time.Duration) { //ExpFloat64 returns an exponentially distributed float64 in the range (0, +math.MaxFloat64] // with an exponential distribution whose rate parameter (lambda) // is 1 and whose mean is 1/lambda (1) from the default Source. //To produce a distribution with a different rate parameter, callers can adjust the output using: // sample := rand.ExpFloat64() / desiredRateParameter // desiredRateNanos := desiredRate/10e8 sample := r.ExpFloat64() / desiredRate return time.Duration(int64(sample * 10e8)) }
// LabeledEuclidean generates a random simple graph on the Euclidean plane. // // Arc label values in the returned graph g are indexes into the return value // wt. Wt is the Euclidean distance between the from and to nodes of the arc. // // Otherwise the function arguments and return values are the same as for // function Euclidean. See Euclidean. func LabeledEuclidean(nNodes, nArcs int, affinity float64, patience int, r *rand.Rand) (g LabeledDirected, pos []struct{ X, Y float64 }, wt []float64, err error) { a := make(LabeledAdjacencyList, nNodes) // graph wt = make([]float64, nArcs) // arc weights // generate random positions if r == nil { r = rand.New(rand.NewSource(time.Now().UnixNano())) } pos = make([]struct{ X, Y float64 }, nNodes) for i := range pos { pos[i].X = r.Float64() pos[i].Y = r.Float64() } // arcs var tooFar, dup int arc: for i := 0; i < nArcs; { if tooFar == nArcs*patience { err = errors.New("affinity not found") return } if dup == nArcs*patience { err = errors.New("overcrowding") return } n1 := NI(r.Intn(nNodes)) var n2 NI for { n2 = NI(r.Intn(nNodes)) if n2 != n1 { // no graph loops break } } c1 := &pos[n1] c2 := &pos[n2] dist := math.Hypot(c2.X-c1.X, c2.Y-c1.Y) if dist*affinity > r.ExpFloat64() { // favor near nodes tooFar++ continue } for _, nb := range a[n1] { if nb.To == n2 { // no parallel arcs dup++ continue arc } } wt[i] = dist a[n1] = append(a[n1], Half{n2, LI(i)}) i++ } g = LabeledDirected{a} return }
// randomSize generates a size greater or equal to zero, with a random // distribution that is skewed towards zero and ensures that most // generated values are smaller than `mag`. func randomSize(rnd *rand.Rand, mag int64) int64 { return int64(rnd.ExpFloat64() * float64(mag) * 0.3679) }