如何以下列方式在Delphi(Object Pascal)中实现以下算法:
上次编辑:请参阅Python intertools implementation。
考虑以下几组及其成员:
S1 = {a1,a2,a3,a4,a5}
S2 = {b1,b2,b3,b4}
S3 = {c1,c2,c3,c4,c5}
选择每组中的第一个成员(P =选择状态):
P1 = {a1,b1,c1}
然后,将第一个增加到其限制:
P2 = {a2,b1,c1} P3 = {a3,b1,c1} P4 = {a4,b1,c1} P5 = {a5,b1, C1}
然后,重置第一组,并将第二组增加“1”;
P6 = {a1,b2,c1}
再次增加第一组...依此类推......重置第三组中每个'加一'的第一组和第二组。
P7 = {a2,b2,c1}
关于计数的基本原理或乘法原理,该算法将生成100个拾取状态/组合。
P100 = {a5,b4,c5}
答案 0 :(得分:1)
你在数。
每个珠子都是一个数字,你在你的例子中你在5号基地工作,因为每个珠子可以有5个位置中的一个。
要确定珠子的哪个位置对应于给定的整数,在相关基数中写入该整数就足够了。以下是17
>> 17.to_s(5).rjust(3, '0')
=> "032"
在这里,我将左边填充到3个珠子,以清楚每个珠子的位置,并且我正在使用珠子从位置0开始而不是位置1的约定。
答案 1 :(得分:1)
我使用递归和条件调用达到了解决方案。我用这种结构创建了一条记录:
TGridKey = record
ID : Integer;
Index : Integer;
Files : TStringList;
end;
TTrialSet = record
theGrid : array of TGridKey;
end;
在TForm类中使用此名称。
TfRandStimuliSet = class (TForm)
//...
lst1: TListBox;
dlgOpenPic: TOpenPictureDialog;
private
FTrialSet: TTrialSet;
procedure TfRandStimuliSet.SubSetsMountEngine;
//...
end;
设置网格阵列的长度:
NumComp := 3;
SetLength(FTrialSet.theGrid, NumComp);
for I := Low(FTrialSet.theGrid) to High(FTrialSet.theGrid) do
begin
FTrialSet.theGrid[I].ID := I;
FTrialSet.theGrid[I].Index:= -1;
FTrialSet.theGrid[I].Files := TStringList.Create;
end;
在每个'I'网格中添加一些字符串:
if dlgOpenPic.Execute then
begin
if dlgOpenPic.Files.Count > 0 then
for K := 0 to (dlgOpenPic.Files.Count - 1) do
begin
FTrialSet.theGrid[I].Files.Add(dlgOpenPic.Files.Strings[K]);
end;
dlgOpenPic.Files.Clear;
end;
然后程序:
procedure TfRandStimuliSet.SubSetsMountEngine;
var ID: integer; s1 : string;
procedure AddStmFromGrid(Grid, Stm : Integer);
begin
s1 := s1 + ExtractFileName(FTrialSet.theGrid[Grid].Files.Strings[Stm]) + ',';
end;
procedure AddTrialFromIndex; //each trial is the current index's
var I: Integer;
begin
for I:= Low(FTrialSet.theGrid) to High(FTrialSet.theGrid) do
AddStmFromGrid(I,FTrialSet.theGrid[I].Index);
lst1.Items.Add(s1);
s1:= '';
end;
procedure IndexReset(aGrid : Integer);
var i : Integer;
begin
for I := aGrid to (High(FTrialSet.theGrid)) do
FTrialSet.theGrid[I].Index := 0
end;
procedure IndexInc(aGrid : Integer);
begin
AddTrialFromIndex; //Save
Inc(FTrialSet.theGrid[aGrid].Index);
end;
function MoveGrid(var ID:integer): Boolean; //begin from right most, the highest grid
var IDMaxIndex, IDCurIndex, LowID, HighID: Integer;
begin
Result := True;
LowID := Low(FTrialSet.theGrid);
HighID := High(FTrialSet.theGrid);
//Application.ProcessMessages;
if (ID < LowID) then
begin
//ShowMessage('False');
AddTrialFromIndex;
Result := False;
end
else
begin
IDMaxIndex:= FTrialSet.theGrid[ID].Files.Count -1;
IDCurIndex := FTrialSet.theGrid[ID].Index;
if IDCurIndex = IDMaxIndex then
begin
ID := ID - 1;
Result:= MoveGrid(ID);//moveleft
Exit;
end;
if (ID < HighID)
and (IDCurIndex < IDMaxIndex) then
begin
IndexInc(ID); //increment/move donw
IndexReset(ID + 1); //reset everything on the right
MoveGrid(HighID); //move to the most right/next down
Exit;
end;
if (ID = (HighID))
and (IDCurIndex < IDMaxIndex) then
begin
IndexInc(ID); //increment/move down
MoveGrid(ID) //next increment/move down
end;
end;
end;
begin
ID := High(FTrialSet.theGrid);
IndexReset(Low(FTrialSet.theGrid)); //0's for everyone
MoveGrid(ID); //begin from the most right
end;