这篇文章发表于 325 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

韦伯的工业区位论是经济地理学里面非常基础的一个理论,然而事实上只是由于介绍者过于温和并没有将一些硬核的东西呈现出来——单就韦伯工业区位论最小运费指向论来说,尽管教科书上写着其中工厂区的最佳选点能够直接用“范力农构架(varignnon frame)”来推求,但其实这个理解是存在问题的。

接下来一点点说起,当然重点是最佳区位的选取。

基本概念回顾

韦伯在1909年出版了《工业区位纯理论》,系统地阐述了工厂企业的区位抉择,认为工业企业成本最低的区位是企业最佳区位。韦伯假设了一个均质平原上,工业企业在已知原料地和市场区位的前提下选择区位。

他在七项一般区位因子中选取了原材料和燃料费用、劳动费用以及运输费用(运费取决于产品重量和运输距离),还区分了其中的原料类型:遍在性原料和限地性原料(特定区位存在的原料)、粗原料(生产过程中会减少重量)和纯原料。

其理论重点有三:运费指向论、劳动力成本指向论、集聚指向论。

运费指向论中设定了两个原料费用,相关的工业生产区位决定因子及原料指数和区位重量。主要公式如下:原料指数(Mi)=局地原料重量(Wm)/产品重量(Wp),也就是生产单位产品需要的局地原料量;区位重量=(局地原料重量+产品重量)/产品重量=1+原料指数,因此,当原料指数大于1时,工厂最好布局在原料地;小于1时在消费地;等于1时,两者均可。于是在多个原料产地和消费地之间,可以运用“范力农构架(varignnon frame)”来确定最佳区位。再进一步,我们能够在空间中划分出综合等费用线。

劳动力成本指向论的思路是工业区位由运费指向转为劳动力成本指向仅限于节约的劳动力成本大于由此增加的运费,即在劳动力成本节约额比由运费最小地点移动产生的运费增加额大时劳动力成本指向就占主导地位(根据这两者的关系,就能够找到临界等费用线)。为判断工业受劳动力成本指向的影响程度,韦伯提出了“劳动力成本指数”的概念,即每单位重量产品的平均劳动力成本。如果劳动力成本指数大,那么从最小运费区移向廉价劳动力区位的可能性就大,但这只是可能性,而不是决定因素。此外,他还提出劳动系数=劳动力成本/区位重量,即美单位区位重量的劳动力成本,该指标可用来表示劳动力成本的吸引力。综上,决定劳动力成本指向有两个条件:基于特定工业性质的条件(通过劳动力成本指数和劳动系数来测定)、人口密度和运费率等环境条件。另外,从技术进步考虑,运输工具的改善会降低运费率,劳动力成本指向会增强;机械化会带来劳动生产率提高,降低劳动系数,导致劳动供给地布局的工业会因运费作用转向消费地。

集聚因子的作用可分为两种形态:经营规模的扩大而产生的生产集聚、多种企业在空间上集中产生的集聚(企业间的协作分工)。其类型又可分为纯粹集聚和偶然集聚:纯粹集聚是技术性和经济性集聚利益产生的集聚,也称为技术性集聚;偶然集聚是由诸如运费指向和劳动力成本指向的结果而带来的工业集中。韦伯认为,当集聚节约额大于因运费(或劳动力成本)指向带来的生产费用节约额时,便会产生集聚。

最佳区位选取

接下来的考虑中可能直接忽略了原料地和消费地这些点呈一条直线和只有原料地和消费地两点的情况,因为考虑起来比较简单。为了不折磨自己2333,接下来的推导我都是手写的而不是LaTeX,也存在着一些懒得改的小错误和不严谨处,见谅。

以上的最佳区位的确定相当于解出下图中的题目。

题干

我们先从最简单的情况开始吧。

特殊情况:三个点+权重均相等

这种情况也就是原料产地和消费地总数目为三,然后从平面中任意一点到这三个点的权重都相同。

三个点+权重均相等

上面的推导中应该直接将权重设为1,懒得改图片了。

特殊情况:三个点+权重不全相等

这里在地理教科书上一般提到的都是用“范力农构架(varignnon frame)”来推求的,也就是下图(选自Polya_1954_Mathematics and Plausible Reasoning的148页插图)。其中的P,Q,R对应着A,B,C三者的权重,而在平衡后的X就是区位三角形的重力中心,也就是运费最小地点。

varignnon_frame

这是因为在物理世界中,这个系统的总体势能最小才会稳定,因而其重力势能必须最小,而这个条件就等价于最佳区位生成所必须的条件。

听起来很有道理,但是其实有一些地方依旧需要推敲(事实上,这种最佳区位如果能出现是需要一定条件的),要想让该架构使用就必须在物理上进行类推(而这正是教科书上没有的)。接下来让我们先看看数学该如何理解这个问题(以下引自Martelli和Mario的论文《Geometrical Solution of Weighted Fermat Problem about Triangles》,推导过程进行了一定的修改,可能导致部分谬误)。

1

我们先从最简单的开始,证明了最佳区位P不可能超出三角形。

fig1

2

可见在以上ii)这种假设的前提条件下,应该就会产生和“范力农构架”一样的结果。

fig2

3

fig3

3-2

以上这种iii)情况的情况就不适合范力农构架,尽管我们能够对范力农构架进行一些约束等以简单理解与判断,但是边界条件却是较难找寻的。还有最后一种值得讨论的情况如下:

4

原料产地和消费地总数目为三且从平面中任意一点到这三个点的权重不全相同的情况仅仅是个有趣的尝试,我们马上就要考虑一些更为普遍的情况。

一般情况:多个点+权重不全相等

最佳点的存在性

以下是对原料产地和消费地总数目大于或等于三的一般情况的证明(引用自Kulin和Kuenne的论文《An Efficient Algorithm for the Numerical Solution of the Generalized Weber Problem in Space Economics》,推导过程进行了一定的修改,可能导致部分谬误)。

一般情形_1

一般情形_2

可见最佳点在多边形的里面或顶点处而且唯一。

Kulin和Kuenne的迭代法

篇幅所限,这里就不赘述具体的方法了,建议看论文《An Efficient Algorithm for the Numerical Solution of the Generalized Weber Problem in Space Economics》中的例子。

对这种多次迭代方法的程序实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import taichi as ti
ti.init()

N, cycles = 6, 50

xy = ti.Vector.field(2, ti.f64, cycles) # position of particles
fixed = ti.Vector.field(2, ti.f64, N) # origin position of particles
w = ti.field(ti.f64, N) # weight
origin_w = ti.field(ti.f64, N) # weight
times = ti.field(int, ())
times[None] = 0


@ti.kernel
def init():
for i in fixed:
fixed[i] = [ti.random(), ti.random()]
w[0], w[1], w[2], w[3], w[4], w[5] = 1.4, 2, 2, 1, 1.5, 2
for i in w:
origin_w[i] = w[i]


@ti.kernel
def paint():
sum_wx, sum_wy, sum_w = 0.0, 0.0, 0.0
for i in fixed:
sum_wx += w[i] * fixed[i][0]
sum_wy += w[i] * fixed[i][1]
sum_w += w[i]
xy[times[None]] = [sum_wx / sum_w, sum_wy / sum_w]
for i in w:
w[i] = origin_w[i] / (fixed[i] - xy[times[None]]).norm()


init()
gui = ti.GUI('The Solution of the Weber Problem')

while times[None] < cycles:
paint()
times[None] += 1

while gui.running:
OUT = xy.to_numpy()
gui.circle(OUT[times[None] - 1], radius=4, color=0xfeee6c)
gui.circles(fixed.to_numpy(), radius=3, color=0xfece91)
gui.show()

最终结果会收敛到最佳点,效果如下:

solution

上图中六个小点是原料产地或消费地,那个较大较亮的点即最佳区位。

利用等费用线

一个简单且有效的方法其实就是绘制综合等费用线,尤其是有了计算机的帮助。显然这种方法因为可以随意定义权重(也就不必是常数),因此拥有普适性,分析现实问题就更为有效。

这里就用taichi来实现这个概念。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import taichi as ti

ti.init(arch=ti.gpu)

width, height, N = 600, 400, 6
pixels = ti.field(dtype=float, shape=(width, height))

score = ti.field(dtype=float, shape=(width, height)) # every pixel score
fixed = ti.Vector.field(2, float, N) # position of fixed points
w = ti.field(float, N) # weight(const)
maximum = ti.field(float, ())
minimum = ti.field(float, ())
minimum_ij = ti.Vector.field(2, float, 1) # 这里我只取一个点,即便有其他点也应该非常接近,不影响判断

pixels.fill(0)
score.fill(0)


@ti.kernel
def init():
minimum[None] = 1000
for i in range(N):
x, y = ti.random(), ti.random()
pixels[int(x * width), int(y * height)] = 1
fixed[i] = ti.Vector([x, y])
w[0], w[1], w[2], w[3], w[4], w[5] = 1.4, 2, 2, 1, 1.5, 2


@ti.kernel
def paint():
for i, j in pixels:
for k in range(N):
z = ti.Vector([i / width, j / height])
score[i, j] += w[k] * (z - fixed[k]).norm()
if score[i, j] > maximum[None]: # 找到的最大值作为分母
maximum[None] = score[i, j]
for i, j in pixels:
score[i, j] /= maximum[None]
if score[i, j] < minimum[None]: # 找到的最小值位置作为最佳点的位置
minimum[None], minimum_ij[0] = score[i, j], ti.Vector([i / width, j / height])


gui = ti.GUI("Isodapanes", res=(width, height))
init()
paint()
while True:
gui.set_image(score)
gui.circles(fixed.to_numpy(), radius=5, color=0xDDDDDD)
gui.circles(minimum_ij.to_numpy(), radius=5, color=0xfef16c)
gui.show()

输出图片如下:

综合等费用线

在程序中呈现的条件下,以上图中灰点是原料产地或消费地,越黑的地方综合费用越低,而黄点就是费用最低的最佳区位。