กราฟพื้นที่เชิงลบ


13

งาน

คุณจะได้รับจำนวนเต็มบวกและคุณต้องส่งออก " กราฟเสริมตนเอง " กับหลาย ๆ โหนด หากคุณไม่รู้ว่ากราฟเสริมด้วยตนเองคืออะไรบทความวิกิพีเดียไม่ช่วยคุณได้มากนักด้านล่างนี้เป็นคำอธิบายสองคำหนึ่งคือคำอธิบายทางเทคนิคและไม่ใช่ทางเทคนิค

ไม่ใช่ทางด้านเทคนิค

กราฟคือชุดของโหนดที่เชื่อมต่อกันด้วยเส้น คะแนนแต่ละคู่สามารถเชื่อมต่อกันด้วยหนึ่งบรรทัด "ส่วนประกอบ" ของกราฟเป็นผลมาจากการทำกราฟและเชื่อมต่อโหนดทั้งหมดที่ไม่ได้เชื่อมต่อและตัดการเชื่อมต่อโหนดทั้งหมดที่อยู่

กราฟเสริมตนเองคือกราฟที่สามารถจัดเรียงส่วนเติมเต็มให้เป็นรูปร่างของต้นฉบับได้ ด้านล่างนี้เป็นตัวอย่างของกราฟเสริมตนเองและการสาธิตวิธีการ

นี่คือกราฟที่มี 5 โหนด:

กราฟ 5 โหนด

เราจะเน้นสถานที่ทั้งหมดที่การเชื่อมต่อสามารถไปด้วยเส้นประสีแดง:

กราฟที่เน้น

ตอนนี้เราจะได้พบกับส่วนเสริมของกราฟโดยการสลับขอบสีแดงและสีดำ:

ส่วนประกอบ

สิ่งนี้ดูไม่เหมือนกราฟต้นฉบับ แต่ถ้าเราย้ายโหนดรอบ ๆ เช่นนั้น (แต่ละขั้นตอนจะสลับสองโหนด):

มอร์ฟ

เราได้กราฟมาแล้ว! กราฟและส่วนประกอบเป็นกราฟเดียวกัน

วิชาการ

กราฟเสริมตนเองคือกราฟที่มีลักษณะสัมพัทธ์กับส่วนประกอบ

ข้อมูลจำเพาะ

คุณจะได้รับจำนวนเต็มบวกผ่านวิธีใดก็ตามที่เหมาะกับคุณที่สุด และคุณจะส่งออกกราฟในวิธีใดก็ตามที่คุณเห็นว่าเหมาะสมซึ่งรวมถึง แต่ไม่ จำกัด เฉพาะแบบฟอร์ม Adjacency Matrix , แบบฟอร์มรายการ Adjacencyและรูปภาพแน่นอน! กราฟเอาท์พุทจะต้องเป็นส่วนประกอบของตัวเองและมีโหนดเป็นจำนวนเต็มเป็นจำนวนเต็ม หากไม่มีกราฟดังกล่าวอยู่คุณจะต้องส่งออกค่าเท็จ

นี่คือและคุณควรตั้งเป้าเพื่อลดจำนวนไบต์ของคุณ

กรณีทดสอบ

ด้านล่างเป็นรูปภาพของเอาต์พุตที่เป็นไปได้สำหรับหลาย n

4

5

9


กราฟเสริมที่สมบูรณ์อยู่ได้ก็ต่อเมื่อกราฟที่สมบูรณ์มีจำนวนเท่ากัน เรารับประกันสิ่งนี้หรือไม่?
xnor

@xnor ฉันลืมที่จะรวมที่ แก้ไขแล้ว
Ad Hoc Garf Hunter

เราต้องจัดการกับอินพุตเชิงลบหรือไม่?
xnor

@xnor ไม่ฉันจะแก้ไขคำถามให้สอดคล้องกัน
Ad Hoc Garf Hunter

3
ก่อนที่ทุกคนจะได้แนวคิดในการตอบคำถามGraphData@{"SelfComplementary",{#,1}}&ฉันเชื่อว่าเพียงแค่โหลดตัวอย่างบางส่วนnจากฐานข้อมูลของ Wolfram ต่ำดังนั้นสิ่งนี้จะไม่ทำงานสำหรับอินพุตที่มีขนาดใหญ่ตามอำเภอใจ
Martin Ender

คำตอบ:


9

Haskell , 77 ไบต์

f n=[(a,b)|b<-[1..n],a<-[1..b-1],mod n 4<2,mod(a+(last$b:[a|odd n,n==b]))4<2]

ลองออนไลน์!

สิ่งนี้ใช้เกณฑ์ที่ชัดเจนที่คำนวณได้ง่ายเพื่อตัดสินว่าขอบนั้น(a,b)อยู่ในกราฟหรือไม่ สร้างอัลกอริธึมนี้โดยทันทีโดยการวนรอบการเปลี่ยนแปลงระหว่างค่าโมดูโล 4

4*m -> 4*m+1 -> 4*m+2 -> 4*m+3 -> 4*m

เรารวมขอบที่จุดปลายสองจุดเพิ่มเป็น 0 หรือ 1 โมดูโล 4 โปรดทราบว่าการวนรอบของการปั่นตามการเพิ่มนี้จะเพิ่ม 2 โมดูโล 4 ลงในผลรวมจุดยอดในแต่ละจุด สิ่งนี้ทำให้เกิดการเปลี่ยนแปลงของจุดยอดที่เติมเต็มขอบ

หากกราฟมีโหนดเพิ่มเติมเกินกว่าหลาย ๆ 4 กราฟนั้นจะอยู่ในวัฏจักรเดียว เรารวมขอบด้วยเมื่อถึงจุดยอดอื่น ๆ การอนุญาตให้จุดยอดพลิกความเท่าเทียมกันและกราฟก็ยังคงเสริมตัวเอง

หากจำนวนจุดยอดไม่ใช่ 0 หรือ 1 โมดูโล 4 ไม่สามารถทำกราฟประกอบตัวเองได้เนื่องจากมีขอบจำนวนคี่ในกราฟสมบูรณ์

โดยรวมนี่คือเงื่อนไข:

  • หากอินพุต n ไม่ใช่ 0 หรือ 1 โมดูโล 4 ให้ส่งรายการว่าง
  • มิฉะนั้นถ้า n เป็นเลขคู่ให้รวมค่าขอบทั้งหมด(a,b)ด้วยa<bและa+bเท่ากับ 0 หรือ 1 โมดูโล 4
  • มิฉะนั้นถ้า n เป็นเลขคี่ให้ทำแบบเดียวกัน แต่ให้รวมขอบของแบบฟอร์มแทน(a,n)เมื่อ a เป็นเลขคู่

รหัสรวมกรณีที่สองและสามโดยการเปลี่ยนสภาพmod(a+b)4<2ด้วยmod(a+a)4<2เมื่อทั้งสองและodd nb==n


5

Brachylog 2 , 24 ไบต์

{⟦₁⊇Ċ}ᶠpḍ.(\\ᵐcdl?∨?<2)∧

ลองออนไลน์!

นี่คือฟังก์ชั่นที่คืนค่าคู่ที่ประกอบด้วยสองรายการ adjacency หนึ่งรายการสำหรับกราฟหนึ่งรายการสำหรับกราฟประกอบ (ในล่าม Brachylog บน TIO คุณสามารถขอให้ประเมินฟังก์ชั่นแทนโปรแกรมเต็มรูปแบบโดยให้Zเป็นอาร์กิวเมนต์บรรทัดคำสั่ง) ตัวอย่างเช่นเอาต์พุตสำหรับอินพุต5คือ:

[[[1,2],[1,3],[1,5],[3,5],[4,5]],[[2,5],[2,3],[2,4],[3,4],[1,4]]]

นี่คือสิ่งที่ดูเหมือนว่าเป็นภาพ (แสดงกราฟสอง):

กราฟและส่วนประกอบที่เหมือนกันใน 5 องค์ประกอบ

ตามปกติในภาษาที่ใช้ภาษาโปรล็อกฟังก์ชันสนับสนุนรูปแบบการโทรมากกว่าหนึ่งรูปแบบ โดยเฉพาะอย่างยิ่งถ้าคุณพยายามที่จะใช้มันเป็นเครื่องกำเนิดไฟฟ้ามันจะแสดงกราฟเสริมที่เป็นไปได้ทั้งหมดด้วยจำนวนจุดยอดที่กำหนด กราฟแต่ละครั้ง)

คำอธิบาย

นี่เป็นเพียงคำอธิบายปัญหาโดยปล่อยให้การใช้ Prolog เพื่อค้นหาวิธีที่ดีที่สุดในการแก้ไข (อย่างไรก็ตามฉันสงสัยว่ามันจะใช้อัลกอริธึมที่ดีกว่าแรงเดรัจฉานในกรณีนี้ดังนั้นจึงไม่มีประสิทธิภาพพอสมควรและการทดสอบดูเหมือนว่าจะยืนยันสิ่งนี้

{⟦₁⊇Ċ}ᶠpḍ.(\\ᵐcdl?∨?<2)∧
 ⟦₁                       The range [1, 2, …, ?], where ? is the input
   ⊇                      A subset of that range…
    Ċ                     …which has exactly two elements
{    }ᶠ                   A list of everything that fits the above description
{⟦₁⊇Ċ}ᶠ                   All edges that could exist in a ?-element graph
       p                  Find a permutation of these…
        ḍ                 …so that splitting it into two equal parts…
          (       ∨   )   …either:
               dl?          produces ? distinct elements
           \                after transposing it
            \ᵐ              and transposing its elements
              c             and flattening one level;
                          or:
                   ?<2      ? was less than 2
         .             ∧  Once you've found it, . specifies what to output

บังเอิญฉันก็ต้องใช้ทั้ง 6 ไบต์ (¼ของโปรแกรมตัวละคร(∨?<2)) ที่เกี่ยวข้องกับกรณีพิเศษ 0 และ 1 ที่น่าผิดหวัง แต่นั่นเป็นลักษณะของกรณีพิเศษ

\\ᵐcdl?ส่วนเป็นเพียงเล็กน้อยยากที่จะเข้าใจเพื่อให้ที่นี่เป็นตัวอย่างที่ทำงาน โดยมีวัตถุประสงค์คือเพื่อตรวจสอบว่าบางสิ่งบางอย่างเป็นกราฟและส่วนประกอบของมันพร้อมกับขอบที่สอดคล้องกันในกราฟและส่วนประกอบที่อยู่ในลำดับเดียวกันภายในรายการ คู่กราฟ / ส่วนประกอบกลายเป็นผลลัพธ์ในที่สุดของโปรแกรม นี่คือกรณีตัวอย่าง:

[[[1,2],[1,3],[1,5],[3,5],[4,5]],[[2,5],[2,3],[2,4],[3,4],[1,4]]]

การแปลงนี้ทำให้เรามีรายการคู่ของขอบที่สอดคล้องกันระหว่างกราฟและส่วนประกอบ:

[[[1,2],[2,5]],[[1,3],[2,3]],[[1,5],[2,4]],[[3,5],[3,4]],[[4,5],[1,4]]

ต่อไปเราจะย้ายภายในองค์ประกอบรายการและทำให้แบนราบในระดับหนึ่ง ที่ให้รายการของคู่ขององค์ประกอบที่สอดคล้องกันระหว่างกราฟและส่วนประกอบ:

[[1,2],[2,5],[1,2],[3,3],[1,2],[5,4],[3,3],[5,4],[4,1],[5,4]]

เห็นได้ชัดว่าสิ่งที่เราต้องการที่นี่คือจะต้องมีไม่เกิน 1 คู่เริ่มจากแต่ละองค์ประกอบ (ดังนั้นพิสูจน์ว่าองค์ประกอบของกราฟและส่วนประกอบอยู่ในการติดต่อแบบ 1 ต่อ 1) เราเกือบจะสามารถยืนยันได้ว่าเพียงแค่ระบุว่ารายการมี?องค์ประกอบที่แตกต่างกันอย่างแน่นอน(เช่นจำนวนองค์ประกอบที่แตกต่างกันเท่ากับจำนวนจุดยอด) ในกรณีนี้การทดสอบจะสำเร็จ องค์ประกอบที่แตกต่างคือ:

[[1,2],[2,5],[3,3],[5,4],[4,1]]

อย่างไรก็ตามสิ่งนี้ทำให้ห้องว่างสำหรับปัญหาที่อาจเกิดขึ้น หากจุดสุดยอดถูกตัดการเชื่อมต่อทั้งหมดในกราฟต้นฉบับการโต้ตอบของมันจะไม่ถูกกล่าวถึงซึ่งจะมีที่ว่างสำหรับการโต้ตอบซ้ำจากจุดสุดยอดอื่น ๆ หากเป็นกรณีนี้กราฟสมบูรณ์จะต้องมีขอบระหว่างจุดสุดยอดที่ (โดยไม่สูญเสียของทั่วไปขอบอกว่ามัน1) และทุกจุดสุดยอดอื่น ๆ และเพื่อให้รายการจดหมายจะมี[1,2], [1,3], ... [1, ?], เมื่อ?มีขนาดใหญ่สิ่งนี้จะนำไปสู่การติดต่อสื่อสารทั้งหมดมากกว่าที่เรามีเป็นอย่างอื่นดังนั้นจึงไม่มีปัญหา ปัญหาเดียวเกิดขึ้นเมื่อ?3 หรือต่ำกว่าซึ่งในกรณีนี้เราจะเพิ่มการติดต่อพิเศษหนึ่งรายการเท่านั้น1ไม่ปรากฏในอินพุต); อย่างไรก็ตามนี่ไม่ใช่ปัญหาในทางปฏิบัติเนื่องจากมี 3 ขอบที่เป็นไปได้ในกราฟองค์ประกอบ 3 ซึ่งเป็นจำนวนคี่ (เช่นเดียวกัน 1 ขอบที่เป็นไปได้ในกราฟ 2 องค์ประกอบเป็นจำนวนคี่) และทำให้ การทดสอบจะล้มเหลวใน\ขั้นตอน (คุณไม่สามารถเปลี่ยนรายการที่ขาดได้นั่นคือรายการที่องค์ประกอบมีความยาวต่างกัน)


ความแตกต่างระหว่างzและ\คือว่าzคือเป็นวงกลมซิปหมายความว่า[[1,2,3],["a"]]จะจบลงด้วยการ[[1,"a"],[2,"a"],[3,"a"]]ที่มีในขณะที่มันจะล้มเหลวz ตอนนี้ใช้ได้กับเมทริกซ์จตุรัสเท่านั้น การใช้งานในอนาคตจะทำให้มันทำงานได้ยกเว้นว่าไม่ใช่วัฏจักร \\z
ลดขนาด

ฉันคิดความแตกต่างจากตัวเองจริง ๆ แต่หลังจากที่ฉันเขียนคำอธิบาย วิธีแก้ปัญหาเฉพาะนี้ขึ้นอยู่กับ `` การทำงานกับสี่เหลี่ยมเท่านั้น (แม้ว่าจะใช้เวลาเพียง 2 ไบต์เท่านั้นหากคุณไม่สามารถใช้ประโยชน์จากขั้นตอนนั้นได้)

2

BBC BASIC, 161 ไบต์

ไฟล์ขนาด Tokenised 140 ไบต์

ดาวน์โหลดล่ามได้ที่http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

I.m:IF2ANDm ORm<4P.0:END
r=400n=-2A.m:t=2*PI/n:F.i=1TOn*n:a=i DIVn:b=i MODn:c=b:IFa+b A.2a*=t:b*=t:L.r+r*SINa,r+r*COSa,r+r*SINb,r+r*COSb:IF 1A.m A.c DRAWr*3,0
N.

รหัสไม่ได้รับการตอบ

  INPUTm                           :REM get input
  IF2ANDm ORm<4PRINT0:END          :REM if m=4x+2 or 4x+3 or less than 4, print 0 and exit
  r=400                            :REM radius of diagram
  n=-2ANDm                         :REM n = m truncated to an even number
  t=2*PI/n                         :REM t = 1/n turns
  FORi=1TOn*n                      :REM for each combination of vertices
    a=i DIVn                       :REM extract a and b
    b=i MODn                       :REM make a copy of c
    c=b                            :REM if a+b MOD 4 = 2 or 3, convert a and b to angles and draw edge.
    IFa+b AND2 a*=t:b*=t:LINEr+r*SINa,r+r*COSa,r+r*SINb,r+r*COSb:IF 1ANDm ANDc DRAWr*3,0
  NEXT                             :REM if m is odd and c is odd, draw a line to the additional vertex for m=4x+1 input.

คำอธิบาย

สิ่งนี้ใช้อัลกอริธึมเดียวกับ Xnor แต่สร้างเอาต์พุตแบบไดอะแกรม

ตำแหน่งnของแบบฟอร์ม4x+2หรือ4x+3ไม่มีวิธีแก้ปัญหาเนื่องจากจำนวนของขอบเป็นเลขคี่

ซึ่งnเป็นรูปแบบ 4x เราจัดจุดยอดทั้งหมดในวงกลมและวาดขอบเหล่านั้นโดยที่(a+b) mod 42 หรือ 3 (ไม่ใช่ 0 หรือ 1 เช่นในกรณีของ Xnor เพื่อเหตุผลในการตีกอล์ฟดังนั้นนี่จึงเป็นส่วนเสริมของโซลูชันที่ Xnor กำหนดไว้)

หากต้องการดูสิ่งนี้ในแง่ของภาพเราใช้จุดสุดยอดทุกวินาทีและวาดขอบไปยังจุดยอดที่ 1 และ 2 วางในทิศทางทวนเข็มนาฬิกา สิ่งนี้กำหนดnทิศทางคู่ขนานครึ่งหนึ่งของทั้งหมด จากนั้นเราบวกขอบอื่น ๆ ทั้งหมดขนานกับสิ่งเหล่านี้

ส่วนเติมเต็มสามารถพบได้โดยเพิ่ม 1 เข้ากับ a และ b ในสเปคขอบแต่ละอันหรือในแนวตั้งด้วยการหมุนไดอะแกรมทีละ1/nตา

ซึ่งnอยู่ในรูปแบบ 4x + 1 เราเพิ่มจุดสุดยอดอีกอันซึ่งเชื่อมโยงกับจุดยอดทุกวินาทีของกราฟ 4x หากวางไว้ตรงกลางความสมมาตรของแผนภาพจะคงอยู่ แต่ฉันเลือกที่จะวางไว้นอกวงกลมหลักของจุดเพื่อความชัดเจน

เอาท์พุต

ต่อไปนี้เป็นกรณีแรก ๆ สำหรับ 4x + 1 กรณี 4x สามารถมองเห็นได้โดยการลบจุดสุดยอดที่ด้านล่างขวาและขอบที่เกี่ยวข้อง

ป้อนคำอธิบายรูปภาพที่นี่


1

JavaScript (ES6), 191 ไบต์

f=(n,a=[],v=n*~-n/4)=>v%1?0:eval(n>5?f(n-=4,a)&&'for(i=0;i<n;)a.push([i,n+1],[i++,n+2]);a.push([n,++n],[n,++n],[n,++n])-v':'for(l=x=0;x<n;x++)for(y=x;y<n;y++)l<v&y>>x&1?l=a.push([x,y]):a')||a

ฟังก์ชั่นนี้จะส่งกลับรายการ adjacency มันใช้สองอัลกอริทึมและแยกความแตกต่างระหว่างกราฟเสริมที่ว่างเปล่าและที่ไม่ใช่เอาท์พุทโดยกลับมา0แทน[]เมื่อไม่มีอยู่ อัลกอริทึมแรกขึ้นอยู่กับกราฟ Rado ที่สร้างขึ้นโดยใช้คำกริยา BITและสร้างกราฟเสริมที่ถูกต้อง 0-, 1-, 4- และ 5 ลำดับ อัลกอริทึมอื่นที่พบโดยเพื่อน ๆ ของเราในวิชาคณิตศาสตร์สร้างกราฟเสริม V + 4 จุดยอดที่ถูกต้องโดยใช้การเพิ่ม4 เส้นทางในกราฟเสริม V ที่ถูกต้อง

มันเริ่มต้นด้วยการตรวจสอบการป้อนข้อมูลเพื่อยืนยันการมีอยู่ของกราฟที่สมบูรณ์ถูกต้อง (ใช้n*~-n/4%1) 0และถ้าไม่ได้ผลให้ผลตอบแทน จากนั้นตรวจสอบว่าn>5และเกิดซ้ำกับn-4เคสเพื่อสร้างโซลูชันลำดับต่ำสุดที่ถูกต้องหรือไม่จากนั้นให้ใช้การบวก 4 เติมเข้ากับรายการ adjacency ที่ส่งคืนระหว่างวิธีสำรองข้อมูลเชนการสอบถามซ้ำ สุดท้ายหากn>5ไม่เป็นความจริงก็ iterates จาก0การn-1สำหรับxและyและการตรวจสอบถ้า(y>>x)&1เป็นความจริง ถ้าเป็นเช่นนั้นโหนดเหล่านั้นจะถูกจับคู่

นี่คือรูปแบบที่อ่านได้ง่ายกว่าของฟังก์ชั่นที่มีผู้ประกอบการประกอบไปด้วยสามส่วนขยายไปยังคำสั่ง if-else และeval()s inlined:

// precalculate amount of required vertices in v
f = (n, a = [], v = n*~-n / 4) => {
  // if amount is non-integer
  if (v % 1) {
    // no valid complementary graph
    return 0;
  } else {
    if (n > 5) {
      // generate valid (n-4)-order complementary graph
      f(n -= 4, a);
      // apply 4-path addition
      for (i = 0; i < n;)
        a.push([i, n+1],[i++, n+2]);
      a.push([n, ++n], [n, ++n], [n, ++n]);
    } else {
      // construct Rado graph using BIT predicate
      for(l = x = 0; x < n; x++)
        for(y = x; y < n; y++)
          // if amount of pairs is less than required and xth bit of y is high
          if (l < v && (y>>x & 1))
            // vertices x and y should be paired
            a.push([x,y]);
    }
    return a;
  }
};

การสาธิต

f=(n,a=[],v=n*~-n/4)=>v%1?0:eval(n>5?f(n-=4,a)&&'for(i=0;i<n;)a.push([i,n+1],[i++,n+2]);a.push([n,++n],[n,++n],[n,++n])-v':'for(l=x=0;x<n;x++)for(y=x;y<n;y++)l<v&y>>x&1?l=a.push([x,y]):a')||a
<input type="number" onchange="o.textContent=JSON.stringify(f(this.value))"><pre id="o"></pre>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.