{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## K-means聚类--python实现代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import cv2\n",
    "from matplotlib import pyplot as plt\n",
    "from matplotlib import colors\n",
    "from scipy import io as spio\n",
    "from scipy import misc      # 图片操作\n",
    "from matplotlib.font_manager import FontProperties\n",
    "font = FontProperties(fname=r\"c:\\windows\\fonts\\simsun.ttc\", size=14)    # 解决windows环境下画图汉字乱码问题\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### step1.找到每条数据距离哪个类中心最近  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def findClosestCentroids(X,initial_centroids):\n",
    "    m = X.shape[0]                  # 数据条数\n",
    "    K = initial_centroids.shape[0]  # 类的总数\n",
    "    dis = np.zeros((m,K))           # 存储计算每个点分别到K个类的距离\n",
    "    idx = np.zeros((m,1))           # 要返回的每条数据属于哪个类\n",
    "    \n",
    "    '''计算每个点到每个类中心的距离'''\n",
    "    for i in range(m):\n",
    "        for j in range(K):\n",
    "            dis[i,j] = np.dot((X[i,:]-initial_centroids[j,:]).reshape(1,-1),(X[i,:]-initial_centroids[j,:]).reshape(-1,1))\n",
    "    \n",
    "    '''返回dis每一行的最小值对应的列号,即为对应的类别\n",
    "    - np.min(dis, axis=1)返回每一行的最小值\n",
    "    - np.where(dis == np.min(dis, axis=1).reshape(-1,1)) 返回对应最小值的坐标\n",
    "     - 注意:可能最小值对应的坐标有多个,where都会找出来,所以返回时返回前m个需要的即可(因为对于多个最小值,属于哪个类别都可以)\n",
    "    '''  \n",
    "    dummy,idx = np.where(dis == np.min(dis, axis=1).reshape(-1,1))\n",
    "    return idx[0:dis.shape[0]]  # 注意截取一下"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### step2. 计算类中心"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def computerCentroids(X,idx,K):\n",
    "    n = X.shape[1]\n",
    "    centroids = np.zeros((K,n))\n",
    "    for i in range(K):\n",
    "        centroids[i,:] = np.mean(X[np.ravel(idx==i),:], axis=0).reshape(1,-1)   # 索引要是一维的,axis=0为每一列,idx==i一次找出属于哪一类的,然后计算均值\n",
    "    return centroids"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### step3. 聚类算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def runKMeans(X,initial_centroids,max_iters,plot_process):\n",
    "    m,n = X.shape                   # 数据条数和维度\n",
    "    K = initial_centroids.shape[0]  # 类数\n",
    "    centroids = initial_centroids   # 记录当前类中心\n",
    "    previous_centroids = centroids  # 记录上一次类中心\n",
    "    idx = np.zeros((m,1))           # 每条数据属于哪个类\n",
    "    \n",
    "    for i in range(max_iters):      # 迭代次数\n",
    "        print (u'迭代计算次数:%d'%(i+1))\n",
    "        idx = findClosestCentroids(X, centroids)\n",
    "        if plot_process:    # 如果绘制图像\n",
    "            plt = plotProcessKMeans(X,centroids,previous_centroids) # 画聚类中心的移动过程\n",
    "            previous_centroids = centroids  # 重置\n",
    "        centroids = computerCentroids(X, idx, K)    # 重新计算类中心\n",
    "    if plot_process:    # 显示最终的绘制结果\n",
    "        plt.show()\n",
    "    print (centroids)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 聚类中心移动过程   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def plotProcessKMeans(X,centroids,previous_centroids):\n",
    "    plt.scatter(X[:,0], X[:,1])     # 原数据的散点图\n",
    "    plt.plot(previous_centroids[:,0],previous_centroids[:,1],'rx',markersize=10,linewidth=5.0)  # 上一次聚类中心\n",
    "    plt.plot(centroids[:,0],centroids[:,1],'rx',markersize=10,linewidth=5.0)                    # 当前聚类中心\n",
    "    for j in range(centroids.shape[0]):\n",
    "        p1 = centroids[j,:]\n",
    "        p2 = previous_centroids[j,:]\n",
    "        plt.plot([p1[0],p2[0]],[p1[1],p2[1]],\"->\",linewidth=2.0)\n",
    "    return plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 初始化类中心--随机取K个点作为聚类中心"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def kMeansInitCentroids(X,K):\n",
    "    m = X.shape[0]\n",
    "    m_arr = np.arange(0,m)      # 生成0-m-1\n",
    "    centroids = np.zeros((K,X.shape[1]))\n",
    "    np.random.shuffle(m_arr)    # 打乱m_arr顺序    \n",
    "    rand_indices = m_arr[:K]    # 取前K个\n",
    "    centroids = X[rand_indices,:]\n",
    "    return centroids"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 二维数据聚类过程演示"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "聚类过程展示...\n",
      "\n",
      "迭代计算次数:1\n",
      "迭代计算次数:2\n",
      "迭代计算次数:3\n",
      "迭代计算次数:4\n",
      "迭代计算次数:5\n",
      "迭代计算次数:6\n",
      "迭代计算次数:7\n",
      "迭代计算次数:8\n",
      "迭代计算次数:9\n",
      "迭代计算次数:10\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAD8CAYAAABXe05zAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAIABJREFUeJztnXl8VOX1/9/PTDIJJGFJiAIKDAiK\noFUQREtdWKxIVeoCapX+LP0WlLpUNCralvrt19IWRK2WTYsLdcG1okWxEKuISlm0KouiEEBZDAmQ\nBZLJZJ7fHzMTZrl35s5kJjOTnPfr5Uty5869517I5557znnOUVprBEEQhMzBlmoDBEEQhNgQ4RYE\nQcgwRLgFQRAyDBFuQRCEDEOEWxAEIcMQ4RYEQcgwRLgFQRAyDBFuQRCEDEOEWxAEIcPISsZBu3Tp\nop1OZzIOLQiC0CpZv379fq11sZV9kyLcTqeTdevWJePQgiAIrRKl1A6r+1oKlSilOimlXlJKbVFK\nbVZKnR2/eYIgCEJzsOpxPwy8pbW+UinlANon0SZBEAQhAlGFWynVATgXuB5Aa+0CXMk1SxAEQTDD\nSqikD1AOPKGU+lgp9bhSKi/JdgmCIAgmWBHuLGAwME9rPQioBe4O3UkpNVkptU4pta68vDzBZgqC\nIAh+rAj3N8A3Wus1vp9fwivkQWitF2qth2ithxQXW6poEQRBEOIgqnBrrfcCu5RSJ/k2jQI2JdUq\nQRAEwRSrVSU3A8/4Kkq2AT9LnkmCIAhCJCwJt9b6E2BIkm0R2iAli2ayrNdQKlQhRbqSsTvWMmvS\n9FSbJQhpjfQqEVJGyaKZLHGOoMLWBZSNClsXljhHULJoZqpNE4S0Ji2Fu2TRTAauXEHX0g0MXLlC\nfpFbKct6DcWlcoO2uVQuy3oNTZFFgpAZpJ1wZ5IXJg+Y5lGhCmPaLgiCl7QT7kzxwjLpAZOuFOnK\nmLYLguAl7YQ7U7ywTHnApDNjd6zFoeuCtjl0HWN3rE2RRYKQGaSdcGeKF5buD5hMCOPMmjSdq8re\nocizH7SHIs9+rip7R6pKBCEKSenH3RzG7ljLEueIIG/2qBc2OnWGhVCkK6lQXQy3tzShJXUDaray\nJuAeVihvGIdFM9NCFIPs7TW0ycNe1msoi50XsmzlCikLFIQIpJ3HnQwvLBne54CaraB18Eatvdtb\nEKNY+6qCs9I2jGNk73PO0TzrHCX5AkGwSNp53OAV71lBW+L3tP1CkWjvc1N+P1AqeKNS3u0tiFGs\nPcwuH8kK48SyiMbIXrfKDtvP/6CZFfaJIAhp53EnmmQlEdMlxh3L+ZIRxom1uiYWe9MlX5AIMiHn\nIGQOrV64kyWw6ZJENT2f9gT9aNcu6pUj4cIR64MxlvuTbgnpeJHSUSHRtHrhTpbApkspm5kd51Sv\nacoT5OkqFIoa1aFJOBY7xyRExGN9MBrZm6UbsOvgoUqtqSxQSkeFRNPqhTtZApsupWxmdrw47kY2\njhrN3pGDydWu8DiyUgnx/mJ9MBrZe03ZCn5StjLl9zJZpEtYTWg9KB1aGZEAhgwZotetW5fw48ZL\nW+5AV7JoJoudY0wTln6KPPvZOCr2JHBo8he8D8bWJLzNZeDKFd4wSQjx3nOhdaKUWq+1ttSFNS2r\nShJNIqtUUkU8Dx+/qEYTbYjf+5s1aTok6cHYWh64mbI2Qcgc2oTHnenE69WaeXpGpJv319o8+dby\nEBKSR5v2uNP9FyQe+yIltyLVOZt60VoHeeHp6P3Fe83pSmt46xPSh1aVnIxWdpXqWloj+xY7x9C3\n9L2ItlSoIpPtkcMbppUzSnnFW+uoiUCr9yzR91YSeoJgTqsKlURKApnFGY1EK1lee6TQRSRbFjsv\nBBX+jI0U3ihZNJNXncOpocA0xp2vq/hq5Lmm9loNV0TaD4jrXkpCT2hrxBIqaVUedyQvzWotbSIW\nS5h5n5G8RbO63mW9hhqKNlqbljT6r8Fbt22emKyhIOJ1mN2zxc4xnBDwlmC23yvO4XHfy3SpkxeE\ndKRVCXekmmKrr97NXSwRSfijLfoxstFc7HVM/UDiwfTcSlGrOvCscxQli2aa7ldLQdz3Ml3q5AUh\nHWlVyclIZVfe1/XobVibG1uNJPxG9pnZ4g/XYBLfjvQQsGprHtURP7eh8UT4vFE5WNZrqGmL2+ba\nJwk9QTCmVXnckbw0o1dvtIcKVRQUzmjuEvlIwu+3L09XhbWEDQwDBHvt4aEOh65jQM1W02SgFVvt\n2sXlZasj7uOx8M+jQhVSrxyG15Nv8mBoLT1IBCFVtKrkZDQCk46gwkri/Mm05tQPW02qRUqAmiYx\ntaZIV3gHJRQMomzU2RzML2DA0veCbAxMFm669Fw61VTTvfTjpsPYdCPXlr0dlmAMtWdZr6HR68BD\nSgvRGgdHcOD2xdB1UIy+JWux0700VBACabPJyWjMmjSdjaNGez2+EE+2qUa4mbFVq0k1/1uAP/6+\nrNdQC0lMzcZRo9mU3w+XyuVgfgGda6rZdOm5QbFj/zVsuvQcOtdUczD/aBIySzfQjloWOy9s8tTN\n4vIDaraGv6UEmeMx7Enuot3RxKiy+UoPWzZOLR35hLjp3x+mTo28z9Sp3v1SRJvyuP10Ld1gWqlR\npCua7ZlZ8fSMSuiydAM5HKHWpITP77UH2r/p0nOZe8vN5B5pZEffIh6ZWuLdubAQDhygpn0uw5a+\nToUqJJ8ajpBLo3I0HdOh63Dg8gqtwfmO5gcKUYDGa1ce1aZ2GtHSZXxSTijEzdSpMG8e3HgjzJ0b\n++dxEovHbUm4lVJlQDXQCLijHTzdhTvaUvBYX+dLFs3kFedwr5AB+VRzWdnqiN8/ofQ9ag3E0opN\nofbf8O4/mmLM2Y3ZTFj6Av0++ww6d4bKyoAHSZGx0IaGO5q2e9g7crCpTbEsqffap1ssZGH+cPYw\nsWy5hFCEyEydyhPbPmf3cfCje2dzep8zm7YnQ7QheaGSEVrr060eOJ0xTFQGEGv537POUV4RVt64\neY3qwHPO0RFXGdZGqaFuwmB149gda8MGJfjP3WBv4JnLLmP2bXex5ok5UROdTd81wEbkh7pZwtf0\nHC0YsjBLgOZTIyEUITpz51LZsQPtD+Xxr+m/4/Z7L+GLG69JmmjHSpuKcfsJjmMbi1Ms5X+BoQc/\nbpVtKv7eMj9rIQZ/XDvQI/T+OYIIK0VNQS5vrd/ZrJruaFUlRvmAc6rXRI6Lc3QRz8CVKxj/2ryk\ntCEwyzVo3/lD7ZGhBoIRHrsdGza6b/XwZvlB7p90Dp/ccX2qzbIs3Bp4Wym1Xik12WgHpdRkpdQ6\npdS68vLyxFmYJPyJyuaWrEUS+MDPAldTmvUeaY4dTfh6kORX1zF2iLNZvT2KdAUQuQ+J/z7uHTmY\njaNG8+K4G4PE3OzBiFJNE+mT4f2aJZlryTfcX3qgCBFRika7nZyaAp6f/ZtUW2N5Ac5wrfVupdQx\nwL+UUlu01u8F7qC1XggsBG+MO8F2JozAxGEeNRymfdg+WbrBcre8SItP/KJrlIg0JCTWbNcuUzvy\nqaaGDsHfxRvjvvKVZzlp82Z4sjNFL74Q0+IYP/5KmJJFwYuGKpRXXFk00zQuHLhwZuDKFZHPb1bd\nE7PFke3wMpplJvZIbbkQEe3B7tHUdqzlJyVzUm2NNY9ba73b9//vgFeBM5NpVLIILRGrVR3QKvzZ\nZaeBZb2GWnp9H7tjbdi8RAgUf2tL0LN0A4rGoG3KLBwCXFa2GqUb2XTpuWQ1NJBfXQ9ZR8jd+hFL\nLvmBNzF54ABrLr0kaugiiJCYenNbAETLJxiRTO9XeqAIVggs2tBodvezM7a4E/cuWsX3Zi1KoWVe\nogq3UipPKVXg/zPwQ+DzZBuWDKzGe+tpZ/n1fdak6Xy/ev3RsIDW5OgjXFO2oskjjdgX2/can8OR\nsIeIW2U3xYKNzr9x3Ag611Qz9S+PMPuSq1nTsTcAO9oXQ2UldO5M/uE6Pr90hHnIIgCHrmNi2VtB\nMfXmtADwv924cGDTjZZsgOR6v9IDRbDCZz//fwBoPJz/6xIeuP91Tpz3nDcxOW9e9DrvJGMlVHIs\n8KryvtJmAc9qrd9KqlVJwrInF8Pre8mimaxxjggqPdM6+Ptm4ZQiXdFUU9y1dIOpLUbhiWW9hvKn\nmmoO+FZOAjTavX+dDR7fX2tlJRQWkn/gQNRkqE03Bq28DFphakA0cfVX2/gTtx5AaTdKg8fgLacJ\n7Un6UIfW3gNFVow2j+opk3n3wD5wZPOjm+/k5FPPP/qhv5pk3rzgn1uYqB631nqb1vo0338Dtdb3\nt4RhycCSJxdjlYmVUIKV1/NotoUes0IV0r304ybRhqPCneeuPZpQfGkF3VeaPBQCbPEvgQ8NJ5n1\nSokWWnjFOTys2karLAv9T5SITDOQFaPNQ2vNih1bcTmy6XPGmfQffl74TnPnej3v0tKWN9BHqygH\ntDJ9pWTRTMNmSHbtIl9XNb02m3XMMxNWK6EEK6/nA2q2Rg0lBB7TyB63T7g7uw5FFV8AtCZPV+HA\n1bQE/hXn8IjhpEDPPBLmdepRps37KlniJdVTjlJNc3MSbZ0tq99lW8c8HO3aM/p/pqLMfnfmzoUt\nW1rWuAAyXriteBiGgwV8ovWTspV8NfLcpnK2y8tWx5S8stpNMLRsLlT4NuX3ixrOCDymkRffaLcD\nUEu7qLF8h67jnOqPaMDhuy/eexdtYZAniR5xc5OE4m3KyLfmcPjQQUqfXAjA+T/9HwoKY6/Gaiky\nXriteBiGSUmlyNWuMBGKNXllFgbp0vAd3UvX07X0Y7qXrmf8a/MiXke0X6xQUTOy87zyTwBo9Jh7\n2IHX5G9WFUQMD49ImNXH23EZrLbU5OuqZicJxdtsflvitszKJxZQV11Fz1NP55QRF6TanIhkvHBb\n8TBi9UKieceh+4YKaG/XNr5wnIxH2UEpPMrOqoKzIoq36S+W1th0I8OqPzZ8yATaecPF1wGQ22hW\nfqeZWLa86ZoiVrsYEItH7C1XdIdtV9gYVv1x0P2aWPYWX408t9mevHibUu4YL1v/8wFffriK7Jxc\nfjj5JvMQSZqQ8cJtxcNoaS/kS0d/w3anqwvMy99N6519wr+mYFDUV357djYARYcPGYuvsjV5nyWL\nZpr2IsmnuklY/WV8sZbNzZo0nTwOh213q2w25fez/GCMBfE2pdwxHo7UVLPyb16n6gfX/D86HtM1\nxRZFJ+NHl0UaV+Yv87KyT7yEroqsUF1MPdZIFRWzJk2HCF38/P09lq1c0eQ9NU1xx9tmdcKny+kC\nHNepGG+XgnCvoUIVNtnsUfawzx26LkJnw+j3KriU0DheniwPOJl/z5lEay93TDTvPv04tQcP0P2k\nAQy68EepNscSGe9xW/EwkumFmMXPzQhNmgZWQAC+uu7I/T2edY7iGecFAcMKvMN73+jxfQAaGxoi\nep9mC5GsVoxEujYr1SzJ8oDF2xRiZfsn69n47krs2dlceMMtKFtmSGKbHKSQSCINZTCrgY42Is3S\nyDADOlZVMvnZOXQoPpYvB/c1Pf5i54Wmvaoj9d+OhpX+3C05ukwQIlF/+DBP3fFLqivKOecn13Pm\nuCtTao+MLmtBzLzHHI4Yhkz8VQ7RpsHH2t8DoNHmjXw1uhsiep/JigVbWdovoi2kC6uefZLqinKO\n7dOPIRdflmpzYiLjY9ypxiyuOqHsXa9naxJnNsM/DT5SvNsMd5ZPuBsaAPNYZ7JiwVaW9ku8VUgH\ndm38lP/+axk2exYX3ngrNnt4viedEY+7mcTr2Ubzev2lfhPL3grzvu3ahc2g1A6bd/qMuyG8W6FV\nm5uDlKIJmUBDfR1vL3gEgGGXTaC4pzO1BsWBeNwJID7P1jjGHer1BnvfR5sGQXhVyRmHPwPA5Wqg\ne+l6PNhMhx8no/LAzFYJjQjpxOolf+fgvj106elk2GXjU21OXEhyMslE6tSWyC5uJYtmsqTX+dz8\n2B+wac3syfehbd7XP0kICoKX3V9u4fnf3gnAT+5/gK4n9EuxRUeJJTkpHneSieTZJtLrXdZrKC5b\nOxrtWdjcDWQ1NtLgE+5ETpURhEzF3dDA8vkPo7WHoZdekVaiHSsS424l+BOe/g6B9ka34eeC0FZZ\n88rzVH67i87djuPs8T9JtTnNQoS7leBPavo7BIYKd1ta9i0IoXxXto01/3gRlOKHN9xCtiMn1SY1\nCxHuVoK/osPvcWcFCLdUdghtmUa3m+XzHkZ7PAy68GKO7z8w1SY1GxHuVoK/xA+bt+Y72+2KqzmU\nILQ21r3+Ct+VfU2H4mP5wTU/TbU5CUGSk62IWZOm8/SWmyk/dICVg/txbO8TfJ/IohehbVLxzS4+\nfOlZAH44+WYcue1SbFFiEI+7leFv7epfPSkIbRWPp5Hl8x+i0e3mlBE/pNf3Tk+1SQlDhLuVkZXt\nHdDbGGX1pCC0dj5+8w32bP2C/M6FnDdxUqrNSSgSKmlliMeduSRyQVZb5+DePbz//NMAjP7FL8nN\ny0+xRYlFPO5Whl+43SLcGYUMOk4c2uPh7YWP4HbV03/4eZxwxrBUm5RwRLgznbFjYc6cph+zsnwe\ntztAuOfM8e4npC0y6DhxfLpyObs2fkq7Dh0Zcf3kVJuTFCRUkiGYvkaPHg133OHdado07A5vjNvt\n8sW458zxfj57doosF6wgg44TQ9X+ct57ZhEAoybdQPsOHVNsUXKwLNxKKTuwDvhWa31x8kwSQjGa\na7nEOQIWzWTWNG8M9Im3/8HhL0vpeqL3tbDR3RAs2tOmpcx+ITrmvcxlxatVtNaseOxRXEeO0Hfo\nWZx41g9SbVLSiCVUciuwOVmGCOZEfY2eNo3Kjh1w7W9k+5qPANj9xgsi2hmE9DJvPptXvcP2T9aT\nk5fHqJ9PRVkcQJKJWBJupdTxwI+Ax5NrjmCE1ddoj92O8k3c2fTNXv46eSw7rr4k6fYJzUcGHTeP\n2oMHeOfJhQCc/9NfkN+5dYeYrIZKHgLuBF/XfqFFiec1WttsHDmgefKPJcz4yz+SaZ6QIJIx3KKt\nsHLRPOpqa3CeNpiB541KtTlJJ6rHrZS6GPhOa70+yn6TlVLrlFLrysvLE2agEMdrtPZgb2wkq6OH\nSdMlKSm0br786H22rvmA7Nx2XDD5plYdIvFjJVQyHLhUKVUGPA+MVEr9PXQnrfVCrfUQrfWQ4uLi\nBJvZtrH6Gm1rbMSjPOzuZ2eT8ysmP/02PZ5bmiKrBSH5HKmuYuWi+QCce+3P6NDlmBRb1DJEDZVo\nracD0wGUUucDd2itr0uyXUIIEV+j58yh8FAVh50duHLGQ1Rm1XLdsuu497aTmXPHHd6otyQohVbI\nO089xuFDBzn+5FM4bfSYVJvTYkgdd6bjK/n7WUD1yPFa06tDL1b038HG+2/hlIA6b0FoLWzbsJbN\nq94hy5HDD2+4BWVrO+sJY7pSrfW/pYY7zVixIqzkTynFxX28f02Lh+d4P1+xIlUWCkLCqT9cy78e\nexSA4ROupXPX7im2qGVpO4+o1sqyZYaetF+4S3eWUnvzFO9+gtBKeO/vT1BTWUHXvicy+EfjUm1O\niyPC3Uo5vuB4Bh8zmLrGOv6141+pNkcQEsbOz//LpyvfwmbP4sIbbsVms6fapBZHhLsVc+kJlwLw\nxtdvpNgSQUgMDXV1vL3gLwCcfcXVdOnRK8UWpQYR7lbMBc4LcNgc/Gfvf9hbuzfV5giCdUK6Xvp5\n//mnOfTdPop79Wbo9m/abNdLEe5WTAdHB0b0HIFG88Y28bqFDMLf9TJAvL/9YjMb3nodZbNxcW4n\n7Hfe6d2vDSLC3cq5pI+3V8nrX7+O1jrF1giCRaZNg9mz+TD/QVbNPZvybz9n+fyHQWtG5xdR+H/3\nt+kGaiLcrZzvH/d9CnML2XZoG5sqN6XaHEGwzrRpHO7roKHPPv67aRz5J63hZF3DqX97qk2LNohw\nt3qybdlc1PsiwOt1C0KmoR0KZYeiflXkTtrJ+48Oo/K6tr2cRIS7DXDJCd5wyZvb36TBI7MohQxF\neUW8/qTvWPP+xFRbk1JEuFs7Y8cy4Km36NOxD5V1lXzw7Qfh+8hMSiETcIOt3kPOF8dy1jlhfe4o\nWTSTgStX0LV0AwNXrmjVg5ZFuFs7o0ej7ijhkt2dAXh9W0i4xD/erI1m54X05cBBX9tirdFu0IdP\nY/DGaznnpo/ovDj437F/vF+FrQsoGxW2Lix2jmH8a/NSYHnykSZTrR1fAue1QwugvYOVO0qpclXR\nwdFBZlIKaYvbXcvmDydDDtgq8jl9xMt0Lu7n/dBWGDQgG4zH+6EUqwqGUbJoZqubJCQed1tg2jTK\nujtQWuPWDVzyxg1sffB+EW0hbfnqlWs4klNF/pEizrtyHZ2L+x0NhZx+Pn+aMhl9++1Ndd5m4/1Q\ntqOzWVsR4nG3IbTNOxmksuozrs7/lBPnjec3V13NgBTbJbQ+ShbNZFmvoVSoQop0JWN3rLXs9VZU\nvMe3XTaiPDYGnPc0NpujKRTi96ofnHADR8jlvCUvcM3p52ND4zE7npmoZzAqGYsyhgwZotetW5fw\n4wrxc+pTp4Zt0yjatT+ZteOXpMAiIVEcFckibHjwoCKKZXNENfL5vccbULOVNQWDgkIXDl1nafhx\nQ0MVa/5zEfX1ezmhzx04nTcCMHDlCm/8OhJag8HYsiLPfjaOSv8cjlJqvdZ6iJV9JVTSBlEecLg8\nnFo3gMUXPJRqczKaVFcyBCflFB5lb0rOLXGOCLPHKIlntF+0c/qvuW/pezzrHBV0vFUFw8LizS6V\naylk8eXW/6W+fi8dOgyiZ89fNG235DUr5RXvACLOZs1gRLjbEFkNGqXtuPNHcHzNL/jbr5bSf9Fz\n4TtKeaAlEiGCzcUwKecjUCz9YrvYOSYmUQ19MI1/bV7QNdeoDjQqR/CXlLGsNImvSQOp8vK32bv3\nVWy2XE59tz+2iy9t+qxIVxoe04hos1lbAxLjbgvMmUPfw/W0Kx7Mb48MpvKhF7j8wUlMuv8hnrlz\nKnY4mqAMrDQRImIkmn4RnGXynUQTzROtUIVh8WGrxwn9XoXqwqqCQlNhjkaT+PobSEHTvzuXq4LN\nW34NwMD1p5Nb8oegf4Njd6yNeg3ec1SEhEXSP0QSDyLcrR2fEL86ezZM8YlzQxadqg7x70FnMmPa\nr/n97bfTFBk0qjSZM8c7+kym6ARhJpotmQwr0pVUKPPYb5GujOiV+8mjJmybcYmdRdEOiTcfDVmM\nbvq35fnqt9Tev4DsKS/x5Z75NDRUcPzHXSgueS7s3+CsSdMhIJaeRw31tMOtso3P0coR4W7tGMyk\nZNo0Dr7zCWjN4xf9GJtbccfDj9Bh1w5j0RYP3BAz0YzltT4WjJKKY4HFzguNBVV7GLtjrffzKLjJ\nDtsW7wPIoesYVv0xm/L7GSZASxbNZNlpQ9lYZSf/yB70oz+guNhBY42Dvves5c9TJrO/U33YW8us\nSdODtiU6yZpJSFVJG6XrO58c/UFrchpcjNv8LdNGDMZ5mtO7XRboRMQoBGG1eiKR51rsHGNYTYHW\n7B05yHJFxt6Rg4I2mX7PpHoDrbHhYXj1f3hx3I1Rr2Pvu+cFHZJGzTZ7F64/axY7co5rtfFpM2Kp\nKhGPWwClqHfk8OL3erP1q/089sKHFDt2knPfdBHtCIS+vifT64sUTy/SFSaefwUAA2q2sqqgyFhs\nI2AaVzY7jlJ4sLOmYBCbv3cSJ18/hZJO9UH3p845HJfKJcdTD9vdsLsRhud4D5ml6EMFz2+5jTNO\nX5r0XEEme+xSVSKQ7XaTW1/HhE27mfnfOmjoRnn1Gez5+YPU/fjqVJuX1syaNJ2No0azd+RgNo4a\nnbRf/ApVZLq9XjlMy+DGvzaPVQXDoop2HtVh22ZNms5VZe9Q5NnP3+++iSkvLg7/YsB5p7y4mL/f\nfRMulcvS4SPQt99Owdq9QVU3tRTQ9/AOPvr7eHjpCHT3Dvr1eEA3aL7WRUw4+SHftSUvV5AOFUHN\nQYS7DeNwuchxN3JlYy5vvrCBOXdey3Fb14PNDlk5uAtPZ9+f/8WB55fg2rUr1ea2aWym6wKhRnU4\nKsxak6eruKrsHQBWFZwVNaFo1y4uL1ttWKbnfzCtGnwmM+Y/yBO/vpW/331T2DGmvLiYGfMfZNUZ\nwwB4cPwUfnfDbZy0fyB/efafOA9VgNZcte8tSl/4Kd1e+AaubIfuaccDrDmuHw9XX0Gf35cxeulq\nIHm5Aoj8BpMJSKikLTJnDgM79OB01Z47LhtBt8L2fPPvA1SOu4/C12ZQeekM6o87Bb19FUe+Xs7h\nf1cBkN2jB3nf/773v2FnYu/UKfzY/fvDyJEwd675+adOhdJS2LIlSReYOFLxOm10To9ZgjHUk1aK\nIzqPxc4LsWESiwafp6z55oKhHOpcQNH+g3AwJ6xMD4DevfnNzp0sP/sczt/wH5aPvJjiQ4cp79ge\nGx5+8eKzzJj/IPfdcBsLxvv7ZGsWTPgpv1lSia2xJ9e/6aJ7wVJGlT+G46Vqvr3weLrlVbLN1oX/\nd9Zsvs7pAyfCAXchM+Y/iF27qR7alWRViKRDRVBziCrcSqlc4D0gx7f/S1rrGck2TEgSvoTjSoPY\ndf1xp1B58a8peuVeGkdfQNZbr1Pz059yqKADtWvW0LBrFweXLOHgkiVgs5E7cGCTkLcbdDo2h8Mr\n2vN8rTSNxHvqVO/nNxonr9IJozrmJc4RkMRuc2bntNNAIzmWjuFRvvBDpJ2UoshTwaHOBRRWHGJH\n1+6MfeZpZk4Yw9zPHRxfsoB7bruCPsOHQlkZde1zufDDVTw9cSK7evTgyg1vU5XdjQHbV3H9k88x\n8+clvD5yPCfscZHr0t7/GrxhFI/du0Dnm+qzWZx9Js7x7zF82ePcd+UUFpzvFXqbdtOOwyy48lra\n61p+M/8vqH4PxHcTLdDSFUGJJmpViVJKAXla6xqlVDbwPnCr1vojs+9IVUkaM3asdwFESMnf3s86\nobOqKbx3AjmvPOctI/QvlJg9G33rrdRt3EjtBx9Qu/oDDn/yCTQcnaaj2rWj/ZAhXiF/p5Sd76/m\n8+4D6D/vIQaceoJ3p0DRjuRyHHY7AAAgAElEQVSRpwlmVRWJ6n1h5Fkv6zXUeiWHWXWHVbQmCzer\nfzKOc594hR4Hq+lSfYRPttnJdjfwxpO3cGLFLlwdO5NdfYhXJ1zCZyedHvR9W6OHzpW5aAZj91h7\nsICHwqyvuO2Ks5q25Okqvh55btM9ufKlZYza8D6vT7ksKQ/JlqwIskosVSUxlQMqpdrjFe4btdZr\nzPYT4c4gopX8mXzuqa3l8Lp11H7wIbUffED91q3h39WaRmVjXb8zOa8wh95PL8wY0QboWrrBtD56\n78jBzTq2mXC4yLEuxtqDA1fUxTWW8WmBs8rF//7pt1zw0dt8UdSDcdc/zKn1O+lTWEN7ZTD6TkO2\nuyMn5v+AnPZZvFNdySFHLnUOxfAtdU272TwNKI+HQrWB2Refxc4OAQlX7WFi2XJLYpqo8FW6VZUk\nXLiVUnZgPdAX+KvW+q5I+4twZxBGHngoFlZONnz3HYc/9Ip47Qcf4i4vD95BazYX9wv2wNOcZHrc\nZse26camUEdUtGZi2VtN4gOqeR54wHEB+u7bT5dPK/lE5wOabvZaLsze3LSbavRg9zTSw9WeMbfd\nwLHdvUIc+FDyxrhdKJuG4u1U7/+S2xf+JSQe7usvAlHvdzp6yokimR53J+BV4Gat9echn00GJgP0\n7NnzjB07dli3WGhVaK3ZcnJ4l28Pii3Ffbhi1RspsCp2kiUSJYtmRlw046A+2Is2CYnYdCO7R57R\n9LPpG0K8aE2eW5O1vIxzbeXcM+1KnlrwCHa3G48tC6U6krvva+5YOJdZUyazf2ivoNWR7deWM2B/\nf1Sn8iAP21+B4hfvowuJzFeA+t9wkh2+SiVJW4CjtT6olPo3MAb4POSzhcBC8HrcsRxXaF2oEJFp\nBOwezRfH9OXk+Q+nxqgImL0yJ2OBjf9hYOYZ2/BwVdk7Qefs0vAdXzhODv6O1gyv/g9wVLij9S2x\nTIDH3WvLHv5QvJ9e99wBXy7jmO7HkZd/HJud2Tx78tm41AhqbTnMmP8g/8fNlOBN3M46mIOe/yD/\ne8OtzJtwfdDh/Z72jPkPgtZsGtPPV4ZnfE8CE4bNrQZJt/BIvFipKikGGnyi3Q5vfc6fkm6ZkPlo\nTYMti49O/gEXdNBc/tRC+GuPtIpxR6scCe2P0dzytGgNnzwog3PC+NfmsbrgTDzYTJeVW+qgFymh\n6RPs3odc/OEP0zl/3TvsPLYbj/7hZmZdcgksXcrUSy+F1+YycOWKpvMECvEsJsMkYMUK1AMPUNOp\nnnxdRQ0FQeddMH4iNt3Ipf95myfGTzC1ObRxlNVqECOBBlq8SihZWHmv6ga8o5T6FFgL/EtrnRnv\nukJqmDqVLJeLzcX9yHppKZNfmU/vJxd4E5Pz5nmrS9IEs4UYrzqHJ+V80TxDo3K0kkUz2ZTfr0m0\nPSg25fcLW+XnX+mYp6vCVlI2YTBsYM01Y8mpq6Pvvv08O2MGP/zXC1zz5znsPLYbPfft4eZ7/sI7\ne/fx5tnn4nn9dZZePTbsOhaMn8h9N9zGGRt8L+LLlsG0acyaNJ0c7TJ8WDw9/nJ++ueHjEVba8N+\n2mN3rMWh64J2DR2WYLYq8lXfcvtAMmnRTSDSZEpILNFK/tKsJNC8csSb+IvmiRmN7Qrsihf6c51y\nUKs6GB7LrILCzIuOFG/3LnU/yzSO7t++5pqx9Ny3h53HdmNrrz6sOmNYUNIw8PNhzy1jyouLOWf9\nGibN/DMu1T7s0Eax5kjVOUDMlTvRwh2xN8dqfpVQIpDRZULqKC2NLMpz53o/Ly1tWbtMMF1woVRU\nT8zIs1tVcFbEn+tph127gg+ktS8p6Qo7h9UJN6G8OO5Gw/4joRxXvq9JlK+b+UiQaAMMe24ZO4/t\nxnHl+wCvZ33dHx/FRTvLY8LM7nGRroz4mRn+ZfgTy5YD3ra2gWPjYl39mCmLbgKRJe9CYrGyjD0N\nPG0/3n7VxhUe0QTAeNBA+BL0QNwqm3xdRY6nKqyEr4YOYTFXKxNuzLi8bLVhVYwDFzV4vf7jV6w3\nt93HsOcMykADeqOAbnq7WNZrKItLN4S8bRR5vesAzzpQ5I1sNBuIEDgYmYAqlMB4dVGvoYZx8Dyq\nadAOy+dKZ8TjFlo9kQb6zpo03dQzjeaJxdvXooZ8No4a7T1+iFiGetHRbDCLiXvnS17IU9N/xc0v\nPBY0g/GystVBcWJ/V7+4UEcnyq8pGGTytqG8Aqt12CzIwA6E0eZEhg5GDg2x+O+dWRz88rLVls+V\n7ojHLaQ1zS3fstJvxMwzjeaJxVt+5xdbK6VtkSpFjGwMvd5/nzGcGfMf5NQD27n0+WVH921aWv4m\nMxZ4a6qNUNqDjrKwp0IVGb+1GPxc5PHPhDxqs9XKHSsj2CpUYdQyzkRWCaUK8biFtCURPZOttO+M\nxesLxMizC6vmiBAHthLfDbZNY9ONEW0MvV5/tcc3nZ08VXI/+76taDruxv9+2iTaobFtv+0nuiyE\nvpT1FZvN6b5n5bv+e9dSfdJThVSVCGlLIlbJJbPfCMReVRI6e7G5KzNDz1+hjKew3/DuP5pWPHbr\n3JfLjuyh+Nd3sXTCGCZPvj9ybXciltH7aM4Kx2gj2DJ96buMLhNaBYnomZzs9p3RX/PNf27uykyj\nMJBp/TbQmOX9dd99YCsLGhvpcfvvGfOrGzjps+XhKzP9NEfQI016jwPDsFFAcjRTV0HGgwi3kLYk\nQnSNftnTqZKgOSszLVW1aE2PA3uCt9kUblsW27MaeHrRM7z7m1voVfoB9YTXZceF1uRRzeDqjaZv\nG/EQ/UGX+r/PlkKEW0hbEiG6LTnQt6WJ9ObhaHBx0r6dDNhdRucjNUGfKY/G3uj2dfW7FoAJZe9G\nXy7vP7auQ6Gpp53xDkrRoB04Kw7y4rjAv6fmC2uiWxBkKhLjFtKa1tIUKC6itNwduHIFV778Jues\nX8N1f3wUtOaY6oMM2L2dvuXfkOXxrkysdeSS56rD5najbVnkHOnGRe4qTnv4rqA+6yWLZvKM84eG\nbWVtuhEPR0v/XnEON10B6qc1dOxrSSTGLbQa2rSH5Z9ABIbiPfOxOVz8wlvcN+VXnLynjAG7t1Nc\nc6jp812di9nYvTc/Ll1KB2zk5R/HSSOvYP1ru9k5sIjTZtuDju9/O4meMB3N4tINUc3PlPmNmYgI\ntyCkKz6xHuObAdmuzyFKTxxMhSrkthcXcseLy3nhmitxd+/MeV9+AkBdVjZbuvZiU3cnVe3ymfrC\nE9w1fwHqgQdg2jQOV7lYv3Q3335xANfsW3CAoXhHe8uxUsOeiUvJMwUJlQhCmuO8+59kuxvQdkXn\nDi5+tOMD7lo8nyUTJlDWuzcAPXr0YMiQIfx93T9Z5jyzSXRfuu2XnHz9lCCP/aU/rWPf9ioumnIq\nfQYVW5pwFEqk5ldw1EsHWm2oK9FhvKRNwLGKCLcgJA7n3f9s+rPN00i2p5FT63fSo8thyrt2Zva4\nH9O1a1fLx1v/Vhkf/WMb/b/fjVE/PTluuwKFK48aFN7l/Gb9ryHza639JGM6ksS4BaGV4PEEO1Ye\nm516m511WSfwtbuOPf36xCTaAM5Tu/DRP7ax47P9eDwamy2+BTZGAx+OMjpo2IIf/6pV8+9lBpFW\n5LbEtcmSd0FIU/676yCXzfsgaJvd4yanoZ7vHSnjwNDuccWRC7vn0aFLLkeqG/iurCpR5oaRiAVU\n6Uqqr02EWxDSjP019dz10qf8eO5q/rvrIAD2RjdZ2k1hxwYuO7yGfzxyC5PeXGLY/zoaSimcp3oT\ni9s/3Z9Q2wOJp9d2ppDqaxPhFoQ0wd3o4YnV2xkx+98sWbeLLJtiSvsKTiwvYyR7ucj5BQfOPoYn\nx1/NfVNu49cLHuGct1fFdS7n97zCXZZE4bYyZixTSfW1iXALQhrw0bYKLn7kfe57fRPVdW7OPbGY\ntzp+zfTfXc/bA+t5bNYUcnMaceEApVgwwdv17+IX3mLp1WNjPl/3fp1w5Nqp3F3LofIjlr4Tqa+5\nEfF2XcwEUn1tUlUiCClkz6Ej3P/PzbzxqbefiGoH9Sd1plOXWl6edlNQKZ9Rd7wpLy5m1PpVnLvm\nPzGfe/ljn/PV+u/4wfh+nDaqR8R9k1FFIQQjMycFIZWMHeutjY6A64EH+OCC8Yyc/S5vfLoHm/Lg\nOaEdR4Z3x3NseyrtxVz40FOUdKpv+o5R4mvB+IlMmDk/LjObwiWfRQ+XWOlrLrQcItyCkGj8S9VN\nxHvDb2dz+Ne/45EugznS0MhFp3QlZ3gurr6FYD9ammd1jFm8CbFepxShbIrdXx6k/og74r6prqIQ\nghHhFoREM20azJ7N1kf+SukFP2bvtl0AlO2v5c83/pFes3/PjT++h/Kh3+eZ/xnGvOvO4ED7IsND\nhY4xS2RCLDcvm24ndMTj0ezcWBFx31RXUQjBiHALQjKYNg13joNuO7fw3Y8u4tULruSPN/yRnz81\nk5LL72bU1Kt489ZzGN7XG66IfYxZYhJiVqtLUl1FIQQjKycFIZkoRbZu5KRdG+m/83P+PfR87rhr\nAgNO7RO0m9Xe4wnrlti/P4wcSe8Zs/ng5a/Y8XkFnkYPNnuALzd1KpSWwpYtrbqveSYiwi0ISUC7\nXEE/KwCl6L9vKzt+NY0BK18L+rzFhXHkSJg3j05Ap2N/ysF9h9nz9SGOO7Gz9/OpU2HePLjxxiAb\n22yL3TQjqnArpXoATwNdAQ+wUGv9cLINE4RMpX7rVr69866gbY2A3aPZ1+skBi181PB7LSqMc+cC\nsGT/6djdm8DmZPun+73CHSjavv2E9MJKjNsN3K61Phk4C/ilUmpAcs0ShMxDezxUPPkk26+4kvrN\nm30bNQ3KzldnXUjxNdcycuVSur76QmoN9TN3LvsL+3JAHw/A5tIvqZ3yMxHtDCCqx6213gPs8f25\nWim1GTgO2JRk2wQhY2jYvZvd0+/h8Jo1AHQ86SRqP/uMXSecyoCFj/K93l5xpGNexKk2qcBj98qA\ny9OOxZ6rOPnn3RjyqwnkpdguwZyYYtxKKScwCFhj8NlkYDJAz549E2CaIKQ/WmuqXn+dvf/7ezw1\nNdgLC+k2ZAgFjz4Cs2fTL1Sc/T+nmXj7abQ7+JyRVP71Ay57+PRUmyOYYLkcUCmVD7wM/EprHdYL\nUmu9UGs9RGs9pLi4OJE2CkJa4j5wgG9vm8buO+/CU1ND/siR9Hl9KQVfbQ0awhuGr86bFSta1uAo\nKO3G7q7nFHcpP7xpeKrNESJgyeNWSmXjFe1ntNavJNckQUh/alatYs899+IuL8fWvj3H3nsPHS+/\nHKWUtRFg06aljbdta3ShbJqTizYwpOIr8hY+CY6DEuNOY6xUlSjgb8BmrXXkBgyC0MrxHD7Md7Nn\nc+DZ5wBoN3gw3f/0Rxw9IjdpSkumTqVL5el07VDGkDuuIq/fRd7t9nbeBCWIeKcpVjzu4cBE4DOl\n1Ce+bfdora1PFhWEVsCR//6X3XfehWvHDsjOpvjmmyn6+SSU3Z5q02LHV/J3lVH1iP9nEe+0xUpV\nyfv41g8IQltENzSwf/4C9s+fD42N5PTrS/c//5nck+MftJtySksjl/z5t5eWtpxNgmVk5aSQckrS\neCl1/bbt7L7zTuo+/xyUovD66ym+7VfYcnJSbVrz2LIl+j7iaact0mRKSCn+Bv0Vti6gbFTYurDE\nOSLqdJVko7Wm8pln2H755dR9/jlZ3brR84knOPbuuzJftIWMRzxuIaVEatA/y+Q7yaZh33fsufde\nat9/H4CO48Zx7K/vxV5QkCKLBCEYEW4hpaRbg/6qN99kz+/uw3PoEPaOHel63310GHNhSmwRBDNE\nuIWUUqQrqVBdDLdHItFx8caqKvb+/v+oev11APLOPYdu//d/ZB9zTNzHFIRkITFuIaXE06A/0XHx\n2g8/ZNul46h6/XVUu3Z0/d0MeixYIKItpC0i3EKLULJoJgNXrqBr6QYGrlzRJLLxTHVJ1OBaT10d\ne//wB3b+bBLuvXvJ/d736P3Ky3S++mrvCkhBSFOU1jrhBx0yZIhet25dwo8rZCZ+Dzl0uku8Y7e6\nlm4AZeBzaA97Rw72TlkfPTrikvL6u++m5tln+a59HtjtdPnlVLpMnozKkuihkBqUUuu11kOs7Cse\nt5B0EuUh+4k6nzHClHXtdnPo6quxz55NDeDo3Rvn889TPHWqiLaQMYhwC0kn0ZUjUePivu57ez/r\nxJ5fPEzdtt0AuHbuZN/w4eS99BLfdu9OzuQp9H7lZdqdekpcdghCqhAXQ0g68VaOmGE2nxFg4MoV\n3m2nfY/l3+WA20X53M3sOfQyhav+hvOrz9nbrx9Fjz9O/nBpXSpkJiLcQtyldVa/ZzTB3K5d1CsH\nXUs3xFXOFzqfsWRR8Dm8D4pqyHKggO6dToEfzaZs14e8NriB20W0hQxGQiVtnHhL62L5XmjlSJ6u\nQqGoUR2avrvYeSFdSz8OqjiJhaA4utacWeEO3sGeBdk55PQ+l4u+PSnm4wtCOiHC3caJN3Fo9Xv+\nMsDFTu/qw4lly8nVLtwqO/iAygZKxV2TXaEKyfZoLvm2gec+OMzcdUeCd2hsgIY6Kvau5X9+0C2m\nYwtCuiGhkjSkJbvlxZs4tPK90DLACtWFZ52jaCTb8Lt+Yu1V0ljj4uavD/GjXdl0cXnLW8tzFMX1\nGtwuNPCFeyef1XzOrYsfZFz7yXDVSItHF4T0Q4Q7zTASuyXOEbBoZlTxjiT4Zp/Fmzi08j0jr7xR\nOSIe14+VipOGfbXUrN5N7Ybv+H/uLEDzRYGNZ5wOeq1ewpQjA9jXWMmNFw9hW/EgYBDV2W5+M/8v\n0O/EtBkdJgixIqGSNCPe0EWkmHOkz+JZcg7Wlqo3p1GU8l1TKFprHnlkHq/M+jf7HtxA7X/2gttD\nbv9CXj7+M24ZdoQe7z/Hb+bP4S31T664/ky2dekIWpOnq6ge2hX1wAOmdd6CkAmIx51mxBu6iCb4\nZp9tHDUaFs3kVedwavC2Lc3GFdVOs5K8wLcCM688DK0hZIm5VjaedY5qetPQDR4O//c7ti79hMtc\n3rrrOhu8flw2L/fUnF2+lFk3TedWgDlzWDphDL+9riTouhu0z9v3e9orVlDSqT5thzgIghki3GlG\nvKGLeAQ/8DMXjibxrKUDS5wjKHttHpvy+5mKWmhJHowO+smoDNAQk74gjcrB6m5DqVqxg5qP9uCp\naaALeZTnKF7omc0rxzs45PB+96u8MSxbucJr47JlTF+5InKf72nTKOlUH3dYShBSiYRK0gyjEATa\nQ4Uqilgql0eN6fZoS8TNvPVVBWc1qwNfaBkgMfTF6V3TyD0b61i8KoeqFTvx1DSQ3S2P357i4JJz\n83iiT06TaANhFSlWHmRm1/2Kc7hhQyxBSBdEuJuJWde7eDEUOwulcma97A6TT4Uq8h4rgMB4tKlX\nHuIJx9NfZNak6bx02y+Z+uJTpp41wJQXF/P3u29i2H43D68/zIurD3P5Nw3keODDLo28fPxnHHPL\nINZ0q8ZtMz+O30azh5UN3fR3VaGKDPeppSDtRqkJQiAi3M0gWfMSZ02azsZRo73iY1E8a8g3PJb2\niT7K5n0I+JJ0gZ35Yll6Hk/CcenwEfx6wSNMeXGx4edTlyxmxmOPclzfcfx1/RGG72+kzgYv9sjm\nih/kcfMZnZg54Gy6vfMxdcpBlm6IauOAmq3hHr7WeJS96e8KTN4AEvDAEoRkIjHuZpCMeYmBZXuY\neIRG4mkpEegTpKYknY+xO9bynHN08KIYg4Sh/zyhdkZL6j04fjKHVR7vDz6L0VvKWN+7JwdybHSq\n9zBryeuMff5xKq78MwU9BlOeo1jSI5tXezjCQiGgqKVD0wPIzIMv0pVsyu8X/nnYz7bw45gcN1Wj\n1ATBCBHuZtDcrneh4jegZitrLCTzjDxky4lAjB8uOsT7VDRi1zpIzP3hFaO+IGFJPbsdevaE7dsp\n0pUsGD8RgK0uFx47nLOvgad/MYacmkoqrn6IT08ZwjNOB293zcKtiBhWifSZ30b/Ss3oaIo8FU1/\nBzWqPfW0D9vLLIcgCKlAQiXNIGpf6AgYhVlWFQyLKrxmNdaxJgJDk3ShC2O0yiKHI4aTaSzVmvfs\nCWVl0Ls3Y3esbQpvuBwO3HYb/3v31eTWVLLnmO5MGfd9rj27Pcu6Z0eMX0dF6yYbrYZ/inQlG0eN\nZu/IwWwcNZps3Ib7yTwcIZ2IKtxKqUVKqe+UUp+3hEGZRLyLV8A4zGI41SWQAGGC8MQo0CRCeVRH\nPFSgsJm9IdSSHyRq/vNGe9MoWTSTXn97lh3HduOdv8IYx+OcWr6sab93Jl1B/x3b2OLsw5Dn3qC8\nnS3Mi7br6LXk4ddU0WSjcXVO8MPM6O/KLFdQQ4FUmAhpgxWP+0lgTJLtyEjimZfoJ56YaaAwRUuM\nXl622lT8QgXLzDvNo6bpwdC39D1OKH2PrqUbsJkk9Wxoxr82j2ecF1Cv2jHsuWV4cm3QTXNHl6dZ\ncOAalt73Y/qXbeOLnr25aN4zjPpiB/tzwmPRCkWerrJcQhh6TbMmTWdY9cfB1TRK+eLj5n9Xpp56\nMxpgCUKiiSrcWuv3gPg63rcB/BUgoV5pNEwFwkSoQoUpWrhi1qTp/KRspe+hopv+s+lGhlV/HGSn\nkXdq1y6O0L7pwVCjOlDra8PqUXZDOz3KzqqCYXhUSOpEKVCQ37Ge6t/YKF3chz/e9zMmvrmMp395\nOROWPhN2LLfKJle7mFj2lnkViS8kZCbC3gRlyD9xpZrCI2a9w8M89QCkwkRIByTGnSLMwiznVH/U\n5MHbdKOpMFlJjM6aNN17Hup94qnwKDtrCgYFeY1Gbw5ZNIYLcCB+7zVse4R/Uj4bdDe45tineOzH\nl3PfDbcxY/6DhqWCFaqQWZOmc03ZiqYHkPeeeG2cWLacvSMHmYpwPMnj4Hth/BCVChMh1SSsqkQp\nNRmYDNCzZ89EHbbVYqXXRzDBy8mtLo23WrIYuny9a+nHMVyNRXxCqPYoHnD8D+TSVG0yY/6DwNGf\n4ei1hC+t9zPacGvg92NtHxBY6WPDgwd7TN8XhJYgYcKttV4ILAQYMmSI9bXNbZhovT4iYVT+dzSc\ncvQ4sXidQTXkFuoozITNsDYaRc3BHHo9cJDTPtxL32P/wrDnvKkTv1ifs35N059DryWeHuWR7lHJ\norWGMysD9/cYXIvRPRaElkZpC8kfpZQTeENrbWkc9pAhQ/S6deuaZ5kQFStiNnDlCt8qwWCKPPu9\nnQEDjmW1DhwArTnJtZntjj5hwggeXKo9a64Zy7ZFOXgqbfzJ8Qu+LRrC2B1rufmeh+mxbx87j+3G\nsOeWgdbkcIRs3NSQb9hL3EiArSSCS0I6H+ZRzeDqjawpGBR2PAcu7zi1EGy6EQ9KugcKSUUptV5r\nPcTKvlE9bqXUc8D5QBel1DfADK3135pnopAIrHjshgtztMe7JDxgf8PyxEgoxf7sY7iq7J2mh0c+\nNWi8vT7WXDOWnvv2wCSfOPvOO2vSdEqAW+55iJ779rD2mgv5yx9+ZSCGkW2LZYXqEXKDOh+uKjjL\ncFm7S+cYft+DYu/IwWF2CUKqsFJVco3WupvWOltrfbyIduahCFmQo2xhCUrThJu/IsUAf/Jw46jR\nTCxbjguHr/JEcVx5gEftIzBm3WPvPpTTSY/y/VE92HiSjEdnXY4Jn7oTaVWmARLTFtINqSpJAonu\nGNgcO5Y4R1Cv2kdtnGQuTpp8k8U8kcaUHb9ifZBoGy5M2r4dGhujXkesK1SDa9yti3Qe1XEvqBKE\nlkSEO8Ekq2NgPEQLfwR6rGN3rDUt79NgYUyZcUOsSHXWVh9wRp3+IgmqpbCPwfEuL1sd94IqQWhJ\nLCUnY6UtJyetJgPjIdbKiq6lGyLWVYfaZLq/9jCxbHnEc3cvXe9dmBOCTTeye+QZBtdQBOig8xkl\nHA2TptrDOdVreHHcjXFdN0COPkK+rpWRZULakNDkpBAbze0YaEY8098jtXo1KmuLVPccLRHqMSkf\nDNxesmgmzzpHBcScjcM3gecx6+myKb+f4fkiXYefLN3AhLJ/h9w3SToKmYOEShJMczoGRiKe6e9m\njZbydRXDqj9mWa+hQWGK5jTNsnLdrziHhycKQwh9wMXzIDQb/+YP21xTtkK8ayGjEeFOMM0Rv0g0\nf/m2f5n4W1xWtpo1BYPC4vBA3DFes+seULO1KY5d66uljkToAyCeB6HxdRsvj090IjldEtNC60Zi\n3EkgnlV+0Uhk7DxZcXjDwRAhC10iYTXGbXXxjRV7E3nsZNoqtH5iiXGLcGcIiRSFSEnIowtNmo/Z\nAyL8vJoiXWH6gEvGgzCSfUYPsESuUhUEIyQ52QqJvSmVOfE0X4oHKwnZLN0QEHM2Frfm9HQxIriy\nJZxQu60mhpOVmBaEUES4M4hECZjVBlVmWPWAzR4Qqez9YaUnS7wdFlvqgSgIkpxsgzRnck8sC4zM\nEpbXlr0d8+CJaDZZTQhGXZyjta+Py1GsetLJSkwLQigS426FJCsmDLHHcZtji5Xvxhr7t7I4J/T7\niY6FC4IRkpxsw5gJ2bDqj9mU36/ZgtJSiU2rghzrg8RqwjTw+1ItIrQEsQi3hEpaGWbx2FUFwxLS\nPyVZC4xCsbrgKNaEYLSZkkbfb05oqblIXbhghAh3K8O0giHES4536K234ZMnaFsy4rhWBTnWB0mo\nCNu0cXfC0O/HOxS6OaRTwzIhvRDhbmXE4vnGWqZWsmgmawoGBT8EtA6bGh8rRl6lVUGOJyEYKMLX\nlr2dtgnFeNocCG0DEe5Whll/EiNiDW8YN3xSERs+RcPMqxxQs9WSoDY3jJHKMEg0pC5cMEOSk60Q\nK0vP40muNaftqxmRkotjd4QP9E0HQW0pZCVm20KqSlqITCr9SoStZkKSr6tw4YjrwdBSVSqZiFSz\ntC1EuFuAtvhLZXbN2ZU4V2AAAARTSURBVLi8syZDsOIZpoNXmc4P4HS2TUgsUg7YArTFxJFZPLiW\nfMP9rcRiU73aMN0rN1JRzSKkP9KrJE7aauLIqF/KspUr4u7RkcjmWfFgtQ+JIKQTItxxIg2FjtLc\nplWJ7v4XC231ASxkNhIqiZNUv+KnE+lcUheNlloJKgiJRDzuOEn1K366kUqvuTk0921BEFKBpaoS\npdQY4GHADjyutf5jpP3bQlWJ0HqQyg0hHUhoOaBSyg58CVwAfAOsBa7RWm8y+44ItyAIQmwkuhzw\nTOArrfU2rbULeB4Y1xwDBUEQhPixItzHAbsCfv7Gt00QBEFIAVaEWxlsC4uvKKUmK6XWKaXWlZeX\nN98yQRAEwRArwv0N0CPg5+OB3aE7aa0Xaq2HaK2HFBcXJ8o+QRAEIQQrwr0W6KeU6q2UcgBXA0uT\na5YgCIJgRtQ6bq21Wyl1E7AcbzngIq31xqRbJgiCIBhiaQGO1noZsCzJtgiCIAgWkCXvgiAIGUZS\n+nErpcqBHQk/cDhdgP0tcJ5MRO6NOXJvjJH7Yk5L3JteWmtLlR1JEe6WQim1zupKo7aG3Btz5N4Y\nI/fFnHS7NxIqEQRByDBEuAVBEDKMTBfuhak2II2Re2OO3Btj5L6Yk1b3JqNj3IIgCG2RTPe4BUEQ\n2hwZK9xKqTFKqS+UUl8ppe5OtT3pglKqh1LqHaXUZqXURqXUram2KZ1QStmVUh8rpd5ItS3phFKq\nk1LqJaXUFt+/nbNTbVM6oJS6zfd79LlS6jmlQiZLp4iMFG7fcIe/AhcBA4BrlFIDUmtV2uAGbtda\nnwycBfxS7k0QtwKbU21EGvIw8JbWuj9wGnKPUEodB9wCDNFan4K35cfVqbXKS0YKNzLcwRSt9R6t\n9Qbfn6vx/gJK/3RAKXU88CPg8VTbkk4opToA5wJ/A9Bau7TWB1NrVdqQBbRTSmUB7THojJoKMlW4\nZbiDBZRSTmAQsCa1lqQNDwF3Ap5UG5Jm9AHKgSd8YaTHlVJ5qTYq1WitvwVmAzuBPcAhrfXbqbXK\nS6YKt6XhDm0ZpVQ+8DLwK611VartSTVKqYuB77TW61NtSxqSBQwG5mmtBwG1QJvPGymlOuN9k+8N\ndAfylFLXpdYqL5kq3JaGO7RVlFLZeEX7Ga31K6m2J00YDlyqlCrDG1obqZT6e2pNShu+Ab7RWvvf\nzF7CK+RtndHAdq11uda6AXgF+H6KbQIyV7hluIMJSimFN1a5WWs9J9X2pAta6+la6+O11k68/15K\ntdZp4T2lGq31XmCXUuok36ZRwKYUmpQu7ATOUkq19/1ejSJNkraW+nGnGzLcISLDgYnAZ0qpT3zb\n7vH1VBcEM24GnvE5QtuAn6XYnpSjtV6jlHoJ2IC3Wutj0mQFpaycFARByDAyNVQiCILQZhHhFgRB\nyDBEuAVBEDIMEW5BEIQMQ4RbEAQhwxDhFgRByDBEuAVBEDIMEW5BEIQM4/8D0dwGCbkFdF8AAAAA\nSUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1c210630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.95399466  5.02557006]\n",
      " [ 3.04367119  1.01541041]\n",
      " [ 6.03366736  3.00052511]]\n"
     ]
    }
   ],
   "source": [
    "print (u'聚类过程展示...\\n')\n",
    "data = spio.loadmat(\"data.mat\")\n",
    "X = data['X']\n",
    "K = 3   # 总类数\n",
    "initial_centroids = np.array([[3,3],[6,2],[8,5]])   # 初始化类中心\n",
    "max_iters = 10\n",
    "runKMeans(X,initial_centroids,max_iters,True)       # 执行K-Means聚类算法"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}