นี่คือปัญหากราฟสี
โปรดจำไว้ว่าการระบายสีกราฟเป็นการกำหนดสีให้กับจุดยอดของกราฟในลักษณะที่ไม่มีจุดยอดสองอันที่แบ่งขอบจะมีสีเดียวกัน โดยเฉพาะจุดยอด (นามธรรม) ของกราฟคือรูปหลายเหลี่ยม จุดยอดสองจุดเชื่อมต่อกับขอบ (undirected) เมื่อใดก็ตามที่พวกเขาตัดกัน (เป็นรูปหลายเหลี่ยม) หากเราใช้วิธีการแก้ปัญหาใด ๆ - ซึ่งเป็นลำดับของ (พูดk ) คอลเลกชัน disjoint ของรูปหลายเหลี่ยม - และกำหนดสีที่ไม่ซ้ำกันให้กับแต่ละคอลเลกชันในลำดับนั้นเราจะได้รับk -กราฟของสี . เป็นที่พึงประสงค์ที่จะหาขนาดเล็กk
ปัญหานี้ค่อนข้างยากและยังไม่มีการแก้ไขสำหรับกราฟตามอำเภอใจ พิจารณาโซลูชันโดยประมาณที่ง่ายต่อการเขียนโค้ด อัลกอริทึมแบบลำดับควรทำ อัลกอรึทึมของเวลส์ - พาวเวลล์เป็นวิธีการแก้ปัญหาที่เป็นไปตามการจัดลำดับของจุดยอดตามลำดับ แปลเป็นภาษาของรูปหลายเหลี่ยมดั้งเดิมอันดับแรกเรียงลำดับรูปหลายเหลี่ยมจากมากไปหาน้อยของรูปหลายเหลี่ยมอื่น ๆ ที่ซ้อนทับกัน การทำงานตามลำดับให้สีเริ่มต้นเป็นรูปหลายเหลี่ยมแรก ในแต่ละขั้นตอนต่อเนื่องให้ลองสีรูปหลายเหลี่ยมถัดไปด้วยสีที่มีอยู่นั่นคือเลือกสีที่ไม่ใช่ใช้แล้วโดยเพื่อนบ้านของรูปหลายเหลี่ยมนั้น (มีหลายวิธีให้เลือกระหว่างสีที่มีให้ลองใช้สีที่มีการใช้งานน้อยที่สุดหรือเลือกแบบสุ่ม) หากรูปหลายเหลี่ยมถัดไปไม่สามารถใช้สีที่มีอยู่ให้สร้างสีใหม่และใช้สีนั้น
เมื่อคุณประสบความสำเร็จในการทำสีด้วยสีจำนวนน้อยให้ดำเนินการสี zonalstats ตามสี: จากการก่อสร้างคุณรับรองได้ว่าไม่มีรูปหลายเหลี่ยมสองสีที่ทับซ้อนกัน
R
นี่คือตัวอย่างรหัสใน (รหัสไพ ธ อนจะไม่แตกต่างกันมาก) อันดับแรกเราอธิบายการทับซ้อนระหว่างรูปเจ็ดเหลี่ยมที่แสดง
edges <- matrix(c(1,2, 2,3, 3,4, 4,5, 5,1, 2,6, 4,6, 4,7, 5,7, 1,7), ncol=2, byrow=TRUE)
นั่นคือรูปหลายเหลี่ยม 1 และ 2 ทับซ้อนกันดังนั้นรูปหลายเหลี่ยม 2 และ 3, 3 และ 4, ... , 1 และ 7
จัดเรียงจุดยอดตามระดับจากมากไปน้อย:
vertices <- unique(as.vector(edges))
neighbors <- function(i) union(edges[edges[, 1]==i,2], edges[edges[, 2]==i,1])
nbrhoods <- sapply(vertices, neighbors)
degrees <- sapply(nbrhoods, length)
v <- vertices[rev(order(degrees))]
อัลกอริทึมการระบายสีแบบต่อเนื่อง (หยาบ) ใช้สีที่เก่าที่สุดที่มีอยู่ซึ่งยังไม่ได้ใช้โดยรูปหลายเหลี่ยมที่ซ้อนกัน:
color <- function(i) {
n <- neighbors(i)
candidate <- min(setdiff(1:color.next, colors[n]))
if (candidate==color.next) color.next <<- color.next+1
colors[i] <<- candidate
}
เริ่มต้นโครงสร้างข้อมูล ( colors
และcolor.next
) และใช้อัลกอริทึม:
colors <- rep(0, length(vertices))
color.next <- 1
temp <- sapply(v, color)
แบ่งรูปหลายเหลี่ยมออกเป็นกลุ่มตามสี:
split(vertices, colors)
ผลลัพธ์ในตัวอย่างนี้ใช้สี่สี:
$`1`
[1] 2 4
$`2`
[1] 3 6 7
$`3`
[1] 5
$`4`
[1] 1
มันแบ่งพาร์ติชันรูปหลายเหลี่ยมออกเป็นสี่กลุ่มที่ไม่ทับซ้อนกัน ในกรณีนี้การแก้ปัญหาไม่เหมาะสม ({{3,6,5}, {2,4}, {1,7}} เป็นสามสีสำหรับกราฟนี้) โดยทั่วไปแล้ววิธีการแก้ปัญหาที่ได้รับไม่ควรเลวร้ายเกินไป