I am using two architecture programs, with visual programming plugins (Grasshopper for Rhino and Dynamo for Revit – for those that know / are interested)
Grasshopper contains a function called ‘Jitter’ this will shuffle a list, however it has an input from 0.0 to 1.0 which controls the degree of shuffling – 0.0 results in no shuffling 1.0 produces a complete shuffle.
The second of the programs (Dynamo) does not contain this functionality. It contains a shuffle module (which contains a seed value) however it is a complete random shuffle.
Ultimately the goal is to produce a series of solid and glazed panels, but to produce a slight random effect (but avoiding large clumping of solid and glazed elements – hence I want a “light shuffle”)
I have written a code which will calculate the number of glazed(True) and solid(False) values required and then evenly distribute True and False values based on the number of items and percent specified.
I have checked out the random module reference however I’m not familiar with the various distributions as described.
Could someone help out or point me in the right direction if an existing function would achieve this.
(I have cheated slightly by adding True False alternately to make up the correct number of items within the list – list3 is the final list, list2 contains the repeated module of true falses)
import math import random percent = 30 items = 42 def remainder(): remain = items % len(list2) list3.append(True) remain -= 1 while remain > 0 : list3.append(False) remain -= 1 return list3 #find module of repeating True and False values list1 = ([True] + [False] * int((100/percent)-1)) #multiply this list to nearest multiple based on len(items) list2 = list1 * int(items/(100/percent)) # make a copy of list2 list3 = list2[:] #add alternating true and false to match len(list3) to len(items) remainder() #an example of a completely shuffled list - which is not desired shuffled = random.sample(list3, k = len(list3))
Here is an approach based on this paper which proves a result about the mixing time needed to scramble a list by using swaps of adjacent items
from random import choice from math import log def jitter(items,percent): n = len(items) m = (n**2 * log(n)) items = items[:] indices = list(range(n-1)) for i in range(int(percent*m)): j = choice(indices) items[j],items[j+1] = items[j+1],items[j] return items
A test, each line showing the result of
jitter with various percents being applied to the same list:
ls = list(('0'*20 + '1'*20)*2) for i in range(11): p = i/10.0 print(''.join(jitter(ls,p)))
00000000000000000000111111111111111111110000000000000000000011111111111111111111 00000000000000111100001101111011011111001010000100010001101000110110111111111111 00000000100100000101111110000110111101000001110001101001010101100011111111111110 00000001010010011011000100111010101100001111011100100000111010110111011001011111 00100001100000001101010000011010011011111011001100000111011011111011010101011101 00000000011101000110000110000010011001010110011111100100111101111011101100111110 00110000000001011001000010110011111101001111001001100101010011010111111011101100 01101100000100100110000011011000001101111111010100000100000110111011110011011111 01100010110100010100010100011000000001000101100011111011111011111011010100011111 10011100101000100010001100100000100111001111011011000100101101101010101101011111 10000000001000111101101011000011010010110011010101110011010100101101011110101110
I’m not sure how principled the above is, but it seems like a reasonable place to start.