如何使用 Grand Central Dispatch 并行化数独求解器?

2024-02-20

作为编程练习,我刚刚编写了一个使用回溯算法的数独求解器(请参阅维基百科 http://en.wikipedia.org/wiki/Algorithmics_of_sudoku#Example_of_a_brute_force_Sudoku_solver_.28in_C.29一个用 C 编写的简单示例)。

为了更进一步,我想使用 Snow Leopard 的 GCD 来并行化它,以便它可以在我的机器的所有内核上运行。有人可以指导我应该如何执行此操作以及应该进行哪些代码更改吗?谢谢!

Matt


如果您最终使用它,请告诉我。它是标准的 ANSI C,所以应该可以在所有东西上运行。使用方法请参见其他帖子。

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

short sudoku[9][9];
unsigned long long cubeSolutions=0;
void* cubeValues[10];
const unsigned char oneLookup[64] = {0x8b, 0x80, 0, 0x80, 0, 0, 0, 0x80, 0, 0,0,0,0,0,0, 0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int ifOne(int val) {
  if ( oneLookup[(val-1) >> 3] & (1 << ((val-1) & 0x7))  )
    return val;
  return 0;
}


void init_sudoku() {
  int i,j;
  for (i=0; i<9; i++)
    for (j=0; j<9; j++)
      sudoku[i][j]=0x1ff;
}

void set_sudoku( char* initialValues) {
  int i;
  if ( strlen (initialValues) !=  81 ) {
    printf("Error: inputString should have length=81, length is %2.2d\n", strlen(initialValues) );
    exit (-12);
  }
  for (i=0; i < 81; i++)
    if ((initialValues[i] > 0x30) && (initialValues[i] <= 0x3a))
      sudoku[i/9][i%9] = 1 << (initialValues[i] - 0x31) ;
}

void print_sudoku ( int style ) {
  int i, j, k;
  for (i=0; i < 9; i++) {
    for (j=0; j < 9; j++) {
      if ( ifOne(sudoku[i][j]) || !style) {
        for (k=0; k < 9; k++)
          if (sudoku[i][j] & 1<<k)
            printf("%d", k+1);
      } else
        printf("*");
      if ( !((j+1)%3) )
        printf("\t");
      else
        printf(",");
    }
    printf("\n");
    if (!((i+1) % 3) )
      printf("\n");
  }
}

void print_HTML_sudoku () {
  int i, j, k, l, m;
  printf("<TABLE>\n");
  for (i=0; i<3; i++) {
    printf("  <TR>\n");
    for (j=0; j<3; j++) {
      printf("    <TD><TABLE>\n");
      for (l=0; l<3; l++) { printf("      <TR>"); for (m=0; m<3; m++) { printf("<TD>"); for (k=0; k < 9; k++)  { if (sudoku[i*3+l][j*3+m] & 1<<k)
            printf("%d", k+1);
          }
          printf("</TD>");
        }
        printf("</TR>\n");
      }
    printf("    </TABLE></TD>\n");
    }
    printf("  </TR>\n");
  }
  printf("</TABLE>");
}



int doRow () {
  int count=0, new_value, row_value, i, j;
  for (i=0; i<9; i++) {
    row_value=0x1ff;
    for (j=0; j<9; j++)
      row_value&=~ifOne(sudoku[i][j]);
    for (j=0; j<9; j++) {
      new_value=sudoku[i][j] & row_value;
      if (new_value && (new_value != sudoku[i][j]) ) {
        count++;
        sudoku[i][j] = new_value;
      }
    }
  }
  return count;
}

int doCol () {
  int count=0, new_value, col_value, i, j;
  for (i=0; i<9; i++) {
    col_value=0x1ff;
    for (j=0; j<9; j++)
      col_value&=~ifOne(sudoku[j][i]);
    for (j=0; j<9; j++) {
      new_value=sudoku[j][i] & col_value;
      if (new_value && (new_value != sudoku[j][i]) ) {
        count++;
        sudoku[j][i] = new_value;
      }
    }
  }
  return count;
}

int doCube () {
  int count=0, new_value, cube_value, i, j, l, m;
  for (i=0; i<3; i++)
    for (j=0; j<3; j++) {
      cube_value=0x1ff;
      for (l=0; l<3; l++)
        for (m=0; m<3; m++)
          cube_value&=~ifOne(sudoku[i*3+l][j*3+m]);
      for (l=0; l<3; l++)
        for (m=0; m<3; m++) {
          new_value=sudoku[i*3+l][j*3+m] & cube_value;
          if (new_value && (new_value != sudoku[i*3+l][j*3+m]) ) {
            count++;
            sudoku[i*3+l][j*3+m] = new_value;
          }
        }
    }
  return count;
}

#define FALSE -1
#define TRUE 1
#define INCOMPLETE 0

int validCube () {
  int i, j, l, m, r, c;
  int pigeon;
  int solved=TRUE;

  //check horizontal
  for (i=0; i<9; i++) {
    pigeon=0;
    for (j=0; j<9; j++)
      if (ifOne(sudoku[i][j])) {
        if (pigeon & sudoku[i][j]) return FALSE;
        pigeon |= sudoku[i][j];
      } else {
        solved=INCOMPLETE;
      }
  }

  //check vertical
  for (i=0; i<9; i++) {
    pigeon=0;
    for (j=0; j<9; j++)
      if (ifOne(sudoku[j][i])) {
        if (pigeon & sudoku[j][i]) return FALSE;
        pigeon |= sudoku[j][i];
      }
      else {
        solved=INCOMPLETE;
      }
  }

  //check cube
  for (i=0; i<3; i++)
    for (j=0; j<3; j++) {
      pigeon=0;
      r=j*3; c=i*3;
      for (l=0; l<3; l++)
        for (m=0; m<3; m++)
        if (ifOne(sudoku[r+l][c+m])) {
          if (pigeon & sudoku[r+l][c+m]) return FALSE;
          pigeon |= sudoku[r+l][c+m];
        }
        else {
          solved=INCOMPLETE;
        }
    }

  return solved;
}

int solveSudoku(int position ) {
  int status, i, k;
  short oldCube[9][9];

  for (i=position; i < 81; i++) {

    while ( doCube() + doRow() + doCol() );

    status = validCube() ;
    if ((status == TRUE) || (status == FALSE))
      return status;


    if ((status == INCOMPLETE) && !ifOne(sudoku[i/9][i%9]) ) {
      memcpy( &oldCube, &sudoku, sizeof(short) * 81) ;
      for (k=0; k < 9; k++) {
        if ( sudoku[i/9][i%9] & (1<<k) ) {
          sudoku[i/9][i%9] = 1 << k ;
          if (solveSudoku(i+1) == TRUE ) {

            /* return TRUE; */
            /* Or look for entire set of solutions */

            if (cubeSolutions < 10) {
              cubeValues[cubeSolutions] = malloc ( sizeof(short) * 81 ) ;
              memcpy( cubeValues[cubeSolutions], &sudoku, sizeof(short) * 81) ;
            }

            cubeSolutions++;
            if ((cubeSolutions & 0x3ffff) == 0x3ffff ) {
              printf ("cubeSolutions = %llx\n", cubeSolutions+1 );
            }

            //if ( cubeSolutions > 10 ) 
            //    return TRUE;

          }

          memcpy( &sudoku, &oldCube, sizeof(short) * 81) ;
        }
        if (k==8)
          return FALSE;
      }

    }
  }

  return FALSE;
}


int main ( int argc, char** argv)  {
  int i;
  if (argc != 2) {
    printf("Error: number of arguments on command line is incorrect\n");
    exit (-12);
  }

  init_sudoku();
  set_sudoku(argv[1]);

  printf("[----------------------- Input  Data ------------------------]\n\n");
  print_sudoku(1);

  solveSudoku(0);
  if ((validCube()==1) && !cubeSolutions)  {
    // If sudoku is effectively already solved, cubeSolutions will not be set
    printf ("\n  This is a trivial sudoku. \n\n");
    print_sudoku(1);
  }


  if (!cubeSolutions && validCube()!=1)
    printf("Not Solvable\n");
  if (cubeSolutions > 1) {
    if (cubeSolutions >= 10)
      printf("10+ Solutions, returning first 10 (%lld) [%llx] \n", cubeSolutions, cubeSolutions);
    else
      printf("%llx Solutions. \n", cubeSolutions);
  }

  for (i=0; (i < cubeSolutions) && (i < 10); i++) {
    memcpy ( &sudoku, cubeValues[i], sizeof(short) * 81 );
    printf("[----------------------- Solution %2.2d ------------------------]\n\n", i+1);
    print_sudoku(0);
    //print_HTML_sudoku();
  }
  return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Grand Central Dispatch 并行化数独求解器? 的相关文章

  • C# 中的监视器与互斥体[重复]

    这个问题在这里已经有答案了 可能的重复 C 中各种线程同步选项之间有什么区别 https stackoverflow com questions 301160 what are the differences between various
  • 如何解决 MongoWaitQueueFullException?

    我运行一个java程序 它是一个线程执行程序 它将数千个文档插入到mongodb中的表中 我收到以下错误 Exception in thread pool 1 thread 301 com mongodb MongoWaitQueueFul
  • 多线程应用程序的调用方法?

    我的应用程序中有一个错误 与here http forums ni com t5 Measurement Studio for NET Waveform Graph quot X quot Error m p 217817 highligh
  • 同步不经常更新的哈希图的最佳方式

    我有一个在应用程序中使用的 HashMap 数据是在应用程序初始加载期间从数据库填充的 然后它始终只是读取并且从不更新 会有多个线程不断地读取数据 由于数据永远不会更新 因此我们目前不使用任何同步 仅使用 HashMap 我们现在定义的方式
  • 如何从 NSOperationQueue 中删除/取消 NSInitationOperation?

    以下两个问题都是在维护 NSOperationQueue 和 NSInvocableOperation 的上下文中提出的 由于我已经使用这个概念来下载多个视频 因此在下载视频完成后 如何从 NSOperationQueue 中删除 释放添加
  • 如何使用 Python 从 Azure Functions 中的辅助线程重定向日志

    我正在使用 Azure 函数运行启动多个线程的 Python 脚本 出于性能原因 一切都按预期工作 但 Azure Functions 日志中仅显示来自 main 线程的信息日志 我在 main 中启动的 辅助 线程中使用的所有日志都不会出
  • 在Java中,如何在每次进入或退出给定对象的监视器时记录一条消息?

    我正在尝试调试一些使用一些自定义引用计数 锁定的 C Java 绑定 我想让 JVM 在每次给定对象进入或退出其监视器时打印一条消息 有什么办法可以做到这一点吗 基本上 我想要这个 synchronized lock System out
  • Android SurfaceView onDraw 停止 Thread.join()

    我正在尝试开发一款游戏SurfaceView 问题是当我想摧毁thread用方法surfaceDestroyed 应用程序停止于thread join 但如果不这样做 绘制画布 canvas drawColor Color GREEN 在里
  • 完成后关闭线程

    完成后如何关闭线程 比如确保没有任何东西再打开或运行 到目前为止我知道如何打开它 但是 不知道如何正确关闭它 int iret1 pthread t thread1 char message1 void multithreading1 vo
  • JMeter:tearDown Thread Group的目的是什么

    我想了解JMeter中tearDown Thread Group的实际用法 在什么场景下可以使用tearDown Thread Group 根据提供的帮助JMeter 拆解线程组 http jmeter apache org userman
  • Socket.*Async 方法是线程化的吗?

    我目前正在尝试找出最小化 TCP 主服务器中使用的线程数量的最佳方法 以便最大限度地提高性能 由于我最近阅读了大量 C 5 0 的新异步功能 异步并不一定意味着多线程 这可能意味着将有限状态对象分成较小的块 然后通过交替与其他操作一起进行处
  • 为什么C++标准库中没有线程池? [复制]

    这个问题在这里已经有答案了 自 C 11 以来 C 中并行 并发编程工具的数量激增 线程 异步函数 并行算法 协程 但是流行的并行编程模式又如何呢 线程池 https en wikipedia org wiki Thread pool 据我
  • 单线程公寓问题

    从我的主窗体中 我调用以下命令来打开一个新窗体 MyForm sth new MyForm sth show 一切都很好 但是这个表单有一个组合框 当我将其 AutoCompleteMode 切换为建议和追加时 我在显示表单时遇到了这个异常
  • 没有公平性的DelayQueue有问题吗?

    在 Java 7 中 DelayQueue 的实现使用没有公平策略的 ReentrantLock 从长远来看 这是一个问题吗 线程会因此而饿死吗 Thanks 如果您考虑ScheduledThreadPoolExecutor 或任何其他生产
  • C++ 在循环中创建线程时出错

    我在 Visual Studio 2015 中运行以下命令时遇到问题 include
  • 基于多线程的 RabbitMQ 消费者

    我们有一个 Windows 服务 它监听单个 RabbitMQ 队列并处理消息 我们希望扩展相同的 Windows 服务 以便它可以监听 RabbitMQ 的多个队列并处理消息 不确定使用多线程是否可以实现这一点 因为每个线程都必须侦听 阻
  • 为什么 std::atomic 比 volatile bool 慢很多?

    多年来我一直使用 volatile bool 来控制线程执行 并且效果很好 in my class declaration volatile bool stop In the thread function while stop do th
  • 监控 Java 应用程序上的锁争用

    我正在尝试创建一个小基准 在 Groovy 中 以显示几个同步方法上的高线程争用 当监控自愿上下文切换时 应该会出现高争用 在 Linux 中 这可以通过 pidstat 来实现 程序如下 class Res private int n s
  • 如何在Python中使用多处理来加速循环执行

    我有两个清单 列表 A 包含 500 个单词 列表 B 包含 10000 个单词 我正在尝试为列表 A 找到与 B 相关的相似单词 我正在使用 Spacy 的相似函数 我面临的问题是计算需要很长时间 我是多处理使用的新手 因此请求帮助 如何
  • Android,Volley请求,响应阻塞主线程

    使用 Volley 处理较大响应时会发生一些不好的事情 String url AppHelper DOMAIN service pages profile update json this infoTextView setText getS

随机推荐

  • 箭头函数 - 为什么会将全局对象打印到控制台? [复制]

    这个问题在这里已经有答案了 为什么o foo 将全局对象打印到控制台 let o foo gt console log this bar console log this o foo Global object undefined o ba
  • “__COMPAT_LAYER”实际上是做什么的?

    最近 我试图给我应用程序管理员权限 无需系统询问 您想授予管理员权限吗 我找到了一种效果很好的方法 我找到的解决方案 我创建了一个名为的bat文件非管理员 bat并在其中写入以下代码 cmd min C set COMPAT LAYER R
  • 将 javah -jni 与 Eclipse 项目结构结合使用

    我需要知道我是否以错误的方式做事 我有以下项目结构 一个非常标准的结构 然后我已经配置了javah作为这样的外部工具 当我运行外部工具时OSManager4Windows java我期待着找到it univpm quickbackup ut
  • 分析 CherryPy

    我一直在尝试开始分析我的 CherryPy Web 服务器 但文档缺乏如何设置的详细信息 我明白我应该能够使用cherrypy lib profiler作为安装我的初始服务器的中间件 现在 我有如下代码 server app ServerC
  • 通配符子域和子文件夹作为 .htaccess 中的参数

    我有一个门户网站http www mysite com http www mysite com 客户在其中注册并获得自己的网站子域版本来运行我的应用程序 我已经设置了通配符子域 DNS VirtualHost 等并使其正常工作 我想要设置的
  • ASP.NET Core 中的服务器端图形

    我最近将 ASP NET MVC 应用程序从 ASP NET 升级到 ASP NET Core 在我的控制器操作中 我有一段依赖 System Drawing 来创建个人资料图片的代码 using FileStream stream new
  • 在 JUnit 测试中的 MockHttpServletRequest 中设置 @ModelAttribute

    我正在尝试测试 spring mvc 控制器 其中一种方法采用表单输入作为 POST 方法 该方法通过一个获取表单的commandObject ModelAttribute注解 如何使用 Spring 的 Junit 测试设置此测试用例 控
  • “在惯常位置找不到 Google Cloud SDK,并且未提供路径。”詹金斯

    我对詹金斯很陌生 但几天来我一直在寻找这个问题的答案 我在 localhost 8080 上运行 jenkins 我用 Java 编写了一个程序 它使用 gradle 部署到 Google App Engine 云 现在我想使用 Jenki
  • Tensorboard 陷入“命名空间层次结构寻找相似子图”的困境

    我尝试通过 Tensorboard 可视化 CNN 的迭代过程 但浏览器总是卡在 命名空间层次结构查找相似子图 中 然后崩溃 QAQ为什么会出现这种情况 我该如何修复它 陷入 命名空间层次结构寻找相似子图 的困境 https i stack
  • DBI::InterfaceError:无法加载驱动程序(未初始化常量 MysqlError)

    我已经包括了宝石 dbd mysql 0 4 4 dbi 0 4 5 mysql 2 8 1 当我运行以下代码时 在 Rails 控制台上 require rubygems require dbi require dbd mysql dbh
  • 增加边框宽度时如何防止相邻元素移动?

    我有一个由盒子组成的简单布局 action box width 300px height 200px border 1px solid black float left margin left 10px margin top 10px ac
  • iOS - 动画效果 - 图像弹出

    我希望 iPhone 应用程序中的图像能够 弹出 在屏幕上 而不仅仅是出现 我所说的 弹出 是指它会从小点增长到实际大小 作为参考 这与 Keynote 中的 pop 动画效果完全相同 我对 iOS 动画完全陌生 所以如果有人能指出我需要使
  • Wordpress EC2 上的永久链接

    我刚刚将我的博客从本地网络服务器转移到 Amazon EC2 Free Linux 服务器 现在除了永久链接之外一切似乎都正常 我禁用并重新启用它们 但它仍然中断 我尝试过运行脚本 sudo a2enmod rewrite 但它说 a2en
  • 又名获取计划。又名获取组。 QueryDSL 中的实体图

    我无法找到任何在 QueryDSL 中实现获取计划的方法 我尝试了很多 你能为我提供任何提示吗 另外 您是否知道在不同情况下选择要获取哪些字段以及延迟加载哪些字段的更好方法 我使用批量获取 因此无法使用 JOIN FETCH 使用这样的 E
  • 选择包含日语字符的 MySQL 行

    有人知道一种可靠的方法 使用 mySQL 或其他方式 来选择数据库中包含日语字符的行吗 我的数据库中有很多行 其中一些仅包含字母数字字符 其中一些包含日语字符 当您遇到字符集问题时的规则 创建数据库时使用utf8编码 CREATE DATA
  • webpack 从多个入口文件导出类

    我正在使用 webpack 捆绑一个框架供第三方使用 该框架应该公开多个 ES6 类 我以模块化方式构建 每个文件编写一个类 我想要做的是将所有这些文件构建在一起 并将它们捆绑在给定的 命名空间 下 例子 苹果 jsexport class
  • 从字符串获取python类对象[重复]

    这个问题在这里已经有答案了 可能的重复 Python 中的动态模块导入 https stackoverflow com questions 301134 dynamic module import in python 可能是一个简单的问题
  • 运行 Maven 安装时如何跳过许可证检查?

    I ran a mvn clean install在我从事的一个大型 Java 项目中 由于某些文件没有正确的许可证头 该项目一直失败 好吧 这不是我现在关心的问题 我该如何跳过呢 我看到的实际错误是 Failed to execute g
  • 计算 Java 函数的签名

    有没有办法computeJava 类的方法的签名 一个签名 like Ljava lang String V表示一个函数 它采用String 作为论据并返回void 什么是rule计算签名 它始终是一组括号 其中包含参数的类型指示符 一个接
  • 如何使用 Grand Central Dispatch 并行化数独求解器?

    作为编程练习 我刚刚编写了一个使用回溯算法的数独求解器 请参阅维基百科 http en wikipedia org wiki Algorithmics of sudoku Example of a brute force Sudoku so