微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

随机选择扬声器顺序的算法可以工作但通常会产生无限循环

我创建了以下算法(用于真正的问题和乐趣),以便在辩论中随机确定向七名学校董事会候选人提问的顺序,以便:

>每位候选人被问到7个​​问题
>每个候选人在位置1,位置2等处恰好回答一次.
>候选人并不总是遵循相同的顺序(随机顺序但受限于前两个规则)

该算法有效,产生约束于规则的随机输出,但经常被无限循环(或出现).我已经无法确定为什么会发生这种情况,尽管逐步执行代码w /额外的日志记录/断点.

注意:此算法尚未推广或优化.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define NUM_ROWS 7
#define NUM_COLUMNS 7

int debate_order[NUM_ROWS][NUM_COLUMNS];
int candidate_used[NUM_ROWS];

void print_debate_order()
{
    int row,column;

    for(column = 0; column < NUM_COLUMNS; column++) {
        printf("Questions #%d\n",column);
        for(row = 0; row < NUM_ROWS; row++)
            printf("  Candidate #%d\n",debate_order[column][row]);
    }
}

void set_unused(int *array,int size)
{
    int i;

    for(i = 0; i < size; i++)
        array[i] = -1;
}

int in_row(int candidate_num,int current_row)
{
    int column;
    for(column = 0; column < NUM_COLUMNS; column++)
        if( debate_order[column][current_row] == -1 ) // reached end of columns filled in
            break;
        else if ( debate_order[column][current_row] == candidate_num ) // found the candidate in this row
            return(1);
    return(0);
}

int main(int argc,const char * argv[]) {
    int row,column;
    int rand_candidate;

    srand((unsigned int)time(NULL));
    for(column = 0; column < NUM_COLUMNS; column++)
        set_unused(&debate_order[column][0],NUM_COLUMNS);

    for(column = 0; column < NUM_COLUMNS; column++) {
        set_unused(candidate_used,NUM_COLUMNS);
        for (row = 0; row < NUM_ROWS; row++ ) {
            do {
                rand_candidate = rand() % 7;
            } while(candidate_used[rand_candidate] == 1 || in_row(rand_candidate,row));
            candidate_used[rand_candidate] = 1;
            debate_order[column][row] = rand_candidate;
        }
    }

    print_debate_order();

    return 0;
}

解决方法

这是算法中的一个缺陷.

我在内部for循环中添加了print_debate_order()以查看程序获得了多远.这是进入无尽之前的最后一个循环的一个输出

Questions #0
  Candidate #2
  Candidate #6
  Candidate #1
  Candidate #3
  Candidate #0
  Candidate #5
  Candidate #4
Questions #1
  Candidate #0
  Candidate #3
  Candidate #4
  Candidate #2
  Candidate #5
  Candidate #1
  Candidate #6
Questions #2
  Candidate #4
  Candidate #2
  Candidate #6
  Candidate #5
  Candidate #3
  Candidate #0
  Candidate #1
Questions #3
  Candidate #5
  Candidate #4
  Candidate #0
  Candidate #1
  Candidate #6
  Candidate #3
  Candidate #2
Questions #4
  Candidate #3
  Candidate #5
  Candidate #2
  Candidate #0
  Candidate #4
  Candidate #6
  Candidate #-1
Questions #5
  Candidate #-1
  Candidate #-1
  Candidate #-1
  Candidate #-1
  Candidate #-1
  Candidate #-1
  Candidate #-1
Questions #6
  Candidate #-1
  Candidate #-1
  Candidate #-1
  Candidate #-1
  Candidate #-1
  Candidate #-1
  Candidate #-1

正如你所看到的,对于问题4,只剩下一个候选人,即候选人1.但是如果你看看前面的问题,你会发现他已经有了问题2的最后一个位置.因此没有候选人可以选择最后一个问题4的位置,你的while循环试图无休止地找到一个.

如果你想从所有作业中统一选择满足你条件的问题,你就必须在这样的事情发生时重新开始,即你的while循环需要跟踪已经测试过的候选人,如果没有留下任何东西,那么从头开始.然而,这也将在很长的时间内结束,具体取决于候选人和问题的数量,但至少不会有无限循环.

你想在这里生成的东西被称为(uniformly distributed) latin square.生成它们不一定是微不足道的,here is a discussion on math.stackexchange.com.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐