#!/usr/bin/python
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from math import sqrt
import matplotlib.pyplot as plt
'''1.對每乙個存在勿連約束的樣本,檢查他的所有勿連約束樣本,如果已經分類,則正常進行勿連約束判斷分類。
如果未分類,則將所有勿連樣本拿出來與當前各分類中心進行距離計算,找出乙個的分類,使得當前樣本與該類
的中心的距離小於所有勿連樣本與它的距離。如果有多個這樣的分類,選擇中心距離當前樣本最近的乙個。
2. 如果不存在這樣的分類,也正常進行勿連約束判斷分類。
'''#計算兩個向量之間的歐式距離
def norm(vec1, vec2):
dist = np.linalg.norm(vec1 - vec2)
return dist
#對乙個列表進行排列,預設返回從小到大的排序,並返回對應的索引
def sort(vec):
clss = {}
for i in range(len(vec)):
clss[vec[i]] = i
vec_sort = sorted(vec)
index =
for i in range(len(vec)):
return vec_sort, index
df = pd.read_csv('watermelon_9_1.csv')
data = df.values[:, 1:]
m, n = data.shape
k = 3
#初始化中心點
centroids = np.vstack((data[6 - 1,:],data[12 - 1,:],data[27 - 1,:]))
c1 = {}
#必連標記,如果樣本沒有約束,則為0;如果有,則為必連集合編號
flag_c = np.zeros(m,dtype=int)
c1[0] = [4 - 1, 25 - 1]
c1[1] = [12 - 1, 20 - 1]
c1[2] = [14 - 1 , 17 - 1]
for i in range(k):
flag_c[c1[i][0]] = i
flag_c[c1[i][1]] = i
#勿連標記,記錄樣本是否有勿連標記,如果沒有則為0;如果有,則為勿連序列對應的起始序列號
flag_m = np.zeros(m,dtype=int)
m1 = np.array([[2,13,19,21,23,23],[21,23,23,2,13,19]])
m1 -= 1
for i in range(6):
if flag_m[m1[0,i]] == 0:
flag_m[m1[0,i]] = i
while true:
#總的標記類別
flag_p = np.zeros(m,dtype=int)
for i in range(m):
#如果已經標記了類別,就跳過
if flag_p[i] > 0:
continue
#如果存在必連標記,則該點取必連兩點的中間值,使得兩點能落在同一類中
if flag_c[i] > 0:
tx = (data[c1[flag_c[i]][0],:] + data[c1[flag_c[i]][0],:]) / 2
else:
tx = data[i,:]
#計算一點到三個中心點的距離
dist = np.zeros(k)
for j in range(k):
dist[j] = norm(tx, centroids[j,:])
dist_sort, index = sort(dist)
#根據勿連標記對該點進行分類
for j in range(k):
tj = index[j] #tj為該類的索引
ptr = flag_m[i] #ptr為是否為勿連標記,如果不是則為0,如果是則為勿連下標值
mf = 0 #錯誤標記,0為正確,1為錯誤
#如果該點是勿連約束
while ptr >0 and ptr < 7 and m1[1, ptr] == i:
#如果它的勿連點的類跟自己的類是同乙個類,則標記錯誤
if flag_p[m1[2,ptr]] == tj:
mf = 1
break
#如果它勿連的模擬自己到中心點的距離還近,則為錯誤
ti = m1[2,ptr]
tdist = norm(data[ti,:], centroids[tj,:])
if tdist < dist_sort[j]:
mf = 1
break
# ptr += 1
#如果該類報錯,則跳轉嘗試下乙個類別
if mf == 1:
continue
#最終出來的值要麼是正確的值,即tj代表該點的分類,要麼是仍然有錯的勿連標記
break
#如果對於該勿連點三個類都存在錯誤資訊,那麼只進行常規的判斷,只需要在不同類即可,不再考慮距離
if mf == 1 and j==k:
for j in range(k):
tj = index[j]
ptr = flag_m[i]
mf = 0
while ptr >0 and ptr < 7 and m1[1,ptr] == i:
if flag_p[m1[2,ptr]] == tj:
mf = 1
break
# ptr += 1
if mf == 1:
continue
break
#最後對該點所屬類進行劃分,根據上面的tj值
if flag_c[i] > 0:
flag_p[c1[flag_c[i]][0]] = tj
flag_p[c1[flag_c[i]][1]] = tj
else:
flag_p[i] = tj
#進行最後的統計,所有點劃分後,更新中心點的位置,比較前後中心點的差異
第十三章 併發
13.1 動機 13.2 基本執行緒 如果必須要控制現成的執行順序,最好是根本不用執行緒,而是自己編寫特定順序彼此控制的協作子程式。繼承thread類或者實現runnable介面。內部類實現。13.3 共享受限資源 1 如果要對類中的某個方法進行同步控制,最好同步所有方法。如果忽略了其中乙個,通常很...
第十三章 類
1.類簡單地說是乙個性的資料型別。類當中有資料成員,和成員函式。類的基本思想就是體現出資料的抽象和封裝。2.這裡只需要說明乙個問題即可 就是類成員函式的const型別 class screen public const int get const int i const int j const 這裡...
第十三章 事件
1 事件的作用 事件是對委託的封裝,如同屬性對字段的封裝。封裝後可以在委託上實現更複雜的邏輯。1.1 封裝訂閱 委託允許使用 對其進行賦值,但向乙個委託例項賦值多個委託時,使用 會造成覆蓋之前的委託。事件只支援 或 對事件進行賦值 1.2 封裝發布 委託可以在其他類進行訪問,而事件可以確保只有包容類...