- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个矩阵,我想随机化几千次,同时保持行和列的总数相同:
1 2 3
A 0 0 1
B 1 1 0
C 1 0 0
1 2 3
A 1 0 0
B 1 1 0
C 0 0 1
#!/usr/bin/perl -w
use strict;
my %matrix = ( 'A' => {'3' => 1 },
'B' => {'1' => 1,
'2' => 1 },
'C' => {'1' => 1 }
);
my @letters = ();
my @numbers = ();
foreach my $letter (keys %matrix){
foreach my $number (keys %{$matrix{$letter}}){
push (@letters, $letter);
push (@numbers, $number);
}
}
my %random_matrix = ();
&shuffle(\@numbers);
foreach my $letter (@letters){
while (exists($random_matrix{$letter}{$numbers[0]})){
&shuffle (\@numbers);
}
my $chosen_number = shift (@numbers);
$random_matrix{$letter}{$chosen_number} = 1;
}
sub shuffle {
my $array = shift;
my $i = scalar(@$array);
my $j;
foreach my $item (@$array )
{
--$i;
$j = int rand ($i+1);
next if $i == $j;
@$array [$i,$j] = @$array[$j,$i];
}
return @$array;
}
最佳答案
您当前算法的问题在于您正试图摆脱死胡同 - 特别是当您的 @letters
和 @numbers
数组(在 @numbers
的初始洗牌之后)不止一次产生相同的单元格。当矩阵很小时,这种方法有效,因为它不需要太多尝试就可以找到可行的重新洗牌。然而,当列表很大时,它是一个杀手。即使您可以更有效地寻找替代方案——例如,尝试排列而不是随机改组——该方法可能注定要失败。
您可以通过对现有矩阵进行小的修改来解决问题,而不是对整个列表进行混洗。
例如,让我们从您的示例矩阵开始(称为 M1)。随机选择一个单元格进行更改(例如 A1)。此时矩阵处于非法状态。我们的目标是以最少的编辑次数来修复它——特别是 3 次以上的编辑。您通过在矩阵周围“走动”来实现这 3 个额外的编辑,每次修复行或列都会产生另一个需要解决的问题,直到走完整个圆圈(错误...完整矩形)。
例如,将A1从0改为1后,下一次修复有3种行走方式:A3、B1、C1。让我们决定第一次编辑应该修复行。所以我们选择A3。在第二次编辑时,我们将修复该列,因此我们可以选择:B3 或 C3(例如 C3)。最后的修复只提供了一个选择(C1),因为我们需要回到我们原来编辑的那一栏。最终结果是一个新的有效矩阵。
Orig Change A1 Change A3 Change C3 Change C1
M1 M2
1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
----- ----- ----- ----- -----
A | 0 0 1 1 0 1 1 0 0 1 0 0 1 0 0
B | 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
C | 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1
use strict;
use warnings;
# Args: N rows, N columns, density, N iterations.
main(@ARGV);
sub main {
my $n_iter = pop;
my $matrix = init_matrix(@_);
print_matrix($matrix);
for my $n (1 .. $n_iter){
warn $n, "\n"; # Show progress.
edit_matrix($matrix);
print_matrix($matrix);
}
}
sub init_matrix {
# Generate initial matrix, given N of rows, N of cols, and density.
my ($rows, $cols, $density) = @_;
my @matrix;
for my $r (1 .. $rows){
push @matrix, [ map { rand() < $density ? 1 : 0 } 1 .. $cols ];
}
return \@matrix;
}
sub print_matrix {
# Dump out a matrix for checking.
my $matrix = shift;
print "\n";
for my $row (@$matrix){
my @vals = map { $_ ? 1 : ''} @$row;
print join("\t", @vals), "\n";
}
}
sub edit_matrix {
# Takes a matrix and moves all of the non-empty cells somewhere else.
my $matrix = shift;
my $move_these = cells_to_move($matrix);
for my $cell (@$move_these){
my ($i, $j) = @$cell;
# Move the cell, provided that the cell hasn't been moved
# already and the subsequent edits don't lead to a dead end.
$matrix->[$i][$j] = 0
if $matrix->[$i][$j]
and other_edits($matrix, $cell, 0, $j);
}
}
sub cells_to_move {
# Returns a list of non-empty cells.
my $matrix = shift;
my $i = -1;
my @cells = ();
for my $row (@$matrix){
$i ++;
for my $j (0 .. @$row - 1){
push @cells, [$i, $j] if $matrix->[$i][$j];
}
}
return \@cells;
}
sub other_edits {
my ($matrix, $cell, $step, $last_j) = @_;
# We have succeeded if we've already made 3 edits.
$step ++;
return 1 if $step > 3;
# Determine the roster of next edits to fix the row or
# column total upset by our prior edit.
my ($i, $j) = @$cell;
my @fixes;
if ($step == 1){
@fixes =
map { [$i, $_] }
grep { $_ != $j and not $matrix->[$i][$_] }
0 .. @{$matrix->[0]} - 1
;
shuffle(\@fixes);
}
elsif ($step == 2) {
@fixes =
map { [$_, $j] }
grep { $_ != $i and $matrix->[$_][$j] }
0 .. @$matrix - 1
;
shuffle(\@fixes);
}
else {
# On the last edit, the column of the fix must be
# the same as the column of the initial edit.
@fixes = ([$i, $last_j]) unless $matrix->[$i][$last_j];
}
for my $f (@fixes){
# If all subsequent fixes succeed, we are golden: make
# the current fix and return true.
if ( other_edits($matrix, [@$f], $step, $last_j) ){
$matrix->[$f->[0]][$f->[1]] = $step == 2 ? 0 : 1;
return 1;
}
}
# Failure if we get here.
return;
}
sub shuffle {
my $array = shift;
my $i = scalar(@$array);
my $j;
for (@$array ){
$i --;
$j = int rand($i + 1);
@$array[$i, $j] = @$array[$j, $i] unless $i == $j;
}
}
关于perl - 在perl中随机化矩阵,保持行和列的总数相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2133268/
我的应用程序包含两部分:网络部分和 GUI。它的工作方式有点像浏览器 - 用户从服务器请求一些信息,服务器发回一些代表某些 View 的数据,然后 GUI 显示它。 现在我已经将网络部分实现为一项服务
给定表达式字符串exp,编写程序检查exp中“{”、“}”、“(”、“)”、“[”、“]的对和顺序是否正确。 package main import ( "fmt" stack "gi
我想要一个简单的脚本在后台保持运行。目前看起来像这样: import keyboard while True: keyboard.wait('q') keyboard.send('ct
我维护着许多 RedHat Enterprise Linux(7 台和 8 台)服务器(>100 台),其中包含不同的应用程序。为了保持理智,我当然会使用 Ansible 等工具,更重要的是,公共(p
我有一个 winforms 应用程序,它在网络服务请求期间被锁定 我已经尝试使用 doEvents 来保持应用程序解锁,但它仍然不够响应, 我怎样才能绕过这个锁定,让应用程序始终响应? 最佳答案 最好
我正在努力在我的项目中获得并保持领先的 0。以下是当前相关的代码: Dim jobNum As String jobNum = Left(r1.Cells(1, 1), 6) r2.Cells(1
我正在尝试在我的 Canvas 中定位元素相对于我的背景。 窗口被重新调整大小,保持纵横比。 背景随着窗口大小而拉伸(stretch)。 问题是一旦重新调整窗口大小,元素位置就会不正确。如果窗口的大小
一直在玩弄 Hibernate 和 PostgreSQL,试图让它按预期工作。 但是由于某种原因,当我尝试将具有@OneToMany 关系的对象与集合中的多个项目保持一致时,除了第一个项目之外,所有项
我想将某些东西提交到 github 存储库,但我(显然)没有任何权利这样做。我对那个 repo 做了一个分支,提交了我的更改并提交了一个 pull-request。 现在,问题是过了一段时间其他人已经
这是一个初学者问题,我仍在考虑“在 OOP 中”,所以如果我错过了手册中的答案或者答案很明显,我深表歉意。 假设我们有一个抽象类型, abstract type My_Abstract_type en
我们正在开展的一些项目在 jQuery 1.4.2 或更早版本中有着深厚的根基,介于缺乏最新版本的性能优势(或语法糖)、使用现已弃用的方法的耻辱以及部署一个积极维护的库的 3 年以上旧版本,升级现在迫
我看到在FMDB 2.0中,作者为线程添加了FMDatabaseQueue。例子是: // First, make your queue. FMDatabaseQueue *queue = [FMDa
我在 NSScrollView 中有一个 NSTableView。 NSTableView 的内容是通过绑定(bind)到 NSArrayController 来提供的,而 NSArrayContro
我在 TreeView 上有一个节点,我手动填充该节点并希望保持排序。通过用户交互,TreeViewItem 上的标题可能会更改,它们应该移动到列表中的适当位置。 我遍历一个 foreach,创建多个
我从主 NSWindow 打开一个 NSWindow。 DropHereWindowController *dropHereWindowController = [[DropHereWindowCon
我需要放置一个 form 3 按钮,当我单击该按钮时,将其显示为按下,其他按钮向上,当我单击另一个按钮时,它应该为“向下”,其他按钮应为“向上” 最佳答案 所有按钮的属性“Groupindex”必须设
我有一个使用 AnyEvent::MQTT 订阅消息队列的 perl 脚本。 目前我想要它做的就是在收到消息时打印出来。我对 perl 完全陌生,所以我正在使用它附带的演示代码,其中包括将 STDIN
如何在 .NET 应用程序中保持 TreeView 控件的滚动位置?例如,我有一个树形 View 控件,并经历了一个向其添加各种节点的过程,并将它们固定在底部。在此过程中,我可以滚动浏览 TreeVi
我维护了大量的 vbscripts,用于在我的网络上执行各种启动脚本,并且有一些我在几乎所有脚本中使用的函数。 除了复制和粘贴之外,有没有人对我如何创建可重用 vbscript 代码库有建议。我并不反
我有一些关于 Azure 自托管的问题。 假设用户 Alex 在物理机 M 上设置了 Windows 自托管代理。当 Alex 注销且计算机进入休眠状态时,代理将脱机。现在,当 Bob 登录同一台计算
我是一名优秀的程序员,十分优秀!