获取矩阵中所有可能的行组合

2 投票
2 回答
2602 浏览
提问于 2025-04-30 19:36

我正在用Python设置一个简单的句子生成器,目的是尽可能多地组合单词,以描述一组关于机器人的普通图片。(这背后有个长故事 :D)

它输出的内容像这样:'赛博格概念可下载插图'

令人惊讶的是,我写的随机生成器最多只能生成255种独特的组合。下面是我的代码:

import numpy
from numpy import matrix
from numpy import linalg

import itertools
from pprint import pprint 
import random


m = matrix( [
    ['Robot','Cyborg','Andoid', 'Bot', 'Droid'],
    ['Character','Concept','Mechanical Person', 'Artificial Intelligence', 'Mascot'],
    ['Downloadable','Stock','3d', 'Digital', 'Robotics'],
    ['Clipart','Illustration','Render', 'Image', 'Graphic'],
]) 

used = []

i = 0

def make_sentence(m, used):
    sentence = []
    i = 0
    while i <= 3:
        word = m[i,random.randrange(0,4)]
        sentence.append(word)
        i = i+1
    return ' '.join(sentence)

def is_used(sentence, used):
    if sentence not in used:
        return False
    else: 
        return True

sentences = []      
i = 0
while i <= 1000:
    sentence = make_sentence(m, used)
    if(is_used(sentence, used)):
        continue
    else:       
        sentences.append(sentence)
        print str(i) + ' ' +sentence
        used.append(sentence)
        i = i+1

如果用randint代替randrange,我可以瞬间生成多达624种组合,但之后就卡在一个无限循环里,无法再生成更多组合。

我想问的是,有没有更合适的方法来确定一个矩阵的所有可能组合?

暂无标签

2 个回答

0

你的代码可以使用递归。这里有一种不使用itertools的策略:

def make_sentences(m, choices = []):
    output = []
    if len(choices) == 4:
         sentence = ""
         i = 0
         #Go through the four rows of the matrix 
         #and choose words for the sentence
         for j in choices:
             sentence += " " + m[i][j]
             i += 1
    return [sentence] #must be returned as a list
    for i in range(0,4):
         output += make_sentences(m, choices+[i])
    return output #this could be changed to a yield statement

这个方法和你最初的函数差别很大。

choices列表用来记录每一行(ROW)中被选中的列的索引。当递归方法发现choices列表中已经选中了四行时,它会输出一个只有一句话的列表。

如果方法发现choices列表没有四个元素,它会递归地调用自己,生成四个新的choices列表。这些递归调用的结果会被添加到输出列表中。

3

你可以使用itertools这个工具来获取矩阵的所有可能组合。我给了一个例子来展示它是怎么工作的。

 import itertools
 mx = [
  ['Robot','Cyborg','Andoid', 'Bot', 'Droid'],
  ['Character','Concept','Mechanical Person', 'Artificial Intelligence', 'Mascot'],
  ['Downloadable','Stock','3d', 'Digital', 'Robotics'],
  ['Clipart','Illustration','Render', 'Image', 'Graphic'],
  ]
for combination in itertools.product(*mx):
     print combination

撰写回答