export type Relation = T[]; export type RelationData = [T, Relation]; export declare class Relationship { /** Is this instance ignore strict references to variables? */ readonly useEqual: boolean; protected readonly __relations: Map>; /** * You can pass dataset parameter to init this instance. * The `RelationData` is type of 2-dimensional tuple array. Check `dataset` getter description. * @param dataset Initial dataset * @param useEqual If you want ignore strict references to variables, this helps you treat other objects as the same variable. * @example * const state = new Relationship([ ['a', ['b', 'c', 'd']] ]) * const clone = new Relationship(state.dataset) */ constructor(dataset?: RelationData[], useEqual?: boolean); private static __CreateMap; protected static FindIndex(useEqual: boolean, array: T[], node: T): number; /** * 배열이 노드를 가지고 있는지 여부를 반환합니다. * @param array 대상 배열입니다. * @param node 검색할 노드입니다. */ protected static Has(useEqual: boolean, array: T[], node: T): boolean; /** * 배열에 노드를 추가합니다. 배열이 이미 노드를 가지고 있다면 무시합니다. * @param array 대상 배열입니다. * @param nodes 추가할 노드입니다. */ protected static Add(useEqual: boolean, array: T[], ...nodes: T[]): T[]; /** * 배열에서 노드를 제거합니다. * @param array 대상 배열입니다. * @param node 제거할 노드입니다. */ protected static Drop(useEqual: boolean, array: T[], ...nodes: T[]): T[]; /** * 배열을 초기화합니다. * @param array 초기화할 배열입니다. */ protected static Clear(array: T[]): T[]; /** * Returns as 2-dimensional array of relationships between nodes in the instance. * Relationships are returned to saveable data-type(json). * @example * const saveData = JSON.stringify(state.dataset) * fs.writeFile('your-file.json', saveData) // in node.js * window.localStorage.set('your-file', saveData) // in browser */ get dataset(): RelationData[]; /** * Get all nodes from the instance. * This getter is include all nodes in the relationship. If you want to exclude the primary node, use the `children` getter. * @example * const state = new Relationship().to('a', 'b').to('b', 'c') * state.nodes // a, b, c * state.from('a').nodes // a, b, c * state.from('b').nodes // b, c */ get nodes(): T[]; /** * Get all children nodes without primary from the instance. * This getter is exclude primary nodes in the relationship. If you want to include all node, use the `nodes` getter. * @example * const state = new Relationship().to('a', 'b').to('b', 'c') * state.children // b, c. because the relationship state is [ ['a', ['b']], ['b', ['c']] ] * state.from('a').children // b, c. because the relationship state is [ ['a', ['b']], ['b', ['c']] ] * state.from('a', 1).children // b. because the relationship state is [ ['a', ['b']] ] * state.from('b').children // c. because the relationship state is [ ['b', ['c']] ] */ get children(): T[]; /** Get all nodes as Set object from the instance. */ get nodeset(): Set; /** * Get all nodes as one-hot vectors from the instance. It could be used as dataset for machine learning. * @example * const vectorA = state.oneHot.get('A') * const vectors = Array.from(state.oneHot.values()) */ get oneHot(): Map; /** * Get a 1-dimensional vector that was filled 0. The vector's size are same as nodes length of instance. This is useful for representing data that does not belong to anything. It could be used as dataset for machine learning. * @example * const voidVector = state.zeroVector * const vectors = Array.from(state.oneHot.values()) * const allVectors = [voidVector, ...vectors] */ get zeroVector(): number[]; /** * Get all nodes as labeled vector from the instance. It could be used as dataset for machine learning. * @example * const labelA = state.label.get('A') * const labels = Array.from(state.label.values()) */ get label(): Map; /** * Returns the clustering models of this instance in the form of a two-dimensional array. */ get clusters(): T[][]; /** * Returns the instance in which the relationship of the node is reversed. */ get reverse(): this; /** * Returns a new instance of this. * The clone instance are copy dataset from this, but It's not deep-copied object. */ get clone(): this; /** * 해당 노드와 관련있는 릴레이션을 반환합니다. 릴레이션이 없다면 생성하고 반환합니다. * @param source 해당 노드입니다. */ protected ensureRelation(source: T, ...targets: T[]): Relation; /** * Creates a new refer between nodes, and returns it as a Relationship instance. * This is one-sided relationship between both nodes. * @param source The source node. * @param targets The target nodes. * @example * // user-a -> user-b * // user-a -> user-c * state.to('user-a', 'user-b', 'user-c') */ to(source: T, ...targets: T[]): this; /** * Creates a new relationship between nodes, and returns it as a Relationship instance. * Both nodes will know each other. * @param a Node A to refer to node B. * @param b Node B to refer to node A. * @example * // user-a <-> user-b * // user-a <-> user-c * state.both('user-a', 'user-b', 'user-c') */ both(a: T, ...b: T[]): this; /** * Creates a new relationship between all each other nodes, and returns it as a Relationship instance. * All nodes will know each others. * @param nodes Nodes to relate to each other. * @example * // user-a <-> user-b * // user-b <-> user-c * // user-c <-> user-a * state.all('user-a', 'user-b', 'user-c') */ all(...nodes: T[]): this; /** * 두 개의 릴레이션데이터 배열을 병합합니다. * 이는 두 개의 인스턴스를 병합하는데 사용하기에 좋습니다. * @param a 병합할 릴레이션데이터 배열입니다. * @param b 병합할 릴레이션데이터 배열입니다. */ protected getCombinedDataset(a: RelationData[], b: RelationData[]): RelationData[]; /** * 인스턴스에 있는 관계를 계산합니다. 시작 노드에서 시작하여, 깊이만큼 탐색합니다. 탐색하여 관계를 새로운 릴레이션데이터 배열로 만들어 반환합니다. * @param source 시작 노드입니다. * @param depth 탐색할 횟수입니다. 재귀할 때 마다 이 횟수가 줄어들어, 0보다 작아지면 기본값을 반환합니다. * @param accDataset 탐색된 관계를 누산할 릴레이션데이터 배열입니다. * @param tests 탐색된 노드를 담고있는 배열입니다. 이미 한 번 탐색된 노드는 이 배열에 담깁니다. 상호참조하는 관계로 인해 무한히 탐색되는 것을 방지하는 용도로 사용됩니다. */ protected getSearchedRelationDataset(source: T, depth: number, accDataset?: RelationData[], tests?: T[]): RelationData[]; /** * 인스턴스에 있는 관계의 깊이를 계산합니다. 현재 노드에서 목표 노드까지의 가장 짧은 깊이를 반환해야 합니다. * 시작 노드는 재귀하여 호출될 때 마다 변경됩니다. * @param current 현재 노드입니다. * @param target 목표 노드입니다. * @param depth 재귀호출되며 누적된 깊이입니다. * @param tests 탐색된 노드를 담고있는 배열입니다. 이미 한 번 탐색된 노드는 이 배열에 담깁니다. 상호참조하는 관계로 인해 무한히 탐색되는 것을 방지하는 용도로 사용됩니다. */ protected getSearchedDepth(current: T, target: T, depth?: number, tests?: T[]): number; /** * Only the nodes that are related to the node received by the parameter are filtered and returned in a new Relationship instance. * You can control calculation depth relationship with depth parameter. * @param source The source node. * @param depth If depth parameter are negative, it's will be calculate all relationship between nodes in instance. Depth parameter default value is -1. * @returns new Relationship instance. * @example * const A = state.to('user-a', 'user-b').to('user-b', 'user-c') // user-a -> user-b -> user-c * A.from('user-a') // 'user-a', 'user-b', 'user-c' * A.from('user-a', 1) // 'user-a', 'user-b' */ from(source: T, depth?: number): this; /** * Returns a new relationship instance with only nodes that meet the conditions or the relational node. * This is similar to the `from` method, but it is useful when you want to use more detailed conditions. * You can control calculation depth relationship with depth parameter. * @param filter condition filter callback function * @param depth If depth parameter are negative, it's will be calculate all relationship between nodes in instance. Depth parameter default value is -1. * @returns new Relationship instance. * @example * // user-a -> user-b * // user-c -> user-d * const A = state.to('user-a', 'user-b').to('user-c', 'user-d') * A.where((node) => node.includes('a')) // user-a, user-b */ where(filter: (node: T, i: number, array: T[]) => boolean, depth?: number): this; /** * Returns the remaining nodes except those received as parameters from the current relationship instance. * @param nodes This is a list of nodes to exclude. * @example * const A = state.all('user-a', 'user-b', 'user-c') * const B = A.from('user-a') * B.nodes // user-a, user-b, user-c * B.without('user-a') // user-b, user-c */ without(...nodes: T[]): T[]; /** * 해당 노드에서 참조하는 노드들 중에서 대상 노드를 제거합니다. * @param source 해당 노드입니다. * @param targets 대상 노드입니다. */ protected unlinkRefersFromSource(source: T, ...targets: T[]): void; /** * Deletes the relationship between nodes and returns it as a Relationship instance. * This is one-sided cut off between both nodes. * Check the `to` method. * @param source The source node. * @param targets The target nodes. * @example */ unlinkTo(source: T, ...targets: T[]): this; /** * Deletes the relationship between nodes and returns it as a Relationship instance. * Both nodes will cut off each other. * Check the `both` method. * @param a Node A to unlink from node B. * @param b Node B to unlink from node A. */ unlinkBoth(a: T, ...b: T[]): this; /** * Delete the node. If the node associated with the deleted node is isolated, it is deleted together. * Returns the result with a Relationship instance. * @param nodes Nodes to be deleted. * @example * // user-a -> user-b * // user-a -> user-c * const A = state.to('user-a', 'user-b').to('user-a', 'user-c') * const B = A.drop('user-a') * B.nodes // empty */ drop(...nodes: T[]): this; /** * Returns whether the instance contains that node. * @param node Node to find. * @example * const A = state.to('user-a', 'user-b') * state.has('user-a') // true */ has(node: T): boolean; /** * Returns whether the instance contains all of its nodes. * @param nodes A list of nodes to search for. * @example * const A = state.to('user-a', 'user-b', 'user-c') * state.hasAll('user-a', 'user-f') // false */ hasAll(...nodes: T[]): boolean; /** * Returns how many nodes are related to the node received by the parameter. * @param node Node to find. * @param log If this parameter is set to true, it returns the value to which the log function is applied. This is useful when the value is too high. * @example * const A = state.to('user-a', 'user-c').both('user-b', 'user-c') * A.weight('user-c') // 2 * A.weight('user-a') // 0 * A.weight('user-b') // 1 */ weight(node: T, log?: boolean): number; /** * Returns the weight of all nodes. Check the `weight` method. * @param log If this parameter is set to true, it returns the value to which the log function is applied. This is useful when the value is too high. * @param normalize Normalize the weight value. Convert all values to values from 0 to 1. * @param toScale Change all weights sum as values to 1 when `normalize` parameter is `true` */ weights(log?: boolean, normalize?: boolean, toScale?: boolean): Map; /** * Returns how many nodes are related to the node received by the parameter. * @param node Node to find. * @param log If this parameter is set to true, it returns the value to which the log function is applied. This is useful when the value is too high. * @example * const A = state.to('a', 'b', 'c', 'd') * A.entry('a') // 3 * A.entry('b') // 0 */ entry(node: T, log?: boolean): number; /** * Returns the entry value of all nodes. Check the `entry` method. * @param log If this parameter is set to true, it returns the value to which the log function is applied. This is useful when the value is too high. * @param normalize Normalize the entry value. Convert all values to values from 0 to 1. * @param toScale Change all entries sum as values to 1 when `normalize` parameter is `true` */ entries(log?: boolean, normalize?: boolean, toScale?: boolean): Map; /** * Returns the found minimum depth to between source to target. * If cannot find the way on source to target, Returns `Infinity` * @param source Node to start * @param target Node to target * @param log If this parameter is set to true, it returns the value to which the log function is applied. This is useful when the value is too high. * @example * const A = state.to('user-a', 'user-b').to('user-b', 'user-c') * A.depth('user-a', 'user-b') // 1 * A.depth('user-a', 'user-c') // 2 * A.depth('user-c', 'user-a') // Infinity */ depth(source: T, target: T, log?: boolean): number; /** * Returns the found minimum distance to between a to b. * If cannot find the way on both node, Returns `Infinity` * This is same as `Math.min(this.depth(a, b), this.depth(b, a))` * @param a Node to find a. * @param b Node to find b. * @param log If this parameter is set to true, it returns the value to which the log function is applied. This is useful when the value is too high. * @example * const A = state.to('user-a', 'user-b').to('user-b', 'user-c') * A.distance('user-a', 'user-b') // 1 * A.distance('user-a', 'user-c') // 2 * A.distance('user-c', 'user-a') // 2 */ distance(a: T, b: T, log?: boolean): number; /** * Merge a relation dataset with this instance. * If there is a non-overlapping dataset, It will be append to instance. * @param datasets Data set to be merged * @example * const A = state.to('user-a', 'user-b') * const B = state.to('user-a', 'user-c') * const C = A.merge(B.dataset).nodes // user-a, user-b, user-c */ merge(...datasets: RelationData[][]): this; /** * This method for instance that `useEqual` options. It returns a original value from `node` parameter. * It will be useful when using between returned Map from `nodeset`, `oneHot`, `label` getters and `weights` method. * @param node Node to find. * @example * const useEqual = true * const state = new Relationship(undefined, useEqual).to({ name: 'a' }, { name: 'b' }) * const weights = state.weights() * * weights.get({ name: 'b' }) // undefined. because 'weights' map instance doesn't using equal system. * * const raw = state.raw({ name: 'b' }) * weights.get(raw) // 1 */ raw(node: T): T | undefined; /** Destroy the data in the instance. It is used for garbage collector. */ clear(): void; }