首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用随机模块python的不同程度的改组

使用随机模块python的不同程度的改组
EN

Stack Overflow用户
提问于 2017-01-31 22:57:21
回答 4查看 832关注 0票数 7

我正在使用两个架构程序,带有可视化编程插件(Grasshopper for Rhino和Dynamo for Revit -对于那些知道/感兴趣的人)

蚱蜢包含一个名为'Jitter‘的函数,这将洗牌一个列表,但是它有一个从0.0到1.0的输入,控制洗牌的程度- 0.0导致没有洗牌1.0产生一个完全的洗牌。

第二个程序(Dynamo)不包含此功能。它包含一个洗牌模块(其中包含一个种子值),但是它是一个完全的随机洗牌。

最终的目标是生产一系列实心和釉面面板,但会产生轻微的随机效应(但避免大量的固体和釉面元素聚集-因此,我想要“轻洗牌”)。

我已经编写了一个代码,它将计算所需的釉(真)和实(假)值的数量,然后根据指定的项目数和百分比均匀地分配真假值。

我已经检查了随机模块引用,但是我不熟悉所描述的各种发行版。

如果一个现有的功能能够实现这一点,有人能帮我或者指出正确的方向吗?

(我稍微作弊,交替地添加了True False,以构成列表中正确的项目数- list3是最终列表,list2包含重复的真假模块)

非常感谢

代码语言:javascript
复制
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))
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-01-31 23:51:57

下面是一种基于本论文的方法,它证明了使用相邻项的交换对列表进行置乱所需的混合时间的结果

代码语言:javascript
复制
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

测试,每一行显示jitter的结果,并将不同百分比应用于同一列表:

代码语言:javascript
复制
ls = list(('0'*20 + '1'*20)*2)

for i in range(11):
    p = i/10.0
    print(''.join(jitter(ls,p)))

典型产出:

代码语言:javascript
复制
00000000000000000000111111111111111111110000000000000000000011111111111111111111
00000000000000111100001101111011011111001010000100010001101000110110111111111111
00000000100100000101111110000110111101000001110001101001010101100011111111111110
00000001010010011011000100111010101100001111011100100000111010110111011001011111
00100001100000001101010000011010011011111011001100000111011011111011010101011101
00000000011101000110000110000010011001010110011111100100111101111011101100111110
00110000000001011001000010110011111101001111001001100101010011010111111011101100
01101100000100100110000011011000001101111111010100000100000110111011110011011111
01100010110100010100010100011000000001000101100011111011111011111011010100011111
10011100101000100010001100100000100111001111011011000100101101101010101101011111
10000000001000111101101011000011010010110011010101110011010100101101011110101110

我不知道上面的原则如何,但这似乎是一个合理的起点。

票数 5
EN

Stack Overflow用户

发布于 2017-01-31 23:16:26

“洗牌的程度”(d)没有明确的定义,所以你需要选择一个。一种选择是:“仍未洗牌的项目的比例是(1-d)”。

您可以将其实现为:

  1. 编制一个指数清单
  2. 移除(1-d)*N
  3. 把剩下的洗牌
  4. 重新插入被移除的
  5. 使用这些方法从原始数据中查找值。
代码语言:javascript
复制
def partial_shuffle(x, d):
    """
    x: data to shuffle
    d: fraction of data to leave unshuffled
    """
    n = len(x)
    dn = int(d*n)
    indices = list(range(n))
    random.shuffle(indices)
    ind_fixed, ind_shuff = indices[dn:], indices[:dn]

    # copy across the fixed values
    result = x[:]

    # shuffle the shuffled values
    for src, dest in zip(ind_shuff, sorted(ind_shuff)):
        result[dest] = x[src]

    return result
票数 4
EN

Stack Overflow用户

发布于 2017-01-31 23:03:19

您所指的其他算法可能是在幕后使用费舍-耶茨洗牌。

这个O(n)洗牌从数组的第一个元素开始,然后用一个随机的更高的元素交换它,然后用一个随机的更高的元素交换第二个元素,依此类推。

自然地,在达到最后一个零位数0,1之前,停止这种洗牌会给出一个部分随机数组,就像你想要的那样。

不幸的是,前面的结果是,所有的“随机性”都建立在数组的一侧。

因此,做一个数组索引的列表,对这些索引进行完全的洗牌,然后使用这些索引作为Fisher-Yates算法的输入,对原始数组进行部分排序。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41969036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档