Advertisement
user1man

kmeans 3

Nov 8th, 2022 (edited)
1,411
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- main call
  2. CALL init_temp_tables();
  3. CALL add_centroids(3);
  4. CALL clear_tables();
  5. SELECT *
  6. FROM centroids_now;
  7.  
  8.  
  9. DROP TABLE centroids_old;
  10.  
  11. -- создать процедуру с входным параметром
  12. -- и в ней выполнить все действия
  13. CREATE OR REPLACE PROCEDURE add_centroids(k int)
  14.     LANGUAGE SQL
  15. AS
  16. $$
  17. -- CALL create_temp_table_centroids_now();
  18. DELETE
  19. FROM centroids_now;
  20. INSERT INTO centroids_now (latitude, longitude)
  21. SELECT latitude, longitude
  22. FROM cams AS m
  23. ORDER BY RANDOM()
  24. LIMIT k;
  25. $$;
  26.  
  27. CALL init_temp_tables();
  28. -- не работает
  29. CREATE OR REPLACE PROCEDURE init_temp_tables()
  30.     LANGUAGE SQL
  31. AS
  32. $$
  33.     CREATE TABLE centroids_now
  34.     (
  35.         id        serial PRIMARY KEY,
  36.         latitude  numeric(10, 8),
  37.         longitude numeric(10, 8)
  38.     );
  39.     CREATE TABLE centroids_old
  40.     (
  41.         id        serial PRIMARY KEY,
  42.         latitude  numeric(10, 8),
  43.         longitude numeric(10, 8)
  44.     );
  45.     CREATE TABLE zones
  46.     (
  47.         id_c int,
  48.         id_p int,
  49.         dist numeric(10, 8)
  50.     );
  51.  
  52.     $$;
  53.  
  54. CREATE OR REPLACE PROCEDURE clear_tables()
  55.     LANGUAGE SQL
  56. AS
  57. $$
  58. DELETE
  59. FROM centroids_now;
  60. DELETE
  61. FROM centroids_old;
  62. DELETE
  63. FROM zones;
  64. $$;
  65.  
  66. -- CREATE OR REPLACE PROCEDURE clear_centroids()
  67. --     LANGUAGE SQL
  68. -- AS
  69. -- $$
  70. -- DROP TABLE centroids_now;
  71. -- $$;
  72.  
  73.  
  74. CREATE TABLE temp AS
  75. SELECT c2.id                                                         AS id_c,
  76.        c.id                                                          AS id_p,
  77.        countDist(c.latitude, c.longitude, c2.latitude, c2.longitude) AS dist
  78. FROM cams c
  79.          CROSS JOIN centroids_now c2;
  80.  
  81. CALL countNewTemp();
  82. CREATE OR REPLACE PROCEDURE countNewTemp()
  83.     LANGUAGE SQL
  84. AS
  85. $$
  86. DELETE
  87. FROM temp t;
  88.  
  89. INSERT INTO temp
  90. SELECT c2.id                                                         AS id_c,
  91.        c.id                                                          AS id_p,
  92.        countDist(c.latitude, c.longitude, c2.latitude, c2.longitude) AS dist
  93. FROM cams c
  94.          CROSS JOIN centroids_now c2;
  95. $$;
  96.  
  97.  
  98.  
  99. DROP TABLE temp;
  100.  
  101. DELETE
  102. FROM temp;
  103.  
  104. SELECT *
  105. FROM temp t;
  106.  
  107. CREATE OR REPLACE FUNCTION countDist(
  108.     latitude1 decimal,
  109.     longitude1 decimal,
  110.     latitude2 decimal,
  111.     longitude2 decimal)
  112.     RETURNS numeric(10, 8)
  113. AS
  114. $$
  115. BEGIN
  116.     RETURN 6371 *
  117.            ACOS(COS(RADIANS(latitude1)) * COS(RADIANS(latitude2)) * COS(RADIANS(longitude2) - RADIANS(longitude1)) +
  118.                 SIN(RADIANS(latitude1)) * SIN(RADIANS(latitude2)));
  119. END;
  120. $$ LANGUAGE plpgsql;
  121.  
  122. -- select from temp table
  123. SELECT c2.id                                                         AS id_c,
  124.        c.id                                                          AS id_p,
  125.        countDist(c.latitude, c.longitude, c2.latitude, c2.longitude) AS dist
  126. FROM cams c
  127.          CROSS JOIN centroids c2
  128. ;
  129.  
  130. -- CREATE TEMPORARY TABLE kmins AS
  131. -- SELECT id_c, id_p, MIN(dist) AS countdist
  132. -- FROM temp t
  133. -- GROUP BY id_c, id_p;
  134. --
  135. --
  136. -- SELECT *
  137. -- FROM kmins
  138. -- ORDER BY id_p;
  139. --
  140. -- DROP TABLE kmins;
  141.  
  142. -- распределение по кучкам
  143. CREATE OR REPLACE PROCEDURE countZones()
  144.     LANGUAGE SQL
  145. AS
  146. $$
  147. DELETE
  148. FROM zones z;
  149. INSERT INTO zones
  150. SELECT *
  151. FROM temp t
  152. WHERE t.id_p = (SELECT t2.id_p
  153.                 FROM temp t2
  154.                 WHERE t2.id_p = t.id_p
  155.                 ORDER BY t2.dist
  156.                 LIMIT 1)
  157.   AND t.id_c = (SELECT t2.id_c
  158.                 FROM temp t2
  159.                 WHERE t2.id_p = t.id_p
  160.                 ORDER BY t2.dist
  161.                 LIMIT 1);
  162. $$;
  163.  
  164. DELETE
  165. FROM zones;
  166.  
  167. CREATE OR REPLACE PROCEDURE countZones2()
  168.     LANGUAGE SQL
  169. AS
  170. $$
  171. DELETE
  172. FROM zones z;
  173. --     посчитать новые temp
  174. CALL countNewTemp();
  175. INSERT INTO zones
  176. SELECT *
  177. FROM temp
  178. WHERE temp.dist IN (SELECT MIN(dist) FROM temp AS dist2 WHERE temp.id_p = dist2.id_p)
  179. $$;
  180.  
  181. CREATE OR REPLACE PROCEDURE countZones3()
  182.     LANGUAGE SQL
  183. AS
  184. $$
  185. DELETE
  186. FROM zones z;
  187. --     посчитать новые temp
  188. CALL countNewTemp();
  189.  
  190. INSERT INTO zones
  191. SELECT *
  192. FROM temp t
  193. WHERE (t.id_c, t.id_p) IN (SELECT t2.id_c, t2.id_p
  194.                            FROM temp t2
  195.                            WHERE t2.id_p = t.id_p
  196.                            ORDER BY t2.dist
  197.                            LIMIT 1)
  198. $$;
  199.  
  200.  
  201. SELECT *
  202. FROM temp t;
  203.  
  204.  
  205. SELECT *
  206. FROM zones z;
  207. -- проверка на то, что с id 2 существует
  208.  
  209.  
  210. CREATE OR REPLACE PROCEDURE getNewCenters()
  211.     LANGUAGE SQL
  212. AS
  213. $$
  214. DELETE
  215. FROM centroids_old;
  216. INSERT INTO centroids_old
  217. SELECT *
  218. FROM centroids_now;
  219. DELETE
  220. FROM centroids_now;
  221. INSERT INTO centroids_now
  222. SELECT z.id_c, ROUND(AVG(c.latitude), 3), ROUND(AVG(c.longitude), 3)
  223. FROM zones AS z
  224.          JOIN cams AS c ON c.id = z.id_p
  225. GROUP BY id_c
  226. ORDER BY id_c;
  227. CALL countZones3();
  228. $$;
  229.  
  230. CREATE OR REPLACE PROCEDURE getNewCentersRec()
  231.     LANGUAGE plpgsql
  232. AS
  233. $$
  234. BEGIN
  235.     WHILE (SELECT COUNT(*) FROM (SELECT * FROM centroids_now EXCEPT SELECT * FROM centroids_old) AS abc) > 0
  236.         LOOP
  237.             CALL getNewCenters();
  238.         END LOOP;
  239. END;
  240. $$;
  241.  
  242. CALL countZones3();
  243. CALL getNewCentersRec();
  244. SELECT *
  245. FROM zones;
  246. SELECT *
  247. FROM centroids_old;
  248. SELECT *
  249. FROM temp;
  250.  
  251.  
  252. SELECT id_c, latitude, longitude
  253. FROM zones AS z
  254.          JOIN cams AS c ON c.id = z.id_p;
Tags: psql
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement