提问人:Rory Holden 提问时间:11/16/2023 最后编辑:WolfieRory Holden 更新时间:11/17/2023 访问量:29
在 MatLab 中将单词表与条件排列
Permutations of a wordlist with criteria in MatLab
问:
我有一个包含 12 个项目的单词列表,由 4 个语义类别组成,每个类别有 3 个项目。这包括沙发、架子、桌子(家具)、飞机、船、卡车(车辆)、夹克、鞋子、毛衣(衣服)、生菜、胡萝卜、菠菜(蔬菜)。我需要用这 12 个项目制作一个随机列表,但是有一些规则。
首先,来自同一语义类别的项目在列表中不能相互相邻(例如生菜和菠菜)。其次,该列表分为 3 个块(第 1-4 项、第 5-8 项和第 9-12 项)。在每个块中,每个语义类别中必须至少有一个项目,但不得超过一个项目。
完整的编码菜鸟,所以我知道如何计算排列,但我不知道如何实现其他规则。任何帮助,非常感谢。
之前的求解器提出了一个解决方案,但给出了 python 的答案。对不起,我没有任何编码能力,无法翻译。
尝试使用
% Wordlist
wordlist = {'Carrot', 'Spinach', 'Lettuce', 'Jacket', 'Shoes', 'Sweater', 'Plane', 'Boat', 'Truck', 'Shelf', 'Table', 'Couch'};
% Define semantic categories
categories = {'Vegetables', 'Clothing', 'Vehicles', 'Furniture'};
while true
% Shuffle indices
shuffled_indices = randperm(length(wordlist));
% Check semantic relatedness and ensure no two related items neighbor each other
no_neighboring_related = all(arrayfun(@(i) ~any(ismember(wordlist(shuffled_indices(i:i+1)), categories)), 1:length(shuffled_indices)-1));
% Check representation in each block
representation_in_blocks = all(arrayfun(@(a) numel(unique(wordlist(shuffled_indices(a:a+3)))) == 4 && ...
all(ismember(categories, wordlist(shuffled_indices(a:a+3)))), [1, 5, 9]));
% If both conditions are met, break out of the loop
if no_neighboring_related && representation_in_blocks
break;
end
end
% Display the randomly generated wordlist
disp('Randomly Generated Wordlist:');
disp(wordlist(shuffled_indices));
但是,这永远不会停止运行,并且必须暂停。
答:
1赞
Wolfie
11/17/2023
#1
你说
在每个块中,每个语义类别中必须至少有一个项目,但不得超过一个项目
我们可以简化这个条件,说每个类别中必须有一个项目。你没有指定,但我假设你不希望整个列表中的每个项目有任何重复 - 我会指出你可以在哪里更改下面的代码以允许在最后重复。
这是带注释的代码,它首先分配第二行来跟踪每个项目的类别,然后遍历每个块并依次从每个类别中选择一个随机项目,然后删除该类别作为其余块的选项并继续选择。wordlist
wordlist = {'Carrot', 'Spinach', 'Lettuce', 'Jacket', 'Shoes', 'Sweater', 'Plane', 'Boat', 'Truck', 'Shelf', 'Table', 'Couch'};
cats = {'Vegetables', 'Clothing', 'Vehicles', 'Furniture'};
ncats = numel(cats); % number of categories
nblocks = numel(wordlist)/ncats; % number of blocks
wordlist(2,:) = repelem(cats,1,nblocks); % make 2nd row for categories
% Intialise output and loop var
thisCat = '';
shuffled = cell(1,size(wordlist,2));
% Loop over each block, where each block contains one of each category
for iblk = 1:nblocks
% Reset "c" to be the list of all categories available to choose from
c = cats;
% Loop over the categories
for ic = 1:ncats
% Randomly pick a category from the list
% Avoiding duplicate neighbours
rc = randi(ncats+1-ic);
while strcmp(c{rc},thisCat)
rc = randi(ncats+1-ic); % keep picking...
end
% Update current category
thisCat = c{rc};
% Find the indicies of words in this category
idxcat = find(strcmp(wordlist(2,:),thisCat));
% Pick a random one of those indicies
iw = idxcat(randperm(numel(idxcat),1));
% Add this work to the output list
shuffled{(iblk-1)*ncats+ic} = wordlist{1,iw};
% remove category from choices for this block
c(rc) = [];
% remove work from choices forever
wordlist(:,iw) = [];
end
end
如果您不介意有重复的单词,可以省略该行,因为它仍会在每个循环开始时检查重复的类别,但可以从 中的更多选项进行匹配。wordlist(:,iw) = []
wordlist
评论
0赞
Rory Holden
11/17/2023
这会在第 19 行产生一个错误,说;无法识别的函数或变量“thisCat”。Untitled2(第 19 行)中的错误,而 strcmp(c{rc},thisCat)
0赞
Wolfie
11/17/2023
@RoryHolden我在复制到我的答案时一定错过了它,但我现在已经更新了它,只需要在循环之前初始化即可
评论