复杂性思维中文第二版 九、基于智能体的模型

九、基于智能体的模型

原文:Chapter 9 Agent-based models

译者:飞龙

协议:CC BY-NC-SA 4.0

自豪地采用谷歌翻译

我们迄今为止看到的模型可能具有“基于规则”的特征,因为它们涉及受简单规则支配的系统。 在本章和以后的章节中,我们将探索基于智能体(agent)的模型。

基于智能体的模型包含智能体,它旨在模拟人和其他实体,它们收集世界的信息,制定决策并采取行动。

智能体通常位于空间或网络中,并在本地彼此交互。 他们通常有不完整的,不全面的世界信息。

智能体之间经常存在差异,而不像以前的所有模型,它们的所有成分都相同。 基于智能体的模型通常包含智能体之间,或世界中的随机性。

自 20 世纪 70 年代以来,基于智能体的模型已成为经济学和其他社会科学,以及一些自然科学中的重要工具。

基于智能体的模型对非均衡系统的动态建模(尽管它们也用于研究均衡系统)非常有用。 它们对于理解个人决策和系统行为之间的关系特别有用。

本章的代码位于chap09.ipynb中,它是本书仓库中的 Jupyter 笔记本。 使用此代码的更多信息,请参见第?节。

9.1 谢林模型

1971 年,托马斯谢(Thomas Schelling)发表了《隔离的动态模型》(Dynamic Models of Segregation),该模型提出了种族隔离的简单模型。 谢林模型的世界是一个网格;每个细胞代表一栋房子。 房屋被两种智能体占用,标记为红色和蓝色,数量大致相同。 大约 10% 的房屋是空的。

在任何时候,智能体可能会高兴或不高兴,这取决于领域中的其他智能体,每个房屋的“邻居”是八个相邻细胞的集合。在一个版本的模型中,如果智能体至少有两个像他们一样的邻居,智能体会高兴,但如果是一个或零,他们就会不高兴。

模拟的过程是,随机选择一个智能体并检查他们是否高兴。 如果是这样,没有任何事情发生。如果不是,智能体随机选择其中一个未占用的细胞并移动。

听到这种模型导致一些隔离,你可能不会感到惊讶,但是你可能会对这个程度感到惊讶。 很快,会出现相似智能体的群落。 随着时间的推移,这些群落会不断聚合,直到有少量的大型群落,并且大多数智能体生活在同质社区中。

如果你不知道这个过程,只看到结果,你可能会认为智能体是种族主义者,但实际上他们都会在一个混合的社区感到非常高兴。 由于他们不愿意数量过大,所以在最坏的情况下,他们可能被认为是排外的。 当然,这些智能体是真实人物的过度简化,所以这些描述可能根本不恰当。

种族主义是一个复杂的人类问题; 很难想象这样简单的模型可以揭示它。 但实际上,它提供了一个强有力论据,有关系统及其各部分之间关系的:如果你观察真实城市的隔离,你不能总结为,个人的种族主义是直接原因,或者,城市居民是种族主义者。

当然,我们必须牢记这个论述的局限性:谢林模型证明了隔离的一个可能原因,但没有提到实际原因。

9.2 谢林模型的实现

为了实现谢林模型,我编写了另一个继承Cell2D的类:


class Schelling(Cell2D):

    def __init__(self, n, m=None, p=0.5):
        self.p = p
        m = n if m is None else m
        choices = [0, 1, 2]
        probs = [0.1, 0.45, 0.45]
        self.array = np.random.choice(choices, (n, m), p=probs)

参数nm是网格的维度,p是相似邻居比例的阈值。 例如,如果p = 0.5,也就是其邻居中少于 50% 为相同颜色,则智能体将不高兴。

array是 NumPy 数组,其中每个细胞如果为空,则为 0;如果由红色智能体占用,则为1;如果由蓝色智能体占用,则为 2。 最初,10% 的细胞是空的,45% 为红色和 45% 为蓝色。

谢林模型的step函数比以前的step函数复杂得多。 如果你对细节不感兴趣,你可以跳到下一节。 但是如果你坚持要看,你可能需要一些 NumPy 的提示。

首先,我将生成逻辑数组,表明哪些细胞是红色,蓝色和占用的:


a = self.array
red = a==1
blue = a==2
occupied = a!=0

我将使用np.correlate2d来计算,对于每个细胞,红色相邻细胞的数量和被占用的细胞数量。

options = dict(mode='same', boundary='wrap')

kernel = np.array([[1, 1, 1],
                   [1, 0, 1],
                   [1, 1, 1]], dtype=np.int8)

num_red = correlate2d(red, kernel, **options)
num_neighbors = correlate2d(occupied, kernel, **options)

现在对于每个细胞,我们可以计算出红色的邻居比例和相同颜色的比例:


frac_red = num_red / num_neighbors
frac_blue = 1 - frac_red
frac_same = np.where(red, frac_red, frac_blue)

frac_red只是num_rednum_neighbors的比率,而frac_bluefrac_red的补。

frac_same有点复杂。 函数np.where就像逐元素的if表达式一样。 第一个参数是从第二个或第三个参数中选择元素的条件。

在这种情况下,如果redTruefrac_same获取frac_red的相应元素。 在红色为False的情况下,frac_same获取frac_blue的相应元素。

现在我们可以确定不满意的智能体的位置:

unhappy_locs = locs_where(occupied & (frac_same < self.p))

结果unhappy_locs是一个 NumPy 数组,其中每行都是占用的细胞的坐标,其中frac_same低于阈值p

locs_wherenp.nonzero的包装函数:

def locs_where(condition):
    return np.transpose(np.nonzero(condition))

np.nonzero接受一个数组并返回所有非零元素的坐标,但结果是两个元组的形式。 np.transpose将结果转换为更有用的形式,即每行都是坐标对的数组。

同样,empty_locs是一个数组,包含空细胞的坐标:

empty_locs = locs_where(a==0)

现在我们到达了模拟的核心。 我们遍历不高兴的智能体并移动它们:

for source in unhappy_locs:
    i = np.random.randint(len(empty_locs))
    dest = tuple(empty_locs[i])
    a[dest] = a[tuple(source)]
    a[tuple(source)] = 0
    empty_locs[i] = source

i是一个用来随机选择空细胞的索引。

dest是一个包含空细胞的坐标的元组。

为了移动智能体,我们将值从source复制到dest,然后将source的值设置为 0(因为它现在是空的)。

最后,我们用source替换empty_locs中的条目,以便刚刚变为空的细胞可以由下一个智能体选择。

9.3 隔离

image

图 9.1:谢林的隔离模型,n = 100,初始条件(左),2 步后(中)和 10 步后(右)

现在让我们看看我们运行模型时会发生什么。 我将以n = 100p = 0.3开始,并运行 10 个步骤。

grid = Schelling(n=100, p=0.3)
for i in range(10):
    grid.step()

图?展示了初始状态(左),2 步(中)后和 10 步(右)后的模拟。

群落迅速形成,红色和蓝色的智能体移动到隔离集群中,它们由空细胞的边界分隔。

对于每种状态,我们可以计算隔离度,它是相同颜色的邻居的比例。在所有细胞中的平均值:

np.sum(frac_same) / np.sum(occupied)

在图?中,相似邻居的比例均值在初始状态中为 55%,两步后为 71%,10 步后为 80%!

请记住,当p = 0.3时,如果 8 个邻居中的 3 个是他们自己的颜色,那么智能体会很高兴,但他们最终居住在一个社区中,其中 6 或 7 个邻居是自己的颜色。

image

图 9.2:随着时间的推移,谢林模型中的隔离程度,范围为p

图?显示了隔离程度如何增加,以及它在几个p值下的平稳位置。 当p = 0.4时,稳定状态下的隔离程度约为 88%,且大多数智能体没有不同颜色的邻居。

这些结果令许多人感到惊讶,它们成为了个人决策与系统行为之间的,复杂且不可预测的关系的鲜明示例。

9.4 糖域

1996年,约书亚爱泼斯坦(Joshua Epstein)和罗伯特阿克斯特尔(Robert Axtell)提出了糖域(Sugarscape),这是一个“人造社会”的智能体模型,旨在支持经济学和其他社会科学的相关实验。

糖域是一款多功能的模型,适用于各种主题。 作为例子,我将复制 Epstein 和 Axtell 的书《Growing Artificial Societies》的前几个实验。

糖域最简单的形式是一个简单的经济模型,智能体在二维网格上移动,收集和累积代表经济财富的“糖”。 网格的一些部分比其他部分产生更多的糖,并且一些智能体比其他人更容易找到它。

这个糖域的版本常用于探索和解释财富的分布,特别是不平等的趋势。

在糖域的网格中,每个细胞都有一个容量,这是它可容纳的最大糖量。 在原始状态中,有两个高糖区域,容量为 4,周围是同心环,容量分别为 3, 2 和 1。

image

图 9.3:原始糖域模型的复制品:初始状态(左),2 步后(中)和 100 步后(右)。

图?(左)展示了初始状态,最黑暗的区域表示容量最高的细胞,小圆圈表示智能体。

最初有随机放置的 400 个智能体。 每个智能体有三个随机选择的属性:

糖:

每个智能体最开始都有先天的糖分,从 5 到 25 之间均匀选择。

代谢:

在每个时间步骤中,每个智能体都必须消耗一定数量的糖,从 1 到 4 之间均匀选择。

视力:

每个智能体可以“看到”附近细胞中糖量,并移动到最多的细胞,但是与其它智能体相比,一些智能体可以看到更远的细胞。 智能体看到的距离从 1 和 6 之间均匀选择。

在每个时间步骤中,智能体以随机顺序一次移动一格。 每个智能体都遵循以下规则:

  • 智能体在 4 个罗盘方向的每一个方向上调查k个细胞,其中k是智能体的视野范围。
  • 它选择糖分最多的未占用的细胞。 在相等的情况下,选择较近的细胞;在距离相同的细胞中,它随机选择。
  • 智能体移动到选定的细胞并收获糖分,将收获增加到其积累的财富并将细胞清空。
  • 智能体根据代谢消耗其财富的一部分。 如果结果总量为负数,智能体“饿死”并被删除。

在所有智能体完成这些步骤之后,细胞恢复一些糖,通常为 1 单位,但每个细胞中的总糖分受其容量限制。

图?(中)显示两步后模型的状态。 大多数智能体正在移到糖最多的地区。 视力高的智能体移动速度最快;视力低的智能体往往会卡在高原上,随机游走,直到它们足够接近来看到下一个水平。

出生在糖分最少的地区的智能体可能会饿死,除非他们的视力很好,先天条件也很高。

在高糖地区,随着糖分的出现,智能体相互竞争,寻找和收获糖分。 消耗高或视力低的智能体最有可能挨饿。

当糖在每个时间步骤增加 1 个单位时,就没有足够的糖来维持我们开始的 400 个智能体。 人口起初迅速下降,然后缓慢下降,在大约 250 左右停下。

图?(右)显示了 100 个时间步后的模型状态,大约有 250 个智能体。 存活的智能体往往是幸运者,出生时视力高和/或代消耗低。 存活到这里的话,它们可能会永远存活,积累无限量的糖。

9.5 财富的不平等

在目前的形式下,糖域建立了一个简单的生态学模型,可用于探索模型参数之间的关系,如增长率和智能体的属性,以及系统的承载能力(在稳定状态下生存的智能体数量)。 它模拟了一种形式的自然选择的,“适应度”较高的智能体更有可能生存下来。

该模型还表现出一种财富不平等,一些智能体积累糖的速度比其他智能体快。 但是对于财富分布,很难说具体的事情,因为它不是“静止的”。 也就是说,分布随着时间的推移而变化并且不会达到稳定状态。

然而,如果我们给智能体有限的寿命,这个模型会产生固定的财富分布。 然后我们可以运行实验,来查看参数和规则对此分布的影响。

在这个版本的模型中,智能体的年龄在每个时间步增加,并且从 60 到 100 之间的均匀分布中,随机选择一个寿命。如果智能体的年龄超过其寿命,它就会死亡。

当智能体因饥饿或年老而死亡时,它由属性随机的新智能体所取代,所以总人口是不变的。

image

图 9.4:100, 200, 300 和 400 步(灰线)和 500 步(黑线)之后的糖(财富)的分布。 线性刻度(左)和对数刻度(右)。

从接近承载能力的 250 个智能体开始,我运行了 500 个步骤的模型。 在每 100 步之后,我绘制了智能体积累的糖的分布。 图?在线性刻度(左)和对数刻度(右)中展示结果。

经过大约 200 步(这是最长寿命的两倍)后,分布变化不大。 并且它向右倾斜。

大多数智能体积累的财富很少:第 25 百分位数大约是 10,中位数大约是 20。但是少数智能体积累了更多:第 75 百分位数是大约 40,最大值大于 150。

在对数刻度上,分布的形状类似于高斯或正态分布,但右尾被截断。 如果它在对数刻度上实际上是正态的,则分布是对数正态分布,这是一种重尾分布。 实际上,几乎每个国家和全世界的财富分布都是重尾分布。

如果说糖域解释了为什么财富分布是重尾的,但是糖域变化中的不平等的普遍性表明,不平等是许多经济体的特征,甚至是非常简单的经济体。 一些实验表明避免或减轻并不容易,它们带有一些规则,对纳税和其他收入转移进行建模。

9.6 实现糖域

糖域比以前的模型更复杂,所以我不会在这里介绍整个实现。 我将概述代码的结构,你可以在 Jupyter 笔记本chap09.ipynb中查看本章的细节,它位于本书的仓库中。 如果你对细节不感兴趣,你可以跳到下一节。

以下是带有step方法的Agent类:


class Agent:

    def step(self, env):
        self.loc = env.look_around(self.loc, self.vision)
        self.sugar += env.harvest(self.loc) - self.metabolism
        self.age += 1

在每个步骤中,智能体移动,收获糖,并增加年龄。

参数env是环境的引用,它是一个Sugarscape对象。 它提供了方法look_around和收获:

  • look_around获取智能体的位置,这是一个坐标元组,以及智能体的视野,它是一个整数。 它返回智能体的新位置,这是糖分最多的可见细胞。
  • harvest需要智能体的(新)位置,并在移除并返回该位置的糖分。

这里是Sugarscape类和它的step方法(不需要替换):

class Sugarscape(Cell2D):

    def step(self):

        # loop through the agents in random order
        random_order = np.random.permutation(self.agents)
        for agent in random_order:

            # mark the current cell unoccupied
            self.occupied.remove(agent.loc)

            # execute one step
            agent.step(self)

            # if the agent is dead, remove from the list
            if agent.is_starving():
                self.agents.remove(agent)
            else:
                # otherwise mark its cell occupied
                self.occupied.add(agent.loc)

        # grow back some sugar
        self.grow()
        return len(self.agents)

Sugarscape继承自Cell2D,因此它与我们所见过的其他基于网格的模型相似。

这些属性包括agents,它是Agent对象的列表,以及occupied,它是一组元组,其中每个元组包含智能体占用的细胞的坐标。

在每个步骤中,Sugarscape以随机顺序遍历智能体。 它调用每个智能体的step,然后检查它是否已经死亡。 所有智能体都移动后,一些糖会恢复。

如果你有兴趣更加了解 NumPy ,你可能需要仔细看看make_visible_locs,它构建一个数组,其中每行包含智能体可见的细胞坐标,按距离排序,但距离相同的细胞 是随机顺序。

你可能想看看Sugarscape.make_capacity,它初始化细胞的容量。 它演示了np.meshgrid的使用,这通常很有用,但需要一些时间才能理解。

9.7 迁移和波动行为

image

图 9.5:Sugarscape中的波动行为:初始状态(左),6 步后(中)和 12 步后(右)

虽然Sugarscape的主要目的不是探索空间中的智能体的移动,但 Epstein 和 Axtell 在智能体迁移时,观察到一些有趣的模式。

如果我们开始把所有智能体放在左下角,他们会迅速走向最近的高容量细胞的“山峰”。 但是如果有更多的智能体,单个山峰不足以支持它们的话,他们很快就会耗尽糖分,智能体被迫进入低容量地区。

视野最长的那些,首先穿过山峰之间的山谷,并且像波一样向东北方向传播。 因为他们在身后留下一些空细胞,所以其他智能体不会追随,直到糖分恢复。

结果是一系列离散的迁移波,每个波都像一个连贯的物体,就像我们在规则 110 CA 和生命游戏中看到的飞船(参见第?节)。

图?显示了初始条件下(左),6 个步骤(中)和 12 个步骤(右)之后的模型状态。 你可以看到,前两个波到达并穿过第二个山峰,留下了一串空细胞。 你还可以看到这个模型的动画版本,其中波形更清晰可见。

虽然这些波动由智能体组成,但我们可以将他们视为自己的实体,就像我们在“生命游戏”中想到的滑翔机一样。

这些波动的一个有趣的属性是,它们沿对角线移动,这可能是令人惊讶的,因为这些智能体本身只是向北或向东移动,从不向东北方移动。 像这样的结果 - 团队或“集合”拥有智能体没有的属性和行为 - 在基于智能体的模型中很常见。 我们将在下一章看到更多的例子。

9.8 涌现

本章中的例子展示了复杂性科学中最重要的想法之一:涌现。 涌现性是系统的一个特征,由它的成分相互作用而产生,而不是它们的属性。

为了澄清什么是涌现,考虑它不是什么会有帮助。 例如,砖墙很硬,因为砖和砂浆很硬,所以这不是涌现。 再举一个例子,一些刚性结构是由柔性部件构成的,所以这看起来像是一种涌现。 但它至多是一种弱例,因为结构特性遵循已知的力学定律。

相反,我们在谢林模型中看到的隔离是一种涌现,因为它不是由种族主义智能体造成的。 即使智能体只是轻微排外,系统的结果与智能体的决策意图有很大不同。

糖域中的财富分配可能是涌现,但它是一个弱例,因为我们可以根据视力,代谢和寿命的分布合理预测它。 我们在最后一个例子中看到的波动行为可能是一个更强的例子,因为波动显示出智能体显然没有的能力 - 对角线运动。

涌现性令人惊讶:即使我们知道所有规则,也很难预测系统的行为。难度不是偶然的;事实上,它可能是涌现的决定性特征。

正如沃尔夫勒姆在“新科学”中所讨论的那样,传统科学是基于这样的公理:如果你知道管理系统的规则,那么你可以预测它的行为。 我们所谓的“法律”通常是计算的捷径,它使我们能够预测系统的结果而不用建立或观察它。

但是许多细胞自动机在计算上是不可减少的,这意味着没有捷径。 获得结果的唯一方法是实现该系统。

一般而言,复杂系统可能也是如此。 对于具有多个成分的物理系统,通常没有产生解析解的模型。 数值方法提供了一种计算捷径,但仍存在质的差异。

解析解通常提供用于预测的恒定时间算法;也就是说,计算的运行时间不取决于预测的时间尺度t。 但数值方法,模拟,模拟计算和类似方法需要的时间与t成正比。 对于许多系统来说,我们无法计算出可靠的预测。

这些观察表明,涌现性基本上是不可预测的,对于复杂系统我们不应该期望,通过计算捷径来找到自然规律。

对某些人来说,“涌现”是无知的另一个名字; 根据这种思维,如果我们针对它没有还原论的解释,那么这个属性就是涌现的,但如果我们在将来更好地理解它,它就不再是涌现的。

涌现性的状况是有争议的话题,所以对此持怀疑态度是恰当的。 当我们看到明显的涌现性时,我们不应该假设永远不会有还原论解释。但我们也不应该假设必须有。

本书中的例子和计算等价原理提供了很好的理由,认为至少有些涌现性永远不会被古典还原论模型“解释”。

你可以在这里更加了解涌现:http://en.wikipedia.org/wiki/Emergence

9.9 练习

练习 1

本章的代码位于本书仓库的 Jupyter 笔记本chap09.ipynb中。打开这个笔记本,阅读代码,然后运行单元格。你可以使用这个笔记本来练习本章的练习。我的解决方案在chap09soln.ipynb中。

练习 2

《The Big Sort》的作者 Bill Bishop 认为,美国社会越来越由政见所隔离,因为人们选择生活在志趣相投的邻居之中。

Bishop 所假设的机制并不是像谢林模型中的智能体那样,如果他们是孤立的,他们更有可能移动,但是当他们出于任何原因移动时,他们可能会选择一个社区,其中的人与他们自己一样。

修改谢林模型的实现来模拟这种行为,看看它是否会产生类似程度的隔离。

有几种方法可以模拟 Bishop 的假设。在我的实现中,随机选择的智能体会在每个步骤中移动。每个智能体考虑k个随机选择的空位置,并选择相似邻居的比例最高的位置。隔离程度和k有什么关系?

练习 3

在糖域的第一个版本中,我们从不添加智能体,所以一旦人口下降,它就不会恢复。 在第二个版本中,我们只是在智能体死亡时才取代,所以人口是不变的。 现在让我们看看如果我们增加一些“人口压力”会发生什么。

编写糖域的一个版本,在每一步结束时添加一个新的智能体。 添加代码来计算每个步骤结束时,智能体的平均视力和平均消耗。 运行模型几百步,绘制人口,平均视力和平均消耗随时间的变化。

你应该能够通过继承SugarScape并覆盖__init__step来实现这个模型。

练习 4

在心灵哲学中,强人工智能是这样的理论,即受到适当编程的计算机可以拥有思想,与人类拥有的思想相同。

约翰·塞尔(John Searle)提出了一个名为“中文房间”的思想实验,旨在表明强 AI 是虚假的。 你可以在 http://en.wikipedia.org/wiki/Chinese_room 上阅读。

对中文房间的论述的系统回复是什么? 你对涌现的认识如何影响你对系统回复的反应?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,332评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,930评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,204评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,348评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,356评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,447评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,862评论 3 394
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,516评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,710评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,518评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,582评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,295评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,848评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,881评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,121评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,737评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,280评论 2 341

推荐阅读更多精彩内容

  • 本白皮书前期在国标委工业二部和工信部科技司的指导下,通过梳理人工智能技术、应用和产业演进情况,分析人工智能的技术热...
    笔名辉哥阅读 24,003评论 2 143
  • 这几年忽然之间不论从事什么行业都要提到定位这个词,感觉你开店不知道定位就会死,就像餐饮业里面现在最流行的4D厨房,...
    雯龍烧烤培训阅读 339评论 0 1
  • 感 颠沛东南复西北,流离春夏又秋冬。 天遥地远年华逝,莫教残梦终成空。
    吾兮无兮阅读 195评论 0 1
  • 2017.08.26No147 0725-0745用时20分钟字数500 记得在八月上旬就发现今年的三伏天差不多进...
    何不可阅读 431评论 2 2
  • 深刻简单 伟大平凡 我们是自己的答案
    关馨仁阅读 85评论 0 1