给定循环内的条件,重复 for 循环的当前迭代

Repeating current iteration of a for loop given a condition inside the loop

我正在尝试模拟 2D 中的聚合物,其中单个聚合物由多个单体构成。模拟的方法是通过随机化两个单体之间的角度。这显然是一个很大的简化:每个单体都是一条线,最后是一个球体。条件是球体不能重叠。我遇到的问题是,如果球体确实重叠,则 continue 命令会完成当前迭代,但不会创建单体,这意味着如果发生 1 次重叠,则单体将比预期少 1 个。需要发生的是,如果它重叠,它将尝试再次构建单体,直到它不与任何其他单体重叠。我尝试了一个 while 循环,但我正在循环内构建每个单体,所以我无法弄清楚。 重叠检查 (check_monomer_distance) 需要检查已生成的每个单体。 (我也需要在 3D 中进行此模拟,但我专注于 2D atm,这就是为什么有一个未使用的变量 dim

import numpy as np
import random


dim = 2
monomer_length = 10
edge_diameter = 1  #radius of spheres
polymer_length = 100 # a single polymer is made out of many monomers of identical length
d_angle = 10


d_theta_range = np.arange(0.0, 2 * np.pi, d_angle)
last_coordinates= np.zeros(int(dim))
list_coo = [np.zeros(int(dim))] #every element in this list is the coordinates of a monomer, which means the polymer at its entirety 


for n_m in range(0, polymer_length): # n_m == Number of monomer
    random_d = random.choice(d_theta_range) # The angle between one monomer to the next
    step = monomer_length * np.array((np.cos(random_d), np.sin(random_d)))
    next_coordinates = last_coordinates + step
    if not check_monomer_distance(list_coo, next_coordinates, dim):  # check to see if monomers overlap
        continue
    last_coordinates = next_coordinates
    list_coo.append(next_coordinates)


def check_monomer_distance(list_coo, next_coordinates, dim):
    for i in range(len(list_coo)-1): # The minus 1 is because it will never overlap with the first previous monomer
        vector = next_coordinates - list_coo[i] # vector from the proposed monomer to every other generated
        vector_length = np.sqrt(vector[0]**2 + vector[1]**2)
        if vector_length < edge_diameter:
            return False # The return values need to be like this I can't change them: if the spheres overlap return False
        return True

最后我需要 运行 一些分析,这就是为什么聚合物是一个列表 (list_coo),我感兴趣的是分析而不是聚合物本身。 角度的随机化需要这样,有点麻烦我知道。

你非常接近:你用语言准确描述了逻辑,但没有在代码中实现它。这是一个经典的“until valid”循环,在许多语言中被视为“while not valid”。

for n_m in range(0, polymer_length): # n_m == Number of monomer

    valid = False
    while not valid  # Repeat this loop until it generates a non-overlapping monomer.
        random_d = random.choice(d_theta_range) # The angle between one monomer to the next
        step = monomer_length * np.array((np.cos(random_d), np.sin(random_d)))
        next_coordinates = last_coordinates + step
        valid = check_monomer_distance(list_coo, next_coordinates, dim):

    last_coordinates = next_coordinates
    list_coo.append(next_coordinates)

您可以通过利用 while 构造和 continue/break 语句来避免使用额外的变量

使用break满足条件时停止:

for n_m in range(0, polymer_length): # n_m == Number of monomer
    while True: # repeat while condition is not met, break when it is
        random_d = random.choice(d_theta_range) # The angle between one monomer to the next
        step = monomer_length * np.array((np.cos(random_d), np.sin(random_d)))
        next_coordinates = last_coordinates + step
        if check_monomer_distance(list_coo, next_coordinates, dim):  # check to see if monomers overlap
            break
    last_coordinates = next_coordinates
    list_coo.append(next_coordinates)

或者在条件不满足时使用continue循环:

for n_m in range(0, polymer_length): # n_m == Number of monomer
    while True: # continue loop until condition met, break when done
        random_d = random.choice(d_theta_range) # The angle between one monomer to the next
        step = monomer_length * np.array((np.cos(random_d), np.sin(random_d)))
        next_coordinates = last_coordinates + step
        if not check_monomer_distance(list_coo, next_coordinates, dim):  # check to see if monomers overlap
            continue
        last_coordinates = next_coordinates
        list_coo.append(next_coordinates)
        break