Commit 57a9ebb0cf68e36878de75b234d6f50c5c665f1f

Authored by Anthex
1 parent 2def30ad

Implement hidden Markov model

Showing 3 changed files with 136 additions and 14 deletions   Show diff stats
.gitignore
1 1 __pycache__/
2 2 *.pyc
  3 +.vscode/
... ...
1   -
2   -from structure import RSSVector, Location, Cell, newCell, KNeighbors, resolve_barycenter
  1 +from structure import RSSVector, Location, Cell, newCell, KNeighbors, resolve_barycenter, MarkovModel, MarkovValue
3 2 import sys
4 3  
5 4 Tf = [] #cells table
... ... @@ -13,7 +12,7 @@ for i in range (0, 3):
13 12 for k in range (0,3):
14 13 Tf[i].append([])
15 14  
16   -#known fingerprints
  15 +#known fingerprints
17 16 Tf[0][0] = newCell(-38,-27,-54,-13,2,2)
18 17 Tf[0][1] = newCell(-74,-62,-48,-33,2,6)
19 18 Tf[0][2] = newCell(-13,-28,-12,-40,2,10)
... ... @@ -39,6 +38,35 @@ def main(args):
39 38 print(a.toString())
40 39  
41 40 #### Markov ####
  41 + MM = MarkovModel(Tf)
  42 + """
  43 + for a in range(0,3):
  44 + for b in range(0,3):
  45 + d = Location(Tf[a][b].location.x, Tf[a][b].location.y)
  46 + print(d.toString())
  47 + print(d.getPositionInArray())
  48 + """
  49 + MM.moveToCellID(8)
  50 + MM.moveToCellID(7)
  51 + MM.moveToCellID(8)
  52 + MM.moveToCellID(7)
  53 + MM.moveToCellID(8)
  54 + MM.moveToCellID(7)
  55 + MM.moveToCellID(8)
  56 + MM.moveToCellID(5)
  57 + MM.moveToCellID(8)
  58 + MM.moveToCellID(2)
  59 + MM.moveToCellID(9)
  60 + MM.moveToCellID(8)
  61 + MM.moveToCellID(1)
  62 + MM.moveToCell(Tf[2][2])
  63 + MM.moveToCellID(8)
  64 + MM.moveToCell(Tf[2][2])
  65 +
  66 + MM.printValues()
  67 + print("")
  68 + MM.printPercentages()
42 69  
43   - return 0
  70 + print("\r\ncurrent cell is #" + str(MM.previousCell) + " , most likely next cell is #" + str(MM.getMostLikely()) + " which is located at " + str(Location.fromID(MM.getMostLikely()).toString()))
  71 +
44 72 main(sys.argv)
45 73 \ No newline at end of file
... ...
structure.py
1 1 from operator import itemgetter as ig
  2 +from math import floor
2 3  
3 4 class RSSVector():
4 5 distances = []
... ... @@ -9,20 +10,20 @@ class RSSVector():
9 10 self.n4 = n4
10 11  
11 12 class Location():
12   - def __init(self):
13   - self.x = self.y = self.z = 0
14   -
  13 +
15 14 def __init__(self, x, y, z=0):
16 15 self.x = x
17 16 self.y = y
18 17 self.z = z
19   -
  18 +
  19 +
20 20 def __mul__(self, multiplier):
21 21 returnValue = Location(self.x, self.y, self.z)
22 22 returnValue.x *= multiplier
23 23 returnValue.y *= multiplier
24 24 returnValue.z *= multiplier
25 25 return returnValue
  26 +
26 27 def __rmul__(self, multiplier):
27 28 return self * multiplier
28 29  
... ... @@ -33,16 +34,109 @@ class Location():
33 34 returnValue.z += added.z
34 35 return returnValue
35 36  
  37 + def __isub__(self, value):
  38 + return self + -1 * value
  39 +
  40 + def __itruediv__(self, divider):
  41 + returnValue = Location(self.x, self.y, self.z)
  42 + returnValue.x /= divider
  43 + returnValue.y /= divider
  44 + returnValue.z /= divider
  45 + return returnValue
  46 +
36 47 def toString(self):
37 48 return "(" + str(self.x) + " ; " + str(self.y) + " ; " + str(self.z) + ")"
38 49  
  50 + def getPositionInArray(self, arraySize=3):
  51 + temp = Location(self.x, self.y)
  52 + temp /= 2
  53 + temp -= Location(1,1)
  54 + return floor((temp.x * arraySize + temp.y)/2)
  55 +
  56 + @staticmethod
  57 + def fromID(id, arraySize=3):
  58 + id -= 1
  59 + y=id % 3
  60 + x=floor((id - y) / 3)
  61 + returnValue = Location(x, y)
  62 + returnValue *= 2
  63 + returnValue += Location(1,1)
  64 + returnValue *= 2
  65 + return returnValue
39 66  
40 67 class Cell():
41 68 def __init__(self, v_, loc):
42 69 self.v = v_
43 70 self.location = loc
44   - self.Likeliness = .0 # Probability of Markov model
45   - self.pastCount = 1
  71 +
  72 +class MarkovValue():
  73 + def __init__(self, nb=0, percentage=0):
  74 + self.nb = nb
  75 + self.percentage = percentage # Probability of Markov model (100% <=> 1.0)
  76 + self.attachedCell = None
  77 +
  78 +class MarkovModel():
  79 + def __init__(self,cells):
  80 + self.MarkovValues = [] #table of the coefficients of the Markov Model
  81 + self.cells = cells
  82 + self.previousCell = 0
  83 + for i in range (0, 11):
  84 + self.MarkovValues.append([])
  85 + for k in range (0, 10):
  86 + self.MarkovValues[i].append(MarkovValue())
  87 +
  88 +
  89 + def moveToCellID(self, nextCell):
  90 + self.MarkovValues[self.previousCell][nextCell].nb += 1
  91 + self.MarkovValues[10][nextCell].nb += 1
  92 + self.MarkovValues[self.previousCell][nextCell].percentage = self.MarkovValues[self.previousCell][nextCell].nb /self.MarkovValues[10][nextCell].nb
  93 + self.previousCell = nextCell
  94 +
  95 + def moveToCell(self, nextCell):
  96 + self.moveToCellID(nextCell.location.getPositionInArray()+1)
  97 +
  98 + def printValues(self):
  99 + print("\t? \t1 \t2 \t3\t4 \t5 \t6 \t7 \t8 \t9")
  100 + print("---------------------------------------------------------------------------------", end='')
  101 +
  102 + for i in range (0, 11):
  103 + print("\r\n", end='')
  104 + if i == 10 or i == 1:
  105 + print("---------------------------------------------------------------------------------\r\n",end='')
  106 +
  107 + print(i, end='\t')
  108 + for k in range (0,10):
  109 + print(self.MarkovValues[i][k].nb, end='\t')
  110 + print("")
  111 +
  112 + def printPercentages(self):
  113 + print("\t? \t1 \t2 \t3\t4 \t5 \t6 \t7 \t8 \t9")
  114 + print("---------------------------------------------------------------------------------", end='')
  115 +
  116 + for i in range (0, 11):
  117 + print("\r\n", end='')
  118 + if i == 1:
  119 + print("---------------------------------------------------------------------------------\r\n",end='')
  120 +
  121 + print(i, end='\t')
  122 + for k in range (0,10):
  123 + print(round(self.MarkovValues[i][k].percentage,2), end='\t')
  124 + print("")
  125 +
  126 + def getMostLikely(self):
  127 + return self.getMostLikelyFromCell(self.previousCell)
  128 +
  129 + def getMostLikelyFromCell(self, currentCell):
  130 + max=0
  131 + max_id=0
  132 + for k in range(1,10):
  133 + if self.MarkovValues[k][currentCell].nb > max:
  134 + max = self.MarkovValues[k][currentCell].nb
  135 + max_id = k
  136 + return max_id
  137 +
  138 + def toString(self):
  139 + return ""
46 140  
47 141 def newCell(n1, n2, n3, n4, l1, l2):
48 142 return Cell(RSSVector(n1,n2,n3,n4), Location(l1,l2))
... ... @@ -51,11 +145,10 @@ def KNeighbors(fingerprints, sample):
51 145 '''
52 146 Returns the 4 closest cells to the given sample and fills sample distance data
53 147 :param Cell[3][3] fingerprints: 2D array of all the cells
54   - :param RSSIVector sample: Mobile terminal sample
  148 + :param RSSVector sample: Mobile terminal sample
55 149 :return Cell[4]: the 4 nearest cells
56 150 '''
57   - distances = []
58   - neighbours = []
  151 + distances, neighbours = [], []
59 152 for row in fingerprints:
60 153 for currentItem in row:
61 154 dist = abs(currentItem.v.n1 - sample.n1) \
... ... @@ -78,7 +171,7 @@ def resolve_barycenter(nC, d):
78 171 :param distance[4] d: distances of the sample of the mobile terminal
79 172 :return Location: Estimated location of the mobile terminal (return None if error)
80 173 '''
81   - return None if len(nC) != 4 else \
  174 + return None if len(nC) != 4 or len(d) != 4 else \
82 175 1 / (1+d[0]/d[1]+d[0]/d[2]+d[0]/d[3])*nC[0].location \
83 176 + 1 / (1+d[1]/d[0]+d[1]/d[2]+d[1]/d[3])*nC[1].location \
84 177 + 1 / (1+d[2]/d[1]+d[2]/d[0]+d[2]/d[3])*nC[2].location \
... ...