当前位置: 首页 > 编程日记 > 正文

Prolog学习:数独和八皇后问题

上一篇简单介绍了下Prolog的一些基本概念,今天我们来利用这些基本概念解决两个问题:数独八皇后问题。

数独

数独是一个很经典的游戏:

玩家需要根据n×n盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-n,不重复。

当然数独的阶有很多,9×9是最常见的,我们就以它做例子。在用Prolog解决之前先想想如果我们用C#或Java来做或怎么做?无非就是数据结构加算法,我们先得用一个数据结构表示数独,然后我们要在这个数据结构上“施加”算法进行求解。采用Prolog的第一步是相同的,我们得找一个数据结构表示数独,毫无疑问在Prolog中我们只能选择列表或元组,这里列表是更好的选择,因为列表可以进行[Head|Tail]解析,后面你就知道为什么了。我们像下面这样表示一个数独:

[_, 6, _, 5, 9, 3, _, _, _,9, _, 1, _, _, _, 5, _, _,_, 3, _, 4, _, _, _, 9, _,1, _, 8, _, 2, _, _, _, 4,4, _, _, 3, _, 9, _, _, 1,2, _, _, _, 1, _, 6, _, 9,_, 8, _, _, _, 6, _, 2, _,_, _, 4, _, _, _, 8, _, 7,_, _, _, 7, 8, 5, _, 1, _] 

“_”代表未知的数字,需要玩家填空的地方。

接下来的步骤跟命令式语言就截然不同了,我们不是描述算法,而是要描述数独这个游戏的规则:

  1. 给定玩家一个9×9的盘面,玩家填充完所有的空格后最终的解仍然是这个9×9的盘面;
  2. 填充完空格后,每一个空格内的数字均在1~9之内;
  3. 填充完空格后,每一行9个数字各不相同;
  4. 填充完空格后,每一列9个数字各不相同;
  5. 填充完空格后,每一个宫格内的数字各不相同。

Ok,这就是整个游戏的规则。你可能觉得第一条规则没什么用,实际上第一条规则定义了“解”的形式,就像在C#中我们确定了方法的签名一样:

sudoku(Puzzle,Solution):- Solution = Puzzle.

事实上这个规则已经可以工作了:

| ?- sudoku([1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9, 1,2,3,4,5,6,7,8,9, 1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9],Solution). Solution = [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9......

当然这只是第一步,这个规则对于输入的数独形式没有任何限制,事实上可以是任意的列表,Prolog都返回yes:

| ?- sudoku([1,2,3],Solution).Solution = [1,2,3]yes

我们需要规定下数独的形式:

sudoku(Puzzle,Solution):-Solution = Puzzle,Puzzle = [S11,S12,S13,S14,S15,S16,S17,S18,S19,S21,S22,S23,S24,S25,S26,S27,S28,S29,S31,S32,S33,S34,S35,S36,S37,S38,S39,S41,S42,S43,S44,S45,S46,S47,S48,S49,S51,S52,S53,S54,S55,S56,S57,S58,S59,S61,S62,S63,S64,S65,S66,S67,S68,S69,S71,S72,S73,S74,S75,S76,S77,S78,S79,S81,S82,S83,S84,S85,S86,S87,S88,S89,S91,S92,S93,S94,S95,S96,S97,S98,S99].
| ?- sudoku([1,2,3],Solution).no

我们接着看第二条规则:“填充完空格后,每一个空格内的数字均在1~9之内” 。上一篇文章中我们介绍了Prolog中有一个内置谓词叫fd_domain,这时候就可以派上用场了:

sudoku(Puzzle,Solution):-Solution = Puzzle,Puzzle = [S11,S12,S13,S14,S15,S16,S17,S18,S19,S21,S22,S23,S24,S25,S26,S27,S28,S29,S31,S32,S33,S34,S35,S36,S37,S38,S39,S41,S42,S43,S44,S45,S46,S47,S48,S49,S51,S52,S53,S54,S55,S56,S57,S58,S59,S61,S62,S63,S64,S65,S66,S67,S68,S69,S71,S72,S73,S74,S75,S76,S77,S78,S79,S81,S82,S83,S84,S85,S86,S87,S88,S89,S91,S92,S93,S94,S95,S96,S97,S98,S99],fd_domain(Puzzle,1,9).

好了现在我们只能输入9×9并且每个每个位置上只能是1~9之间的数的列表了。

好了,现在到整个游戏的关键规则,事实上2,3,4这三个规则才决定了数独的难度,1,2只不过是基础,我们来统一考虑这三个问题。这里其实比想象的简单多了。我们首先要做的就是需要定义出来宫格

Row1 = [S11,S12,S13,S14,S15,S16,S17,S18,S19],
Row2 = [S21,S22,S23,S24,S25,S26,S27,S28,S29],
Row3 = [S31,S32,S33,S34,S35,S36,S37,S38,S39],
Row4 = [S41,S42,S43,S44,S45,S46,S47,S48,S49],
Row5 = [S51,S52,S53,S54,S55,S56,S57,S58,S59],
Row6 = [S61,S62,S63,S64,S65,S66,S67,S68,S69],
Row7 = [S71,S72,S73,S74,S75,S76,S77,S78,S79],
Row8 = [S81,S82,S83,S84,S85,S86,S87,S88,S89],
Row9 = [S91,S92,S93,S94,S95,S96,S97,S98,S99],Col1 = [S11,S21,S31,S41,S51,S61,S71,S81,S91],
Col2 = [S12,S22,S32,S42,S52,S62,S72,S82,S92],
Col3 = [S13,S23,S33,S43,S53,S63,S73,S83,S93],
Col4 = [S14,S24,S34,S44,S54,S64,S74,S84,S94],
Col5 = [S15,S25,S35,S45,S55,S65,S75,S85,S95],
Col6 = [S16,S26,S36,S46,S56,S66,S76,S86,S96],
Col7 = [S17,S27,S37,S47,S57,S67,S77,S87,S97],
Col8 = [S18,S28,S38,S48,S58,S68,S78,S88,S98],
Col9 = [S19,S29,S39,S49,S59,S69,S79,S89,S99],Square1 = [S11,S12,S13,S21,S22,S23,S31,S32,S33],
Square2 = [S14,S15,S16,S24,S25,S26,S34,S35,S36],
Square3 = [S17,S18,S19,S27,S28,S29,S37,S38,S39],
Square4 = [S41,S42,S43,S51,S52,S53,S61,S62,S63],
Square5 = [S44,S45,S46,S54,S55,S56,S64,S65,S66],
Square6 = [S47,S48,S49,S57,S58,S59,S67,S68,S69],
Square7 = [S71,S72,S73,S81,S82,S83,S91,S92,S93],
Square8 = [S74,S75,S76,S84,S85,S86,S94,S95,S96],
Square9 = [S77,S78,S79,S87,S88,S89,S97,S98,S99],

上一篇文章中我还提到一个谓词叫fd_all_different:检查列表中是否有重复元素,接下来我们只要证明每一列,每一行,每一个宫格列表内没有重复元素就可以了:

fd_all_different(Row1),
fd_all_different(Row2),
……
fd_all_different(Col1),
fd_all_different(Col2),
……
fd_all_different(Square1),
fd_all_different(Square2),
……

其实到此这个解数独的程序已经结束了,不过最后这几行代码太土了,我们可以采用用递归“优化”下,像下面这样:

valid([]).
valid([Head|Tail]):-fd_all_different(Head),valid(Tail).
valid([Row1,Row2,Row3,Row4,Row5,Row6,Row7,Row8,Row9,Col1,Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Square1,Square2,Square3,Square4,Square5,Square6,Square7,Square8,Square9]).

不管你信不信,我们已经搞定了,最终完整的代码如下:

valid([]).
valid([Head|Tail]):-fd_all_different(Head),valid(Tail).
sudoku(Puzzle,Solution):-Solution = Puzzle,Puzzle = [S11,S12,S13,S14,S15,S16,S17,S18,S19,S21,S22,S23,S24,S25,S26,S27,S28,S29,S31,S32,S33,S34,S35,S36,S37,S38,S39,S41,S42,S43,S44,S45,S46,S47,S48,S49,S51,S52,S53,S54,S55,S56,S57,S58,S59,S61,S62,S63,S64,S65,S66,S67,S68,S69,S71,S72,S73,S74,S75,S76,S77,S78,S79,S81,S82,S83,S84,S85,S86,S87,S88,S89,S91,S92,S93,S94,S95,S96,S97,S98,S99],fd_domain(Puzzle,1,9),Row1 = [S11,S12,S13,S14,S15,S16,S17,S18,S19],Row2 = [S21,S22,S23,S24,S25,S26,S27,S28,S29],Row3 = [S31,S32,S33,S34,S35,S36,S37,S38,S39],Row4 = [S41,S42,S43,S44,S45,S46,S47,S48,S49],Row5 = [S51,S52,S53,S54,S55,S56,S57,S58,S59],Row6 = [S61,S62,S63,S64,S65,S66,S67,S68,S69],Row7 = [S71,S72,S73,S74,S75,S76,S77,S78,S79],Row8 = [S81,S82,S83,S84,S85,S86,S87,S88,S89],Row9 = [S91,S92,S93,S94,S95,S96,S97,S98,S99],Col1 = [S11,S21,S31,S41,S51,S61,S71,S81,S91],Col2 = [S12,S22,S32,S42,S52,S62,S72,S82,S92],Col3 = [S13,S23,S33,S43,S53,S63,S73,S83,S93],Col4 = [S14,S24,S34,S44,S54,S64,S74,S84,S94],Col5 = [S15,S25,S35,S45,S55,S65,S75,S85,S95],Col6 = [S16,S26,S36,S46,S56,S66,S76,S86,S96],Col7 = [S17,S27,S37,S47,S57,S67,S77,S87,S97],Col8 = [S18,S28,S38,S48,S58,S68,S78,S88,S98],Col9 = [S19,S29,S39,S49,S59,S69,S79,S89,S99],Square1 = [S11,S12,S13,S21,S22,S23,S31,S32,S33],Square2 = [S14,S15,S16,S24,S25,S26,S34,S35,S36],Square3 = [S17,S18,S19,S27,S28,S29,S37,S38,S39],Square4 = [S41,S42,S43,S51,S52,S53,S61,S62,S63],Square5 = [S44,S45,S46,S54,S55,S56,S64,S65,S66],Square6 = [S47,S48,S49,S57,S58,S59,S67,S68,S69],Square7 = [S71,S72,S73,S81,S82,S83,S91,S92,S93],Square8 = [S74,S75,S76,S84,S85,S86,S94,S95,S96],Square9 = [S77,S78,S79,S87,S88,S89,S97,S98,S99],valid(Row1,Row2,Row3,Row4,Row5,Row6,Row7,Row8,Row9,Col1,Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Square1,Square2,Square3,Square4,Square5,Square6,Square7,Square8,Square9).

反正我信了,我们来试试吧,就以上面我从百度上找到的那个图为例:

| ?- sudoku([_, 6, _, 5, 9, 3, _, _, _,9, _, 1, _, _, _, 5, _, _,_, 3, _, 4, _, _, _, 9, _,1, _, 8, _, 2, _, _, _, 4,4, _, _, 3, _, 9, _, _, 1,2, _, _, _, 1, _, 6, _, 9,_, 8, _, _, _, 6, _, 2, _,_, _, 4, _, _, _, 8, _, 7,_, _, _, 7, 8, 5, _, 1, _],Solution).Solution = [7,6,2,5,9,3,1,4,8,9,4,1,2,7,8,5,3,6,8,3,5,4,6,1,7,9,2,1,9,8,6,2,7,3,5,4,4,7,6,3,5,9,2,8,1,2,5,3,8,1,4,6,7,9,3,8,7,1,4,6,9,2,5,5,1,4,9,3,2,8,6,7,6,2,9,7,8,5,4,1,3]

美化后的结果是这样的:

[7,6,2,5,9,3,1,4,8,9,4,1,2,7,8,5,3,6,8,3,5,4,6,1,7,9,2,1,9,8,6,2,7,3,5,4,4,7,6,3,5,9,2,8,1,2,5,3,8,1,4,6,7,9,3,8,7,1,4,6,9,2,5,5,1,4,9,3,2,8,6,7,6,2,9,7,8,5,4,1,3]

Perfect!

八皇后问题

Ok,有了数独问题作为铺垫,下面看八皇后问题应该就应该没那么难了,请保持用Prolog思考问题的方式,解决后你会发现Prolog真是这方面的“专家”,Let's Go!

八皇后问题也是一个非常经典的问题:

八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

老套路我们先描述游戏规则。

  1. 每个皇后有一个行号和列号,行号和列号的取值范围在1~8之间;
  2. 一个棋盘上有八个皇后;
  3. 任意两个皇后不可以共享一行;
  4. 任意两个皇后不可以共享一列;
  5. 任意两个皇后不可以在同一个对角线上(左下角->右上角);
  6. 任意两个皇后不可以在同一个对角线上(右下角->左上角)。

在了解规则之后我们梳理一下这个问题,对照上面这个图:

我们给棋盘上每一个位置设定一个坐标(x,y),八个皇后的坐标分别为(x1,y1),(x2,y2)……我们以回溯的角度看问题,假设如图已经得到了最后解,那么这8个坐标满足:x1,x2……各不相同,y1,y2……个不相同,找出(x1,y1),(x2,y2)……中属于对角线1上的和对角线2上的位置,它们坐标应该个不相同。

(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8)
(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(2,8)
(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),(3,7),(3,8)
(4,1),(4,2),(4,3),(4,4),(4,5),(4,6),(4,7),(4,8)
(5,1),(5,2),(5,3),(5,4),(5,5),(5,6),(5,7),(5,8)
(6,1),(6,2),(6,3),(6,4),(6,5),(6,6),(6,7),(6,8)
(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),(7,7),(7,8)
(8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8)

所以整个问题的难点在于给定类似下面这样一个列表,我们需要找出其中的所有的行号,列号,和在对角线上的坐标:

[(1,1),(1,5),(2,5),(2,2),(8,8),(4,4),(4,5),(5,4)]

找出行号和列号稍微简单点,这里直接给出答案,大家也可以自己思考下:

rows([],[]).
rows([(Row,_)|QueensTail],[Row|RowsTail]):-rows(QueensTail,RowsTail).
cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-cols(QueensTail,ColsTail).

把上面的列表代进去简单验证下:

| ?- rows([(1,1),(1,5),(2,5),(2,2),(8,8),(4,4),(4,5),(5,4)],Rows).Rows = [1,1,2,2,8,4,4,5]yes
| ?- cols([(1,1),(1,5),(2,5),(2,2),(8,8),(4,4),(4,5),(5,4)],Cols).Cols = [1,5,5,2,8,4,5,4]yes

关键是如何验证对角线上的元素,而且两条对角线是不一样的,提醒下因为我们最后会还是会利用fd_all_different这个谓词。

好吧,我们回过头观察下上面那个棋盘的坐标图(注意我标红的地方),有没有发现什么规则呢?

  • 左上角到右下角的对角线上的元素:所有坐标的横坐标-纵坐标都相同,等于0;
  • 左下角到右上角的对角线上的元素:所有坐标的横坐标+纵坐标都相同,等于9;

OK,我们可以定义下面这样两个谓词diags1和diags2:

diags1([],[]).
diags1([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-Diagonal is Col - Row,diags1(QueensTail,DiagonalsTail).
diags2([],[]).
diags2([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-Diagonal is Col + Row,diags2(QueensTail,DiagonalsTail).

我们可以简单验证下:

| ?- diags1([(2,2),(8,8)],Diags1).Diags1 = [0,0]yes

| ?- diags2([(4,5),(5,4)],Diags2).

 Diags2 = [9,9]

yes

如果坐标在对角线上,那么抓取到的列表元素都是相等的。

好了,到目前为止我们已经完成了最难的部分,剩下的都是一些验证性工作。我们最终的“程序入口”应该是这样的:

eight_queens([(X1,Y1),(X2,Y2),(X3,Y3),(X4,Y4),(X5,Y5),(X6,Y6),(X7,Y7),(X8,Y8)])

我们还需要一些验证性工作:

1.给定列表里的皇后是不是合法的,即横纵坐标都在1~8之内,这用到了我上一篇中提到的member谓词:

valid_queen((Row,Col)):-Range = [1,2,3,4,5,6,7,8],member(Row,Range),member(Col,Range).

2.验证给定的列表是不是八个皇后,这里用到一个length谓词,顾名思义:

length(Board,8).

3.需要递归的验证给定的列表中的每个元素是不是“皇后”:

valid_board([]).
valid_board([Head|Tail]):- valid_queen(Head),valid_board(Tail).

Ok,下面就是八皇后问题的答案的完整代码:

valid_queen((Row,Col)):-Range = [1,2,3,4,5,6,7,8],member(Row,Range),member(Col,Range).valid_board([]).
valid_board([Head|Tail]):- valid_queen(Head),valid_board(Tail).rows([],[]).
rows([(Row,_)|QueensTail],[Row|RowsTail]):-rows(QueensTail,RowsTail).cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-cols(QueensTail,ColsTail).diags1([],[]).
diags1([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-Diagonal is Col - Row,diags1(QueensTail,DiagonalsTail).diags2([],[]).
diags2([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-Diagonal is Col + Row,diags2(QueensTail,DiagonalsTail).eight_queens(Board) :-length(Board,8),valid_board(Board),rows(Board,Rows),cols(Board,Cols),diags1(Board,Diags1),diags2(Board,Diags2),fd_all_different(Rows),fd_all_different(Cols),fd_all_different(Diags1),fd_all_different(Diags2).   

没错,答案已经出来,但事实上上面这个程序运行的非常慢,我在我i7的笔记本上的GNU Prolog中执行下面这个问题,半天没有响应:

| ?- eight_queens([(X1,Y1),(X2,Y2),(X3,Y3),(X4,Y4),(X5,Y5),(X6,Y6),(X7,Y7),(X8,Y8)]).

其实我们可以对这个问题进行一个简化。我们可以肯定棋盘上八行每行肯定有一个皇后,又因为互不能在一行,因此我们假设八皇后的坐标分别为:(1,A),(2,B),(3,C),(4,D),(5,E),(6,F),(7,G),(8,H)。那么我们可以对上面的代码进行优化,去掉所有对行的操作,优化后代码如下:

valid_queen((Row,Col)):- member(Col,[1,2,3,4,5,6,7,8]).valid_board([]).
valid_board([Head|Tail]):- valid_queen(Head),valid_board(Tail).cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-cols(QueensTail,ColsTail).diags1([],[]).
diags1([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-Diagonal is Col - Row,diags1(QueensTail,DiagonalsTail).diags2([],[]).
diags2([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-Diagonal is Col + Row,diags2(QueensTail,DiagonalsTail).eight_queens(Board) :-Board = [(1,_),(2,_),(3,_),(4,_),(5,_),(6,_),(7,_),(8,_)],length(Board,8),valid_board(Board),cols(Board,Cols),diags1(Board,Diags1),diags2(Board,Diags2),fd_all_different(Cols),fd_all_different(Diags1),fd_all_different(Diags2).

然后这样问问题:

eight_queens([(1,Y1),(2,Y2),(3,Y3),(4,Y4),(5,Y5),(6,Y6),(7,Y7),(8,Y8)]).
| ?- eight_queens([(1,Y1),(2,Y2),(3,Y3),(4,Y4),(5,Y5),(6,Y6),(7,Y7),(8,Y8)]).Y1 = 1
Y2 = 5
Y3 = 8
Y4 = 6
Y5 = 3
Y6 = 7
Y7 = 2
Y8 = 4 ? aY1 = 1
Y2 = 6Y1 = 2
Y2 = 7
Y3 = 3
Y4 = 6
Y5 = 8
Y7 = 6
Y8 = 3Y1 = 2
Y2 = 8
Y3 = 6
Y4 = 1
Y5 = 3
Y6 = 5
Y7 = 7
Y8 = 4Y1 = 3
Y2 = 1
Y3 = 7
Y4 = 5
Y5 = 8
Y6 = 2
Y7 = 4
Y8 = 6
……
Y1 = 8
Y2 = 3
Y3 = 1
Y4 = 6
Y5 = 2
Y6 = 5
Y7 = 7
Y8 = 4Y1 = 8
Y2 = 4
Y3 = 1
Y4 = 3
Y5 = 6
Y6 = 2
Y7 = 7
Y8 = 5(81860 ms) no

?后跟a可以一次性询问所有答案,可以看到还是相当的慢,这也算是声明式语言的一个劣势吧。

好了,今天介绍的两个问题就到此结束了。问题本身并不是重点,重点是我们思考问题的方式。

最后提供:源代码下载,希望大家可以喜欢Prolog这门小巧简单,功能强大的语言。

转载于:https://www.cnblogs.com/zhanjindong/p/3331528.html

相关文章:

每年节省170万美元的文档预览费用,借助机器学习的DropBox有多强​?

【CSDN 编者按】Dropbox 借助机器学习的预测功能,每年能为公司节省了一百多七十多万美元的基础架构成本。非常了不起的成就。本文,一起来看一看 Dropbox 采用机器学习的经过,以及分析一下其中的利弊。译者 | 弯月 责编 | 张文出品 | CSDN&a…

asp.net 对xml文件的读写,添加,修改,删除操作

asp.net 对xml文件的读写,添加,修改,删除操作 下面有代码调试正确 using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using…

阿里重金投数梦工场 布局PaaS动了谁的奶酪

就目前云计算市场来看,巨头的争夺表面上还在IaaS激战,但实际上他们对PaaS也在默默布局。6月8日,PaaS相关服务商数梦工场宣布完成光大实业资本、阿里巴巴等公司共同投资的7.5亿元A轮融资。值得注意的是,阿里巴巴是几位投资方中唯一…

ASP.net中太长的数据缩略显示

问题&#xff1a;用<%# DataBinder.Eval(Container.DataItem,"NewsID"&#xff09;%>显示数据的&#xff0c;如果标题太长了怎么规定字数&#xff0c;多余的用"..."代替解决方法&#xff1a; 1.使用后台代码解决&#xff1a; cs文件代码&#xff1a;…

再见 for 循环!pandas 提速 315 倍~

for是所有编程语言的基础语法&#xff0c;初学者为了快速实现功能&#xff0c;依懒性较强。但如果从运算时间性能上考虑可能不是特别好的选择。本次东哥介绍几个常见的提速方法&#xff0c;一个比一个快&#xff0c;了解pandas本质&#xff0c;才能知道如何提速。下面是一个例子…

UVa 374 - Big Mod

题目大意&#xff1a;计算R BP mod M&#xff0c;根据模运算的性质计算。 正常计算会超时&#xff0c;可以用分治的思想降低时间复杂度。不过如果遇到00&#xff0c;结果...话说00的结果是1吗&#xff1f;忘了都... 1 #include <cstdio>2 3 int powMod(int base, int ex…

微软在慕尼黑设立欧洲首个物联网实验室

北京时间3月30日晚间消息&#xff0c;微软今日在慕尼黑设立了其在欧洲的首个物联网实验室。在此之前&#xff0c;微软已经在雷德蒙(Redmond)总部和中国深圳设立了物联网实验室。 慕尼黑是德国许多知名大企业的故乡&#xff0c;如宝马和西门子等。在此之前&#xff0c;思科和IBM…

linux的strace命令

linux的strace命令 strace 命令是一种强大的工具&#xff0c;它能够显示所有由用户空间程序发出的系统调用。 strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息&#xff0c;而且不需要以任何特殊的方式来构建内核。 下面记录几个常用 option . …

明年,我要用 AI 给全村写对联

作者 | 神经小兮来源 | HyperAI超神经春节已经过完&#xff0c;你是否还沉浸在年味里&#xff1f;到腊月二十九、三十&#xff0c;家家户户贴上了 红红的春联&#xff0c;春节就正式拉开了序幕。春联也称为「对联」、「门对」、「楹联」&#xff0c;是汉语所独有的一种艺术形式…

C++实现int与string之间的相互转换

2019独角兽企业重金招聘Python工程师标准>>> c 利用stringstream实现int与string类型的相互转换&#xff0c;记录在此&#xff0c;以备后用 #include<iostream> #include<sstream> #include<string>using namespace std;string add_int(const st…

逆变器的技术创新 让光伏电站更具发展前景

曾几何时&#xff0c;光伏发电因为光照强度和温度的变化&#xff0c;逆变器输出功率波动大&#xff0c;对电网产生冲击&#xff0c;而被称为垃圾电而受到限制。随着技术的进步&#xff0c;光伏逆变器完善了多种保护功能&#xff0c;增加了低&#xff08;零&#xff09;电压穿越…

8个免费实用的C++GUI库

C标准中并没有包含GUI&#xff0c;这也使得C开发图形化界面需要依赖于第三方的库。实际上&#xff0c;图形界面恰恰是C的强项&#xff0c;小到平常使用的各类桌面软件&#xff0c;大到魔兽世界这样的游戏&#xff0c;都是C擅长的地方。C之所以能做到这一点&#xff0c;原因在于…

.Net2.0 使用ConfigurationManager读写配置文件

.net1.1中如果需要灵活的操作和读写配置文件并不是十分方便&#xff0c;一般都会在项目中封装一个配置文件管理类来进行读写操作。而在.net2.0中使用ConfigurationManager 和WebConfigurationManager 类可以很好的管理配置文件&#xff0c;ConfigurationManager类在System.Conf…

举个例子,如何用GCN图卷积神经网络实现摔倒监测?

作者 | 李秋键责编 | 寇雪芹头图 | 下载于视觉中国引言近几年来深度学习的发展越来越火热&#xff0c;其中最为典型的就是半监督学习的新研究进展GCN。由Kipf和Welling提出的GCN被证明是一种有效的图半监督学习框架应用&#xff0c;如社会、医疗、商业和交通网络分析&#xff0…

数据中心节能大法 —— 尽在上海11月中国数据中心展

根据调研机构451Research的预测&#xff0c;全球数据中心托管市场2018年的市场规模将达到332亿美元。据悉&#xff0c;2015年我国数据中心节能改造规模已达30亿元左右&#xff0c;数据中心节能市场的空间是非常大的&#xff0c;在未来有望达到85亿元的市场空间。 根据调研机构4…

古怪的ConfigurationManager类

开始使用VS 2005&#xff0c;习惯性的使用ConfigurationSettings类来读取应用程序配置文件的信息时&#xff0c;却被编译器提示说&#xff1a;警告 1 “System.Configuration.ConfigurationSettings.AppSettings”已过时:“This method is obsolete, it has been replaced by …

最常用的css选择器及兼容性 +几个好用却不多见的 nth-child等

你也许已经掌握了id、class、后台选择器这些基本的css选择器。但这远远不是css的全部。下面向大家系统的解析css中30个最常用的选择器&#xff0c;包括我们最头痛的浏览器兼容性问题。掌握了它们&#xff0c;才能真正领略css的巨大灵活性。 1. * * { margin: 0; paddin…

对比四种爬虫定位元素方法,你更爱哪个?

作者 | 陈熹来源 | 早起Python头图 | 下载于视觉中国在使用Python本爬虫采集数据时&#xff0c;一个很重要的操作就是如何从请求到的网页中提取数据&#xff0c;而正确定位想要的数据又是第一步操作。本文将对比几种 Python 爬虫中比较常用的定位网页元素的方式供大家学习&…

2017年安全漏洞审查报告:安全补丁在不断增加,用户却不安装

软件漏洞难修复吗&#xff1f;年度FLexera漏洞审查报告显示&#xff0c;全部安全漏洞当中有81%已经拥有与之匹配的修复补丁&#xff0c;但多数常见软件项目的补丁安装率却相当低下。 作为一家面向应用程序开发商与企业客户的软件安全漏洞管理解决方案厂商&#xff0c;Flexera S…

Visual SourceSafe简明培训教程

名称Visual SourceSafe简明培训教程(Visual SourceSafe Training Short Course) 作者晨光&#xff08;Morning&#xff09; 简介对于采用Visual SourceSafe 6.0作为版本控制工具的项目及产品开发&#xff0c;本教程针对不同用户角色&#xff0c;提供有关该软件的若干使用指导…

水母智能联合蚂蚁森林、犀牛智造等,用AI助力非遗出圈,39万人开工得“福”

如今过年越来越有年味了&#xff0c;许多淡出已久的中国传统年俗&#xff0c;以更有趣、更年轻新潮、更科技的方式回到了大家身边。集五福、写福字、贴福字&#xff0c;挂福饰品&#xff0c;当然还有接“福袋”&#xff01;人工智能实现智能设计已经相当成熟&#xff0c;已有微…

绿色信托任重道远 应建立补偿机制?

作为绿色金融的分支之一&#xff0c;绿色信托面临的状况不如绿色信贷、绿色债券&#xff0c;整体规模尚小&#xff0c;且监管方面的鼓励措施未有明确&#xff0c;甚至连概念都尚未统一。 日前&#xff0c;北京大学法学院非营利组织法研究中心与中航信托联合发布《2016年绿色信托…

解读C#正则表达式

多少年来&#xff0c;许多的编程语言和工具都包含对正则表达式的支持&#xff0c;.NET基础类库中包含有一个名字空间和一系列可以充分发挥规则表达式威力的类&#xff0c;而且它们也都与未来的Perl 5中的规则表达式兼容。 此外&#xff0c;regexp类还能够完成一些其他的功能&am…

wpa_supplicant学习

2019独角兽企业重金招聘Python工程师标准>>> interface gtk makefile wrapper buffer methods 目录(?)[-] 本来以为这个东西只有在Atheros的平台上用的突然发现Ralink的平台也可以用甚至还看到还有老美把这个东西往android上移植看来是个好东西学习一下 官方…

一张图,看编程语言十年热度变化

作者 | 叶庭云来源 | 修炼Python头图 | 下载于视觉中国什么是 TIOBE 排行榜TIOBE 排行榜是根据互联网上有经验的程序员、课程和第三方厂商的数量&#xff0c;并使用搜索引擎&#xff08;如Google、Bing、Yahoo!&#xff09;以及Wikipedia、Amazon、YouTube 统计出排名数据&…

小扎的野心不止做社交 市政厅的上线说明了这一点

一个月前&#xff0c;扎克伯格刚在一封6千字长信里宣布了自己要做一个全球社区的理想&#xff0c;日前Facebook就上线了个叫“市政厅”的政务服务功能。 美国的用户在“市政厅”的功能页填写完自己的地理位置信息之后&#xff0c;可以看到当地政府官员的名单&#xff0c;包括美…

C#调用存储过程简单完整例子

CREATE PROC P_TEST Name VARCHAR(20), Rowcount INT OUTPUT AS BEGINSELECT * FROM T_Customer WHERE NAMENameSET RowcountROWCOUNT END GO ---------------------------------------------------------------------------------------- --存储过程调用如下: -------------…

高手的习惯:pythonic风格代码

来源 | Python大数据分析责编 | 寇雪芹头图 | 下载于视觉中国什么是pythonicpythonic是开发者们在写python代码过程中总结的编程习惯&#xff0c;崇尚优雅、明确、简单。就好比中文的笔画&#xff0c;讲究先后顺序&#xff0c;最符合文字书写的习惯。因为是习惯&#xff0c;不是…

计算机天才Aaron Swartz 名作 《如何提高效率》——纪念真正的“hacker!

如何提高效率 《HOWTO: Be more productive》&#xff08;如何提高效率&#xff09;作者&#xff1a;Aaron Swartz 肯定有人跟你说过这样的话&#xff0c;“你有看电视的那么长时间&#xff0c;都可以用来写一本书了”。不可否认写书肯定比看电视更好的利用了时间&#xff0c;但…

python的web压力测试工具-pylot安装使用

pylot是python编写的一款web压力测试工具。使用比较简单。而且测试结果相对稳定。 这里不得不鄙视一下apache 的ab测试&#xff0c;那结果真是让人蛋疼&#xff0c;同样的url&#xff0c;测试结果飘忽不定&#xff0c;看得人心惊肉跳&#xff0c;摸不着头脑。 下载 pylot官网&a…