【计算几何】帝国边界划分问题【Voronoi图的原理】

news2024/11/27 4:19:00

一、说明

        Voronoi 单元也称为泰森多边形。 Voronoi 图在许多领域都有实际和理论应用,主要是在科学和技术领域,但也在视觉艺术领域使用。Voronoi 图以数学家 Georgy Voronoy 的名字命名,也称为 Voronoi 镶嵌、Voronoi 分解、Voronoi 分区或 Dirichlet 镶嵌(以 Peter Gustav Lejeune Dirichlet 命名)。

        在数学中,Voronoi 图是将对平面(集合)划分为多个区域的算法。在最简单的情况下,这些对象只是平面上的有限多个点(称为种子、站点或生成器)。对于每个种子,都有一个对应的优先划分区域。这种区域称为 Voronoi 单元,由平面上离该种子比其他任何点更近的所有点组成。一组点的 Voronoi 图与该组的 Delaunay 三角剖分是对偶的。

        注意:点、区域、边界线成为这个算法的关键要素。

二、帝国边界划分问题

        我们用一个童话故事构成思想实验。

        话说,哈里发国王年事已高,厌倦朝政,因而计划将他的王国分为四份,分别由四个王子管理。于是召来宰相易普拉辛,说到:“我亲爱的宰相,我打算将王国分成四个部落,分别交给王子们统辖,如今有四个城池,分别是查兰,是哥,达玛,宿吐作为它们的都城,可是如何划分疆土我毫无主张,是真主启发我召你商议此事。”宰相思索片刻,说到:“赞美安拉,我倒是有一个谋划,请借地图叙述”,国王当即请出地图如下:

         且看宰相如何划分国土。首先,确定查兰的边疆,如下:

        1)从查兰引出三个线段,分别连接(是哥,达玛,宿土)

        2)分别作出三条线段的中分线。

         做出三条中分线L1,L2,L3。中分线上的特征是(以查兰和达玛为例),L1线上点到查兰的距离一定等于该点到达玛距离,因此谁也没“侵犯”谁。因此,绿线和红线都是“公平线”,蓝线多余,查兰的土地已经画出。

        3)接着划分达玛:从达玛引出线段,连接是哥和宿土,继续上述操作:

        显然,图中新增出公平线S1,S2,图中的粉色(靠近达玛一侧区域)能保证达玛没有“侵犯”其它邻国。至此,达玛的边界因L1,S1,S2确定。

        4)最后,从宿土到是哥引出线段,并做出中分线T1,如图:

        至此,宿土的边疆也因T1和S1划分完成。

         哈里发看了宰相的划分,依然不悦,对宰相说到:“依照爱卿的划分,国土面积不等,如何说服四位王子服从分配?”宰相说到:“安啦是唯一的主,不妨把命运交给安拉,让他们抓阄分配”,国王听后,大喜曰:“然”。
 

三、voronoi的正规定义

3.1 最简单的voronoi情况

        在最简单的情况下,如第一张图片所示,我们在欧几里得平面中得到一组有限的点 {p1, ..., pn}。在这种情况下,每个站点 pk 只是一个点,其对应的 Voronoi 单元 Rk 由欧几里得平面中的每个点组成,这些点到 pk 的距离小于或等于它到任何其他 pk 的距离。每个这样的单元都是从半空间的交集获得的,因此它是一个(凸)多面体。 [6] Voronoi 图的线段是平面上与最近的两个站点等距的所有点。 Voronoi 顶点(节点)是与三个(或更多)站点等距的点。 

3.2 在距离空间的数学描述

        设X是一个距离函数的度量空间,K是一组索引,{\textstyle (P_{k})_{k\in K}} 是空间中非空子集(站点)的元组(索引集合){\textstyle X}。 Voronoi 单元或 Voronoi 区域,{\textstyle R_{k}},与网站相关{\textstyle P_{k}} 是所有点的集合{\textstyle X}距离{\textstyle P_{k}} 不大于它们到其他站点的距离{\textstyle P_{j}},其中{\textstyle j} 是任何不同于{\textstyle k}。换句话说,如果{\textstyle d(x,\,A)=\inf\{d(x,\,a)\mid a\in A\}}, 表示点与集合之间的距离({\textstyle x} 和子集{\textstyle A}),然后有:

        Voronoi 图只是单元格的元组{\textstyle (R_{k})_{k\in K}}。原则上,一些站点可以相交甚至重合(下面描述了代表商店的站点的应用程序),但通常假定它们是不相交的。此外,定义中允许有无限多个站点(此设置在数字几何和晶体学中有应用),但同样,在许多情况下,只考虑有限多个站点。

        在空间是有限维欧几里德空间的特殊情况下,每个站点都是一个点,有有限多个点并且所有点都不同,那么 Voronoi 单元是凸多胞形,它们可以用组合方式表示它们的顶点、边、二维面等。有时,导出的组合结构被称为 Voronoi 图。然而,一般而言,Voronoi 单元可能不是凸的,甚至可能不是连接的。在通常的欧几里德空间中,我们可以用通常的术语重写形式定义。每个 Voronoi 多边形{\textstyle R_{k}} 与生成点相关联{\textstyle P_{k}}。让{\textstyle X} 是欧氏空间中所有点的集合。让1个{\textstyle P_{1}} 是生成其 Voronoi 区域的点

        1个{\textstyle R_{1}},2个{\textstyle P_{2}} 生成2个{\textstyle R_{2}}, 和3个{\textstyle P_{3}} 生成3个{\textstyle R_{3}}等等。然后,正如 Tran 等人所表达的那样,[7]“Voronoi 多边形中的所有位置都比欧几里得平面中的 Voronoi 图中的任何其他生成点更接近该多边形的生成点”。

3.3 不同距离空间所得 Voronoi 单元不同

        如图,下面是基于欧氏空间和曼哈顿空间的划分:

 

        以上就是欧氏空间和曼哈顿空间的划分细节。

四、代码和库

4.1 算法库

以下给出算法库Voronoi,是通过python写的代码

from PIL import Image, ImageColor, ImageDraw
from random import randint, choice, random, seed as randomseed
from typing import *
from math import hypot, sqrt
from queue import Queue
from dataclasses import dataclass
from enum import Enum

import os
import sys


class ColorAlgorithm(Enum):
    random           = 1
    no_adjacent_same = 2
    least_possible   = 3


class RegionAlgorithm:
    def randomized(width: int, height: int, regions: int, mask_function) -> List[Tuple[int, int]]:
        """Return regions that are entirely random."""
        points = []
        while len(points) != regions:
            p = (randint(0, width - 1), randint(0, height - 1))

            if p in points:
                continue

            if not mask_function(p):
                continue

            points.append(p)

        return points

    def uniform(width: int, height: int, regions: int, mask_function) -> List[Tuple[int, int]]:
        """Return regions that attempt to be somewhat uniform."""
        k = 10
        points = []
        while len(points) != regions:
            best_p = None
            d_max = 0

            i = 0
            while i < k * len(points) + 1:
                p = (randint(0, width - 1), randint(0, height - 1))

                if p in points:
                    continue

                if not mask_function(p):
                    continue

                if len(points) == 0:
                    best_p = p
                    break

                d_min = float('inf')
                for x, y in points:
                    d = hypot(p[0]-x, p[1]-y)

                    if d < d_min:
                        d_min = d

                if d_min > d_max:
                    d_max = d_min
                    best_p = p

                i += 1

            points.append(best_p)

        return points


class DistanceAlgorithm:
    def euclidean(x, y, xn, yn):
        """Calculate the image regions (up to a distance) using euclidean distance."""
        return hypot(xn-x, yn-y)

    def manhattan(x, y, xn, yn):
        """Calculate the image regions using manhattan distance."""
        return abs(xn-x) + abs(yn-y)

    def euclidean45degrees(x, y, xn, yn):
        """Calculate the image regions using euclidean, but allow only lines in 45 degree increments."""
        return sqrt(2 * min(abs(xn-x), abs(yn-y)) ** 2) + abs(abs(xn-x) - abs(yn-y))

    def chebyshev(x, y, xn, yn):
        """Calculate the image regions using chebyshev distance."""
        return min(abs(xn-x), abs(yn-y)) + abs(abs(xn-x) - abs(yn-y))

    def set_each_point(seed: int, width: int, height: int,
            region_centers: List[Tuple[int, int]], image: List[List[int]],
            d_limit: int, f: List[Callable[[int, int, int, int], float]], mask_function):
        """Calculate the image regions (up to a distance) using the provided metric."""
        randomseed(seed)

        region_distance_functions = [f if not isinstance(f, list) else choice(f) for _ in range(len(region_centers))]

        for x in range(width):
            for y in range(height):
                if not mask_function((x, y)):
                    continue

                d_min = float('inf')

                for i, region in enumerate(region_centers):
                    xn, yn = region
                    d = region_distance_functions[i](x, y, xn, yn)

                    if d < d_min:
                        d_min = d

                        if d <= d_limit:
                            image[x][y] = id(region)

class Utilities:
    def error(message, q=True):
        print(f"\u001b[38;5;1mERROR:\u001b[0m {message}", flush=True)

        if q:
            sys.exit(1)

    def warning(message):
        print(f"\u001b[38;5;208mWARNING:\u001b[0m {message}", flush=True)

    def info(message):
        print(f"\u001b[38;5;11mINFO:\u001b[0m {message}", flush=True)

    def success(message):
        print(f"\u001b[38;5;2mSUCCESS:\u001b[0m {message}", flush=True)

    def hex_to_tuple(color: str):
        color = color.strip("#")
        return (int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16))

    def get_different_adjacent_colors(width, height, image, colors, color_algorithm):
        from pulp import LpProblem, LpVariable, LpMinimize, lpSum, PULP_CBC_CMD

        edges = set()

        mapping = {}
        n = 0

        for x in range(width):
            for y in range(height):
                for xd, yd in ((0, 1), (1, 0), (-1, 0), (0, -1)):
                    xn, yn = x + xd, y + yd

                    if not 0 <= xn < width or not 0 <= yn < height:
                        continue

                    i1, i2 = image[x][y], image[xn][yn]

                    if i1 is None or i2 is None:
                        continue

                    if i1 < i2:
                        if i1 not in mapping:
                            n += 1
                            mapping[n] = i1
                            mapping[i1] = n

                        if i2 not in mapping:
                            n += 1
                            mapping[n] = i2
                            mapping[i2] = n

                        edges.add((mapping[i1], mapping[i2]))

        edges = list(edges)
        model = LpProblem(sense=LpMinimize)

        chromatic_number = LpVariable(name="chromatic number", cat='Integer')
        variables = [[LpVariable(name=f"x_{i}_{j}", cat='Binary') \
                      for i in range(n)] for j in range(n)]

        for i in range(n):
            model += lpSum(variables[i]) == 1
        for u, v in edges:
            for color in range(n):
                model += variables[u - 1][color] + variables[v - 1][color] <= 1
        for i in range(n):
            for j in range(n):
                model += chromatic_number >= (j + 1) * variables[i][j]

        if color_algorithm == ColorAlgorithm.least_possible:
            model += chromatic_number
        else:
            model += chromatic_number == len(colors)

        status = model.solve(PULP_CBC_CMD(msg=False))

        if chromatic_number.value() > len(colors):
            Utilities.error("Not enough colors to color without adjacent areas having the same one!")

        return {mapping[variable + 1]: colors[color]
                for variable in range(n)
                for color in range(n)
                if variables[variable][color].value() == 1}

    def add_border(background, border_size, read_image, write_image, width, height, mask_function):
        r = border_size // 2

        for x in range(width):
            for y in range(height):
                if not mask_function((x, y)):
                    continue

                for dx, dy in ((0, 1), (1, 0)):
                    xn, yn = x + dx, y + dy

                    if not 0 <= xn < width or not 0 <= yn < height:
                        continue

                    if not mask_function((xn, yn)):
                        continue

                    if read_image[x][y] != read_image[xn][yn]:
                        draw = ImageDraw.Draw(write_image)
                        draw.ellipse((x-r, y-r, x+r, y+r), fill=(*background,0))


def generate(
        path: str,
        regions: int,
        colors: List[Union[Tuple[int], str]],
        width: int = 1920,
        height: int = 1080,
        region_algorithm = RegionAlgorithm.uniform,
        distance_algorithm = DistanceAlgorithm.euclidean,
        color_algorithm = ColorAlgorithm.random,
        seed: Optional[int] = None,
        border_size: int = 0,
        mask: Optional[str] = None,
        mask_color = "#000000",
        animate = False,
        background = "#FFFFFF",
):
    # possibly seed the random algorithm
    if seed is None:
        seed = random()

    # possibly convert string colors to tuples
    i = 0
    while i < len(colors):
        if type(colors[i]) == str:
            colors[i] = Utilities.hex_to_tuple(colors[i])

        i += 1

    if type(mask_color) == str:
        mask_color = Utilities.hex_to_tuple(mask_color)
    elif type(mask_color) == list:
        mask_color = tuple(mask_color)

    if type(background) == str:
        background = Utilities.hex_to_tuple(background)
    elif type(background) == list:
        background = tuple(background)

    randomseed(seed)

    mask_function = lambda p: True

    if mask is not None:
        try:
            mask_img = Image.open(mask)
            Utilities.info("Mask provided.")

            w, h = mask_img.size

            mask_function = lambda p: mask_img.getpixel(p) == mask_color

            if w != width:
                Utilities.warning("Specified width doesn't match mask width, using mask width.")
                width = w

            if h != height:
                Utilities.warning("Specified height doesn't match mask height, using mask width.")
                height = h


        except Exception as e:
            Utilities.error(f"Error loading mask from '{mask}'.")

    if type(regions) == list:
        Utilities.info("Region centers provided, skipping generation.")

        # flip vertically!
        region_centers = [(int(center[0] * width), int(height - center[1] * height)) for center in regions]
    else:
        Utilities.info("Calculating region centers.")
        region_centers = region_algorithm(width, height, regions, mask_function)

    image = [[None] * height for _ in range(width)]
    Utilities.info("Calculating region areas.")
    DistanceAlgorithm.set_each_point(seed, width, height, region_centers, image, float("inf"), distance_algorithm, mask_function)

    # either assign colors randomly, or calculate the chromatic number and assign them then
    if color_algorithm == ColorAlgorithm.random:
        Utilities.info("Assigning region colors.")
        region_colors = {id(region): choice(colors) for region in region_centers}
    else:
        Utilities.info("Assigning region colors such that no two adjacent regions have the same color.")
        region_colors = Utilities.get_different_adjacent_colors(width, height, image, colors, color_algorithm)

    # if we're masking, some regions won't be assigned
    region_colors[None] = background

    # the original, full image (without borders)
    pil_image = Image.new("RGB", (width, height))
    for x in range(width):
        for y in range(height):
            pil_image.putpixel((x, y), region_colors[image[x][y]])

    if border_size != 0:
        Utilities.add_border(background, border_size, image, pil_image, width, height, mask_function)

    if animate:
        if not os.path.exists(path):
            os.makedirs(path)

        d = 1

        while True:
            animation_image = [[None] * height for _ in range(width)]
            DistanceAlgorithm.set_each_point(seed, width, height, region_centers, animation_image, d, distance_algorithm, mask_function)

            animation_pil_image = Image.new("RGB", (width, height))

            for x in range(width):
                for y in range(height):
                    animation_pil_image.putpixel((x, y), background if animation_image[x][y] is None else region_colors[image[x][y]])

            if border_size != 0:
                Utilities.add_border(background, border_size, animation_image, animation_pil_image, width, height)

            animation_path = os.path.join(path, f"{d}.png")

            animation_pil_image.save(animation_path, "PNG")
            Utilities.success(f"Animation image saved to {animation_path}")

            d += 1

            if image == animation_image:
                Utilities.success(f"Done!")
                break

    else:
        pil_image.save(path, resolution=300)
        Utilities.success(f"Image saved to {path}!")

4.2 参数说明 

generate function arguments

  • path: the path (including an extension) to save the resulting file to
  • regions: the number of distinct regions in the diagram
  • colors: a list of tuples denoting the RGB of the color, or strings denoting the color in hex
  • width: the width of the image; defaults to 1920
  • height: the height of the image; defaults to 1080
  • region_algorithm: the algorithm that determines the centers of the regions:
    • RegionAlgorithm.uniform attempts to make the centers equidistant to one another; default
    • RegionAlgorithm.randomized makes the center positions entirely random
  • distance_algorithm: the algorithm that determines the way the distance is measured; if a list of the algorithms is provided, a random one is picked for each point
    • DistanceAlgorithm.euclidean: standard euclidean distance (hypotenuse); default
    • DistanceAlgorithm.manhattan: Manhattan (taxicab) distance (4 directions)
    • DistanceAlgorithm.chebyshev: Chebyshev distance (8 directions)
    • DistanceAlgorithm.euclidean45degrees: euclidean distance, but lines can only point in 45 degree increments
  • color_algorithm: the algorithm that determines the colors of the regions
    • DistanceAlgorithm.random: pick the colors randomly
    • DistanceAlgorithm.no_adjacent_same: pick the colors such that no two adjacent regions have the same color
    • DistanceAlgorithm.least_possible: same as no_adjacent_same, but attempt to do so in the least number of colors
  • seed: the seed for the random number generator; no seed by default
  • border_size: the thickness of the border (in pixels); defaults to 0 (no border)
  • mask: a path to an image mask so only specific areas are used
  • mask_color: the color of the mask to fill, ignoring everything else; defaults to #000000
  • animate: creates images in the folder path of the regions filling in; defaults to False
  • background: background of the animation/masking/borders; defaults to #FFFFFF

4.3 调用方法 

from voronoi import *

generate(
    path = "1.png",
    width = 3840,
    height = 2160,
    regions = 70,
    colors = [(0, 0, 0), (15, 15, 15), (23, 23, 23), (30, 30, 30)],
    color_algorithm = ColorAlgorithm.no_adjacent_same,
)

结果图: 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/475113.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

减少过拟合:暂退法

文章目录 &#xff08;一&#xff09;过拟合&#xff08;二&#xff09;暂退法 &#xff08;一&#xff09;过拟合 1.过拟合产生的原因 (1)根本原因&#xff1a; 我们都知道模型参数的优化方式&#xff1a;反向传播更新梯度&#xff0c;然后随机梯度下降。 也非常清楚模型参…

【Java笔试强训 9】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;另类加法…

弗洛伊德算法(求最短路径)

弗洛伊德算法介绍 和迪杰斯特拉算法一 样&#xff0c; 弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法。弗洛伊德算法(Floyd)计算图中各个顶点之间的最短路径迪杰斯特拉算法用于计算图中某-一个顶点到其他项点的最短路径。弗洛伊德算法VS迪杰斯特拉算…

【数据库架构】PostgreSQL的最佳群集高可用性方案

如果您的系统依赖PostgreSQL数据库并且您正在寻找HA的集群解决方案&#xff0c;我们希望提前告知您这是一项复杂的任务&#xff0c;但并非不可能实现。 我们将讨论一些解决方案&#xff0c;您可以从中选择对您的容错要求。 PostgreSQL本身不支持任何多主群集解决方案&#xff0…

Python Unet ++ :医学图像分割,医学细胞分割,Unet医学图像处理,语义分割

一&#xff0c;语义分割&#xff1a;分割领域前几年的发展 图像分割是机器视觉任务的一个重要基础任务&#xff0c;在图像分析、自动驾驶、视频监控等方面都有很重要的作用。图像分割可以被看成一个分类任务&#xff0c;需要给每个像素进行分类&#xff0c;所以就比图像分类任务…

C++-FFmpeg-8-(1)基本概念与原理-rtsp-I、P、B 帧-DTS、PTS-

目录 1.rtsp是什么&#xff1f; 2. I、P、B 帧 3.DTS、PTS 4.rtsp协议抓包分析&#xff1f; 1.rtsp是什么&#xff1f; 流程&#xff1a; 鉴权&#xff1a; 2种 &#xff1a;basice64 Digest 哈希值 哈希值不可逆。nonce 做的单项散列&#xff08;MD5,SHA512&#xff0…

HTML(二) -- 表格设计

目录 1. 基本格式&#xff1a; 表格常用属性&#xff1a; 2. 表格标签 为什么使用表格&#xff1f; 简单通用、结构稳定数据显示的非常的规整、可读性非常好 1. 基本格式&#xff1a; <table style"border: 1px solid black;" border"1px">&l…

AWE2023什么值得看?智哪儿带你五大关键词读懂AWE2023

4月27至30日&#xff0c;2023年中国家电及消费电子博览会&#xff08;AWE 2023&#xff09;在上海浦东新国际博览中心开展。 作为与德国IFA、美国CES并肩的全球前三国际家电及消费电子展览会&#xff0c;时隔两年AWE终于重启。沉淀两年&#xff0c;它的规模也是历年最大&#x…

QT+OpenCV配置

QTOpenCV配置 1 下载CMake2 安装CMake3 下载OPenCV4 配置环境变量4.1 配置QT环境变量4.2 配置CMake环境变量4.3 重启电脑生效 5 CMake编译OPenCV5.1 解决报错 6 测试 1 下载CMake 链接&#xff1a;https://cmake.org/download/ 2 安装CMake 3 下载OPenCV 链接&#xff1a;htt…

本地elasticsearch中文分词器 ik分词器安装及使用

ElasticSearch 内置了分词器&#xff0c;如标准分词器、简单分词器、空白词器等。但这些分词器对我们最常使用的中文并不友好&#xff0c;不能按我们的语言习惯进行分词。 ik分词器就是一个标准的中文分词器。它可以根据定义的字典对域进行分词&#xff0c;并且支持用户配置自…

网络设备中VRRP协议和Linux服务器中keepalived的两个区别

1、什么是VRRP&#xff1f;keepalived又是什么&#xff1f; VRRP全称是Virtual Router Redundancy Protocol&#xff0c;即虚拟路由冗余协议。它的主要目的是在一个网络中提供冗余的路由。当一个三层网络设备或服务器出现故障时&#xff0c;VRRP可以确保网络仍能正常工作。VRR…

在.NET Core中正确使用HttpClient的方式

HttpClient 是 .NET Framework、.NET Core 或 .NET 5以上版本中的一个类&#xff0c;用于向 Web API 发送 HTTP 请求并接收响应。它提供了一些简单易用的方法&#xff0c;如 GET、POST、PUT 和 DELETE&#xff0c;可以很容易地构造和发送 HTTP 请求&#xff0c;并处理响应数据。…

算法之时间复杂度---数据结构

目录 前言&#xff1a; 1.时间复杂度 1.1时间复杂度的理解 1.2规模与基本操作执行次数 1.3大O渐进表示法 1.4计算基本操作的次数 2.常见的时间复杂度及其优劣比较 ❤博主CSDN&#xff1a;啊苏要学习 ▶专栏分类&#xff1a;数据结构◀ 学习数据结构是一件有趣的事情&…

2023五一数学建模B题完整模型代码【原创首发】

已经完成五一数学建模全部内容&#xff0c;大家可以文末查看&#xff01;&#xff01;供参考使用&#xff01; 摘要 随着网络购物的普及和发展&#xff0c;快递行业需求持续增长&#xff0c;对于快递公司来说&#xff0c;准确预测运输需求以及合理规划运输线路和仓库布局变得…

分享一个有意思的键盘,我们就只会ctrl c+v

先上效果图&#xff1a; 再上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>* {border: 0;box-sizing: border-box;margin: 0;padding: 0;}:roo…

【pyTorch学习笔记④】PyTorch基础·中篇

文章目录 三、Numpy与Tensor3.Tensor的索引4.Tensor的广播机制5.逐元素操作6.归并操作7.比较操作8.矩阵操作9.PyTorch与Numpy的比较 相关推荐 三、Numpy与Tensor 3.Tensor的索引 &#xff08;1&#xff09;item&#xff1a;若Tensor为单元素&#xff0c;则返回标量&#xff0…

驱动开发:通过MDL映射实现多次通信

在前几篇文章中LyShark通过多种方式实现了驱动程序与应用层之间的通信&#xff0c;这其中就包括了通过运用SystemBuf缓冲区通信&#xff0c;运用ReadFile读写通信&#xff0c;运用PIPE管道通信&#xff0c;以及运用ASYNC反向通信&#xff0c;这些通信方式在应对一收一发模式的时…

【Java笔试强训 8】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;两种排…

【Java笔试强训 6】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;不要二 …

权限提升:本地权限提升.(AT || SC || PS )

权限提升&#xff1a;本地权限提升. 权限提升简称提权&#xff0c;由于操作系统都是多用户操作系统&#xff0c;用户之间都有权限控制&#xff0c;比如通过 Web 漏洞拿到的是 Web 进程的权限&#xff0c;往往 Web 服务都是以一个权限很低的账号启动的&#xff0c;因此通过 Web…