使用“与非”门构建一个4-vertex Connectedness Tester


12

连接图形是包含任意两个顶点之间的路径的曲线图。

挑战

建立一个[2-input NAND-gate]电路,确定是否连接了4-vertex图。
(一个门的2个输入可以是相同的输入位或另一个门。)
如果已连接图形,则输出True,否则输出False。

输入值

具有4个顶点的简单图的六个可能的边:

[ 0 ë 10 ë 21 ë 20 ë 31 ë 32 ë 3 ]

其中 e b表示顶点ab之间是否存在边

连接等于以下条件:

  • 如果少于3个输入为True,则输出False。

  • 如果三个以上输入为True,则输出True。

  • 如果恰好3个输入为True,并且它们形成一个三角形,则输出False。

  • 否则,输出True。

使用最少门的答案将获胜。结将被
最低的电路深度(从输入到输出的最长路径的长度)破坏 。


您可以进一步指定输入格式吗?
LegionMammal978 '16

iej是从顶点 i到顶点 j 的,是否为True或False 。

输入可以当作01吗?输出怎么样?
TheCoffeeCup

3
@TheCoffeeCup这是逻辑电路设计问题,而不是代码高尔夫球
lirtosiast '16

@ThomasKwa哎呀,没有注意到。
TheCoffeeCup

Answers:


4

30个NAND

与其问何时获得1,不如问我们何时获得0。最好这样问,因为0小于1。

这是根据边数(帕斯卡三角形的第6行)的分布

Edges     0  1  2  3  4  5  6
Frequency 1  6 15 20 15  6  1 (total 64)
Output    0  0  0  *  1  1  1
* = 0 if triangle (4 possibilities) 1 if claw (4 possibilities) 
1 if two opposite edges and one other (12 possibilities)

这样问问题,我们得到以下图和表达式

 ___D___
|\     /|
| E   F |
|  \ /  |
A   X   C
|  / \  |
| /   \ |
|/__B__\|

(A|C|D|B)&(A|D|E)&(D|B|E|F)&(C|B|E)&(A|C|E|F)&(D|F|C)&(A|F|B) 

我们假设输出将默认为1,但在以下任一情况下将更改为0

1.三个相邻边的A 0(测试3个输入)

2.A对两个相对的边对(测试4个输入)为0

上面的术语已经按照可以将它们分组的方式进行了排序。(顺便说一下,此版本的表达式关于AFB顶点是旋转对称的。)

((A|D)|((C|B)&E))&((B|E)|((D|F)&C))&((C|F)|((A|E)&D))&(A|F|B)    =6 inverters
   1      1  1       1      1  1       1      1  1      1        =10 (7 OR with both inputs inverted, 3 NAND)
      2                 2                 2               2      =8  (4 OR with one input inverted)
                 2                 2                 2           =6  (3 AND) 
                                                        Total    =30

每个&或的得分|位于符号下方,并按以下说明合理性:

级别0:我们为每个输入投资一个逆变器:6个NAND

级别1:我们可以通过将反相器置于输入端(总共3个NANDS)来从NAND门构建一个OR,但是由于我们在上一步中已经投资了6个NANDS,因此我们可以从7个NAND门制造7个OR门。我们还需要3个AND门。对于这些,我们将仅使用NAND,而将输出取反。10个NAND

级别2:同样,我们从NAND门构建4个OR门。在每种情况下,我们从“或”门获得1个输入,因此我们必须对其进行反转。但是另一个输入已经被反相了(来自上一步中与一个&符号相对应的NAND中的一个,在三种情况下来自一个符号,而来自后一个反相器中的一个),因此对于每个OR功能,我们只需要2个门。4 * 2 = 8

级别3:现在,我们需要将四个输出相加。这需要3个AND门,每个AND门由2个NAND构建,3 * 2 = 6

总共有30个NAND门,对于|级别为1的分支,最大深度为2 + 2 + 4 = 8 NAND,对于级别为1的分支,最大深度为3 + 1 + 4 = 8 NAND &

以下Ruby脚本从视觉上确认上述表达式有效。

64.times{|i|
  a=i%2
  b=i/2%2
  c=i/4%2
  d=i/8%2
  e=i/16%2 
  f=i/32%2

puts i, ((a|d)|((c|b)&e))&((b|e)|((d|f)&c))&((c|f)|((a|e)&d))&(a|f|b)

puts " ___#{d}___
|\\     /|
| #{e}   #{f} |
|  \\ /  |
#{a}   X   #{c}
|  / \\  |
| /   \\ |
|/__#{b}__\\|


"
}

7

19个NAND

没有比这更简单的电路了。

图片下方有测试代码。至于理解,这很困难。那里有几个IF门,输入被归类为一个三角形,并添加了自由角线,以便一步一步地进行分析,但这并不是简单的方法。如果有人设法理解它,我会印象深刻。

在此处输入图片说明

带有测试的Verilog代码:

// 4-vertex Connectedness Tester                                                                  
// Minimal at 19 NANDs                                                                            
//                                                                                                
// By Kim Øyhus 2018 (c) into (CC BY-SA 3.0)                                                      
// This work is licensed under the Creative Commons Attribution 3.0                               
// Unported License. To view a copy of this license, visit                                        
// https://creativecommons.org/licenses/by-sa/3.0/                                                
//                                                                                                
// This is my entry to win this Programming Puzzle & Code Golf                                    
// at Stack Exchange:                                                                             
// /codegolf/69912/build-a-4-vertex-connectedness-tester-using-nand-gates/                                                                                      
//                                                                                                
// I am sure there are no simpler solutions to this problem.                                      
// It has a logical depth of 11, which is deeper than                                             
// circuits using a few more NANDs.                                                               

module counting6 ( in_000, in_001, in_002, in_003, in_004, in_005, in_006, out000 );
  input  in_000, in_001, in_002, in_003, in_004, in_005, in_006;
  output out000;
  wire   wir000, wir001, wir002, wir003, wir004, wir005, wir006, wir007, wir008, wir009, wir010, wir011, wir012, wir013, wir014, wir015, wir016, wir017;

  nand gate000 ( wir000, in_000, in_000 );
  nand gate001 ( wir001, in_001, in_003 );
  nand gate002 ( wir002, wir001, wir000 );
  nand gate003 ( wir003, in_002, wir002 );
  nand gate004 ( wir004, wir002, wir002 );
  nand gate005 ( wir005, wir004, in_002 );
  nand gate006 ( wir006, wir005, wir004 );
  nand gate007 ( wir007, in_005, wir006 );
  nand gate008 ( wir008, in_003, wir006 );    
  nand gate009 ( wir009, in_004, wir003 );
  nand gate010 ( wir010, wir003, wir009 );
  nand gate011 ( wir011, wir009, wir000 );
  nand gate012 ( wir012, wir011, in_001 );
  nand gate013 ( wir013, wir008, wir012 );
  nand gate014 ( wir014, wir013, in_005 );
  nand gate015 ( wir015, wir006, wir013 );
  nand gate016 ( wir016, wir015, wir007 );
  nand gate017 ( wir017, wir016, wir010 );
  nand gate018 ( out000, wir014, wir017 );
endmodule


module connecting6_test;
   reg [5:0] X;
   wire a;

  counting6 U1 (
  .in_000 (X[0]),
  .in_001 (X[1]),
  .in_002 (X[2]),
  .in_003 (X[3]),
  .in_004 (X[4]),
  .in_005 (X[5]),
  .in_006 (X[6]),
  .out000 (a )
  );

  initial begin
    X = 0;
  end

  always
    #10  X = X+1;

 initial  begin
    $display("\t\t     \t_");
    $display("\t\ttime,\t \\db/_,\tconnected");
    $monitor("%d,\t%b,\t%d",$time, X, a );
  end

  initial
   #630  $finish;

endmodule

// iverilog -o hello hello.v                                                                      
// vvp hello                                                                                      

金·奥胡斯


您是否证明了这一最低要求?如果是,怎么办?
lirtosiast

我使用统计测试来获得证明它很小的证据。对于像这样的相对简单的电路,测试是相当确定的。
KimOyhus

1

Mathematica,17门

我们简单地列举所有规则,构造布尔函数,并将其最小化NAND

#->If[Total@#<3||
       MemberQ[{{1,1,1,0,0,0},{1,0,0,1,1,0},{0,1,0,1,0,1},{0,0,1,0,1,1}},#]
       ,0,1] /.{1->True,0->False}& /@
     Tuples[{0,1},6];
BooleanMinimize[BooleanFunction[rule], "NAND"]

结果

(#1⊼#2⊼#4)⊼(#1⊼#2⊼#5)⊼(#1⊼#2⊼#6)⊼(#1⊼#3⊼#4)⊼ \
(#1⊼#3⊼#5)⊼(#1⊼#3⊼#6)⊼(#1⊼#4⊼#6)⊼(#1⊼#5⊼#6)⊼ \
(#2⊼#3⊼#4)⊼(#2⊼#3⊼#5)⊼(#2⊼#3⊼#6)⊼(#2⊼#4⊼#5)⊼ \
(#2⊼#5⊼#6)⊼(#3⊼#4⊼#5)⊼(#3⊼#4⊼#6)⊼(#4⊼#5⊼#6)&

,其中#1...#6有6个参数槽。


测试用例

f=%; (* assign the function to symbol f *)

f[True, True, True, True, False, False]
(* True *)

f[True, True, False, True, False, False]
(* True *) (*, three Trues do not form a triangle *)

f[True, True, True, False, False, False]
(* False *) (*, three Trues form a triangle *)

p⊼q⊼r是not (p&q&r)什么意思?``您的结果是最终的意思是什么?

@RickyDemer是的,p⊼q⊼r意味着(p⊼q)⊼r,它等于!(p&&q&&r)
njpipeorgan

插入False,False,True似乎表明(p⊼q)⊼r不等同于!(p&&q&&r)

@RickyDemer这是个问题...我认为是理所当然的。
njpipeorgan

此外,至少BooleanMinimize [EXPR,“NAND”]的WolframAlpha的版本并没有一定最小化与非门的数量。(尝试BooleanMinimize [((((a NAND b)NAND(c NAND d))NAND((e NAND f)NAND(g NAND h))),“ NAND”]。)最多有7个NAND?

1

64个NAND

六个边缘可以分为三对相对的边缘。要连接图,必须有两个相对的边以及第三个边,或三个边连接到同一顶点。

       •
       U

   Z   •   Y  
    V     W 
 •     X     •

相对的对是UX,VY,WZ,因此:

A = U+V   ;3 gates
B = W+X
C = Y+Z

D = UV(B+C)  ;2+2+3=7 gates
E = WX(A+C)
F = YZ(C+A)

Result = D+E+F+UVW+UYZ+XVZ+XWY ; 18 + 16 = 34 gates

以通常的方式构建“与”门或“或”门,使用的门总数为3*3+7*3+34= 64。


[True,True,False,True,False,False]给出了一个没有任何相对边的连通图。

@RickyDemer我认为现在可以使用...
lirtosiast '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.