码迷,mamicode.com
首页 > 其他好文 > 详细

使用深度搜索分析心理调查问卷的研究

时间:2016-05-13 04:33:20      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:

使用深度搜索分析心理调查问卷的研究

背景

昨天我女朋友发了一个心理调查问卷要我做。我向来对这种形似心理调查问卷嗤之以鼻: 一个人的性格怎么可能由几个简单的问题决定。但作为技术人员,我决定用技术的手段分析这份调查问卷,向女朋友证明其缺乏科学性。

调查问卷的原版如下图
技术分享

有兴趣的朋友可以玩玩~

我想了解如下几个问题:
1. 问卷是不是有环路?如果有环路,则可证明这份问卷不正规。
2. A 答案是不是不可能达到?因为4个答案中,只有A答案没有同的倾向。
3. 如果 A 答案能到达,那么有多少种可能?占比是多少?

分析

这种问卷调查有特点:每一个题目都对应多个选项;每一个选项,都对应一个题目或者答案。从一个人答题的路径来看,其实这就是一个典型的图结构。

结合我想了解的问题,有如下几个方面需要考虑:
1. 证明图没有环路
2. 使用DFS证明A是可以达到的
3. 统计所有的可能的结果,算出A的占比

建模

我打算使用 列表模式 构建图

  @list = [
    [1],
    [2,3],
    [3,4],
    [4,5,6],
    [5,6,7],
    [6,7],
    [7,8,9],
    [8,9],
    [9,10,11],
    [10,11,12],
    [12,13],
    [13,14],
    [13,15],
    [15,18,14],
    [15,18],
    [16,18],
    [17,18,19,20],
    [20,21,‘B‘],
    [19,‘C‘],
    [22,‘A‘],
    [21, ‘D‘],
    [22, ‘B‘],
    [‘A‘, ‘C‘, ‘D‘]
  ]

图的节点有 0 到 22, 再加上 A, B, C, D。
1. 因为我不想处理下标,所以图的起始位置,我设置成0;
2. 图的节点,我简单的用数组的下标表示;
3. 答案直接输出,不需要放在节点的集合中;

DFS

图有没有环路

代码如下:

def has_cycle?
  recursion_stack = [false] * 23

  check_cycle(0, recursion_stack)
end

def check_cycle(vertex, recursion_stack)
  recursion_stack[vertex] = true

  @list[vertex].each do |node|
    next if over?(node)

    return true if recursion_stack[node]
    check_cycle(node, recursion_stack)
  end

  recursion_stack[vertex] = false

  return false
end

其中 over?方法是用来判断递归是否结束。

def over?(point)
  [‘A‘, ‘B‘, ‘C‘, ‘D‘].include?(point.to_s)
end
  1. has_cycle 来判断是否有回路,我将一次完全迭代的节点是否访问到了的信息保存在recursion_stack
  2. 它调用 深度搜索 算法实现的 check_cycle

运行得出的结果是 false

A 可以到达吗?A如果可以到达,那么A的可能性有多大?

@result = []

def dfs(node)
  @list[node].each do |vertex|
    if over?(vertex)
      @result << vertex
      next
    end

    dfs(vertex)
  end
end

使用深度有限搜索, 将最后的结果保存在 @result中,将结果打印出来。

def count_charactor(result, charactor)
  result.count { |item| item == charactor }
end

dfs(0)

puts "一共有 %d 可能的答案" % @result.size
(‘A‘..‘D‘).to_a.each do |charactor|
  puts "#{charactor}: %d 种可能, 占比为 %f" % [ count_charactor(@result, charactor), count_charactor(@result, charactor).to_f / @result.length]
end

结果如下:

一共有 27860 可能的答案
A: 8960 种可能, 占比为 0.321608
B: 3360 种可能, 占比为 0.120603
C: 8120 种可能, 占比为 0.291457
D: 7420 种可能, 占比为 0.266332

输出能到答案A的100路径

@i = 0

def dfs(node, stack)
  stack.push node

  @list[node].each do |vertex|
    if over?(vertex)
      @result << vertex

      if vertex == ‘A‘
        @i += 1
        puts "到A的路径有:"
        puts stack.join(" -> ")
      end

      break if @i == 100

      next
    end

    dfs(vertex, stack)
  end

  stack.pop
end

用一个栈stack来保存路径, 到A点将所有的结果输出

总结

图的算法应用真的很广泛,值得深入研究。有时候将实时中的问题抽象成图的问题,能让我们从另外的一个角度看问题。再则,用ruby实现图的算法也是很简单的。dfsbfs简单,但收到程序栈的限制。但比较适合本程序。

使用深度搜索分析心理调查问卷的研究

标签:

原文地址:http://blog.csdn.net/hexudong08/article/details/51340504

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!