我有一个包含 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));
然而,这永远不会停止运行,必须暂停。
你说
在每个块中,每个语义类别必须至少但不超过一项
我们可以简化该条件,即每个类别中必须“恰好”有一个项目。您没有指定,但我假设您不希望整个列表中的每个项目有任何重复 - 我将指出您可以在哪里更改以下代码以允许在末尾出现重复项。 这里是注释代码,首先将第二行分配给
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
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([1,ncats+1-ic]);
while strcmp(c{rc},thisCat)
rc = randi([1,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
中的更多选项进行匹配。