知乎高问:为什么有些人不愿意在女领导手下工作?
刚看到个知乎高问,问的是:为什么有些人不愿意在女领导手下工作?话题一出来,评论区就挺热闹。
贴子本身讨论的是职场选择偏好,不是性别对立。但网友回帖里,有人直言“事情多、情绪起伏大”,也有人反驳这是刻板印象。
我觉得吧,这事不能一刀切。事多不多,很多时候跟岗位、流程有关;情绪稳不稳,也更多是个人管理能力问题,跟性别真没必然关系。
说白了,大家讨厌的不是女领导,而是“不专业的领导”。要是目标清晰、边界明确、情绪不外溢,谁当领导其实都一样。
当然,也得承认,有些人对女性领导天然更敏感,一点不顺就容易被放大解读,这本身也是职场偏见的一部分。怎么说呢,职场就像坐地铁,挤不挤看线路,不该怪司机性别。
面试题:销售员
有个销售员,要从公司出发,跑一圈客户城市,每个城市刚好去一次,最后再回公司。每两个城市之间都有路,路程可能不一样。问题就是——怎么走,总路程最短?
听着是不是很像那个“旅行商问题”(Traveling Salesman Problem,TSP),其实就是同一个东西,名字换成“销售员”而已。
先别急着上算法,脑子里先画个图:每个城市是一个点,两点之间有一条边,边上写着距离。你要做的事,就是在这个图上绕一圈,把所有点都串起来,最后回到起点,还要保证总路程最短。
如果城市特别少,比方说 4 个城市,其实可以直接暴力: 把“访问城市的顺序”全部列出来,算每种顺序的总路程,取个最小值就完事了。
用程序来说就是枚举全排列。用 Python 写出来大概这样:
import itertools
deftsp_bruteforce(dist):
n = len(dist)
cities = range(1, n) # 0 当出发城市
best = float('inf')
best_path = None
for perm in itertools.permutations(cities):
path = (0,) + perm + (0,)
total = 0
for i in range(len(path) - 1):
total += dist[path[i]][path[i + 1]]
if total < best:
best = total
best_path = path
return best, best_path
这个思路超级直观,优点就是“能跑就行”,缺点也很明显:城市一多就爆炸。 原因是排列数是 n!,比如 10 个城市就已经是 3628800 种走法了,电脑也会嫌累。
所以面试里如果你只说暴力,面试官一般会继续追问一句:那城市多了怎么办?
这时候就轮到动态规划出场了。
动态规划这块,不要一上来就被状态吓住,其实核心就一句话:
“我关心的是:已经走过哪些城市、现在人在哪个城市、在这种前提下的最短路程。”
我们可以用一个二进制的整数 mask 来表示“走过哪些城市”。 举个例子,有 4 个城市 0,1,2,3: 如果 mask = 0b01101,就说明走过了 0、2、3(从右往左数 bit 位)。
然后搞一个二维数组 dp[mask][i]: 表示从起点 0 出发,走过 mask 里面这些城市,最后停在城市 i 的最短路程。
那转移怎么写呢? 如果现在状态是 dp[mask][j],想再去一个没去过的城市 k,那新状态就是:
new_mask = mask | (1 << k)dp[new_mask][k] = min(dp[new_mask][k], dp[mask][j] + dist[j][k])
最后所有城市都走完了,也就是 mask = (1 << n) - 1,再加上从终点回 0 的距离,取个最小值就行。
完整一点的 Python 代码:
deftsp_dp(dist):
n = len(dist)
ALL = 1 << n
INF = float('inf')
# dp[mask][i] = 从 0 出发,走过 mask 中的点,最后停在 i 的最短路程
dp = [[INF] * n for _ in range(ALL)]
dp[1][0] = 0# 只走过城市 0,且停在 0
for mask in range(ALL):
for i in range(n):
if dp[mask][i] == INF:
continue
# 尝试去下一个没去过的城市 j
for j in range(n):
if mask & (1 << j): # 已经去过就跳过
continue
new_mask = mask | (1 << j)
new_cost = dp[mask][i] + dist[i][j]
if new_cost < dp[new_mask][j]:
dp[new_mask][j] = new_cost
# 所有城市都走完以后,再回 0
end_mask = ALL - 1
ans = INF
for i in range(n):
if dp[end_mask][i] == INF:
continue
ans = min(ans, dp[end_mask][i] + dist[i][0])
return ans
这个算法大概是 O(n^2 * 2^n) 的复杂度。 看着还是很吓人,不过和 n! 比起来,已经是大升级了,20 个城市左右还能勉强用一下。
实际项目里要是城市再多,比如上百个,就得上各种“近似算法”“贪心”“局部搜索”之类的,那就是工程优化的世界了,就不像这题这么干净了。我之前做数据库压测脚本的时候,还真用过类似的 bitmask DP 去枚举一堆组合,感觉那次算是把这个套路彻底用顺手了
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB