Search code examples
rrandomnodes

Fixing the First and Last Numbers in a Random List


I used this code to generate these random numbers (corresponds to an edge list for a graph) such that (Generating Random Graphs According to Some Conditions):

  • The first and last "nodes" are the same (e.g. starts at "1" and ends at "1")
  • Each node is visited exactly once

See below:

d = 15

relations = data.frame(tibble(
  from = sample(data$d),
  to = lead(from, default=from[1]),
))

> relations
   from to
1     1 11
2    11  7
3     7  5
4     5 10
5    10 13
6    13  9
7     9 15
8    15  2
9     2  3
10    3  4
11    4  8
12    8  6
13    6 12
14   12 14
15   14  1

If I re-run this above code, it will (naturally) produce a different list:

relations
   from to
1     6  9
2     9  2
3     2  5
4     5  8
5     8 13
6    13  1
7     1 14
8    14  3
9     3 11
10   11 12
11   12  7
12    7 15
13   15  4
14    4 10
15   10  6
  • Can I do something so that each time I generate a new random set of numbers, I can fix the first and last number to a specific number?

For instance, could I make it so that the first number and the last number are always "7"?

#example 1
   from to
1     7 11
2    11  1
3     1  5
4     5 10
5    10 13
6    13  9
7     9 15
8    15  2
9     2  3
10    3  4
11    4  8
12    8  6
13    6 12
14   12 14
15   14  7

#example 2
   from to
1     7  9
2     9  2
3     2  5
4     5  8
5     8 13
6    13  1
7     1 14
8    14  3
9     3 11
10   11 12
11   12  6
12    6 15
13   15  4
14    4 10
15   10  7

In the above examples (example 1, example 2), I took the first two random lists I made and manually replaced the first number and last number with 7 - and then replaced the replacement numbers as well.

  • But is there a way to "automatically" do this instead of making a manual correction?

For example, I think I figured out how to do this:

#run twice to make sure the output is correct

  relations = data.frame(tibble(
      from = sample(data$d),
      to = lead(from, default=from[1]),
    ))
    
    orig_first = relations[1,1]
    
    
    relations[1,1] = 7
    relations[15,2] = 7
    
    relation = relations[-c(1,15),]
    r1 = relations[1,]
    r2 = relations[15,]
    
    final_relation = rbind(r1, relation, r2)

#output 1 : seems correct (starts with 7, ends with 7, all nodes visited exactly once)

   from to
1     7  8
2     8  4
3     4  7
4     7 13
5    13  1
6     1 14
7    14  6
8     6  9
9     9 11
10   11 10
11   10 12
12   12  2
13    2  5
14    5 15
15   15  7

#output 2: looks correct

   from to
1     7  9
2     9  2
3     2  1
4     1  6
5     6  3
6     3 10
7    10 11
8    11 14
9    14 12
10   12  7
11    7 13
12   13  4
13    4 15
14   15  8
15    8  7
  • Am I doing this correctly? Is there an easier way to do this?

Thank you!


Solution

  • Here is a way to do this -

    library(dplyr)
    
    set.seed(2021)
    d = 15
    fix_num <- 7
    
    relations = tibble(
      from = c(fix_num, sample(setdiff(1:d, fix_num))),
      to = lead(from, default=from[1]),
    )
    
    relations
    
    # A tibble: 15 x 2
    #    from    to
    #   <dbl> <dbl>
    # 1     7     8
    # 2     8     6
    # 3     6    11
    # 4    11    15
    # 5    15     4
    # 6     4    14
    # 7    14     9
    # 8     9    10
    # 9    10     3
    #10     3     5
    #11     5    12
    #12    12    13
    #13    13     1
    #14     1     2
    #15     2     7