def generateCelfHeap(self): # -- calculate expected profit for all combinations of nodes and products -- ### celf_item: (list) (mg, k_prod, i_node, flag) celf_heap = [(0.0, -1, '-1', 0)] diffpw_ss = DiffusionPW(self.graph_dict, self.seed_cost_dict, self.product_list, self.pw_list, self.monte) for i in set(self.graph_dict.keys()): s_set = [set() for _ in range(self.num_product)] s_set[0].add(i) ep = 0.0 for _ in range(self.monte): ep += diffpw_ss.getSeedSetProfit(s_set) ep = round(ep / self.monte, 4) if ep > 0: for k in range(self.num_product): mg = round( ep * self.product_list[k][0] * self.pw_list[k] / (self.product_list[0][0] * self.pw_list[0]), 4) celf_item = (mg, k, i, 0) heap.heappush_max(celf_heap, celf_item) return celf_heap
def generateSeedExpectedInfDictUsingDAG2(self, k_prod, s_set, mioa_dict): node_rank_dict = {i: 0.0 for i in self.seed_cost_dict[0]} for s_node in s_set[k_prod]: node_rank_dict[s_node] = 1.0 for i in mioa_dict[s_node]: if mioa_dict[s_node][i] > node_rank_dict[i]: node_rank_dict[i] = mioa_dict[s_node][i] s_total_set = set(s for k in range(self.num_product) for s in s_set[k]) seed_exp_inf_dict = {} for s_node in s_set[k_prod]: mioa_set = set() s_node_dict = {s_node: (1.0, s_node)} source_heap = [] for i in self.graph_dict[s_node]: s_node_dict[i] = (self.graph_dict[s_node][i], s_node) heap.heappush_max(source_heap, (self.graph_dict[s_node][i], i)) # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) i_prev = s_node_dict[i_node][1] if i_node in s_total_set: continue if node_rank_dict[i_prev] <= node_rank_dict[i_node]: continue mioa_set.add(i_node) if i_node in seed_exp_inf_dict: seed_exp_inf_dict[i_node].append(i_prob) else: seed_exp_inf_dict[i_node] = [i_prob] if i_node in self.graph_dict: for ii_node in self.graph_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in mioa_set: ii_prob = round( i_prob * self.graph_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in s_node_dict: ii_prob_d = s_node_dict[ii_node][0] if ii_prob > ii_prob_d: s_node_dict[ii_node] = (ii_prob, i_node) source_heap.remove( (ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: s_node_dict[ii_node] = (ii_prob, i_node) heap.heappush_max(source_heap, (ii_prob, ii_node)) return seed_exp_inf_dict
def generateCelfHeap(self, data_name): # -- calculate expected profit for all combinations of nodes and products -- ### celf_item: (list) (mg, k_prod, i_node, flag) Billboard_set, Handbill_set = SpiltHeuristicsSet(data_name) Billboard_celf_heap, Handbill_celf_heap = [], [] diff = Diffusion(self.graph_dict, self.product_list, self.product_weight_list) for i in Billboard_set: s_set = [set() for _ in range(self.num_product)] s_set[0].add(i) ep = diff.getSeedSetProfitBCS(s_set) if ep > 0: for k in range(self.num_product): mg = safe_div(ep * self.product_list[k][0] * self.product_weight_list[k], self.product_list[0][0] * self.product_weight_list[0]) celf_item = (mg, k, i, 0) heap.heappush_max(Billboard_celf_heap, celf_item) for i in Handbill_set: s_set = [set() for _ in range(self.num_product)] s_set[0].add(i) ep = diff.getSeedSetProfitBCS(s_set) if ep > 0: for k in range(self.num_product): mg = safe_div(ep * self.product_list[k][0], self.product_list[0][0] * self.product_weight_list[0]) mg = safe_div(mg, self.seed_cost_dict[k][i]) celf_item = (mg, k, i, 0) heap.heappush_max(Handbill_celf_heap, celf_item) return Billboard_celf_heap, Handbill_celf_heap
def generateCelfHeapR(self): # -- calculate expected profit for all combinations of nodes and products -- ### celf_item: (list) (mg_ratio, k_prod, i_node, flag) i_anc_dict = {} celf_heap = [(0.0, -1, '-1', 0)] mep = (0.0, {}) diffap_ss = DiffusionAccProb(self.graph_dict, self.seed_cost_dict, self.product_list) for i in self.graph_dict: i_dict = diffap_ss.buildNodeDict({i}, i, 1, set()) i_anc_dict[i] = i_dict ei = getExpectedInf(i_dict) if ei > 0: for k in range(self.num_product): if self.seed_cost_dict[i] == 0: break else: mg_ratio = round(ei * self.product_list[k][0] / self.seed_cost_dict[i], 4) if mg_ratio > mep[0]: mep = (mg_ratio, i_dict) celf_item = (mg_ratio, k, i, 0) heap.heappush_max(celf_heap, celf_item) return celf_heap, i_anc_dict, mep
def generateMIA(self, s_set): ### mioa_dict[i_node_u][i_node_v] = (prob, path): MIP from i_node_u to i_node_v ### miia_dict[i_node_v][i_node_u] = (prob, path): MIP from i_node_u to i_node_v mioa_dict, miia_dict = {}, {} sub_graph = copy.deepcopy(self.graph_dict) s_total_set = set(s for k in range(self.num_product) for s in s_set[k]) for s_node in s_total_set: induceGraph(sub_graph, s_node) for source_node in sub_graph: ### source_dict[i_node] = (prob, in-neighbor) mioa_dict[source_node] = {} source_dict = {source_node: (1.0, source_node)} source_heap = [] for i in sub_graph[source_node]: source_dict[i] = (sub_graph[source_node][i], source_node) heap.heappush_max(source_heap, (sub_graph[source_node][i], i)) # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) i_prev = source_dict[i_node][1] # -- find MIP from source_node to i_node -- i_path = [i_node, i_prev] while i_prev != source_dict[i_prev][1]: i_prev = source_dict[i_prev][1] i_path.append(i_prev) i_path.reverse() mioa_dict[source_node][i_node] = (i_prob, i_path) if i_node not in miia_dict: miia_dict[i_node] = {source_node: (i_prob, i_path)} else: miia_dict[i_node][source_node] = (i_prob, i_path) if i_node in sub_graph: for ii_node in sub_graph[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in mioa_dict[source_node]: ii_prob = round(i_prob * sub_graph[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_dict: ii_prob_d = source_dict[ii_node][0] if ii_prob > ii_prob_d: source_dict[ii_node] = (ii_prob, i_node) source_heap.remove((ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: source_dict[ii_node] = (ii_prob, i_node) heap.heappush_max(source_heap, (ii_prob, ii_node)) return mioa_dict, miia_dict
def generateMIOA(self): mioa_dict = {} for source_node in self.graph_dict: ### source_dict[i_node] = (prob, in-neighbor) mioa_dict[source_node] = {} source_dict = { i: (self.graph_dict[source_node][i], source_node) for i in self.graph_dict[source_node] } source_dict[source_node] = (1.0, source_node) source_heap = [(self.graph_dict[source_node][i], i) for i in self.graph_dict[source_node]] heap.heapify_max(source_heap) # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) i_prev = source_dict[i_node][1] # -- find MIP from source_node to i_node -- i_path = [i_node, i_prev] while i_prev != source_node: i_prev = source_dict[i_prev][1] i_path.append(i_prev) i_path.pop() i_path.reverse() mioa_dict[source_node][i_node] = (i_prob, i_path) if i_node in self.graph_dict: for ii_node in self.graph_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in mioa_dict[source_node]: ii_prob = round( i_prob * self.graph_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_dict: ii_prob_d = source_dict[ii_node][0] if ii_prob > ii_prob_d: source_dict[ii_node] = (ii_prob, i_node) source_heap.remove( (ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: source_dict[ii_node] = (ii_prob, i_node) heap.heappush_max(source_heap, (ii_prob, ii_node)) return mioa_dict
def generateDegreeHeap(self): degree_heap = [] for i in self.graph_dict: deg = len(self.graph_dict[i]) for k in range(self.num_product): degree_item = (int(deg), k, i) heap.heappush_max(degree_heap, degree_item) return degree_heap
def generateSeedDAGDict(self, dag_dict, s_set_k): sdag_dict = {} s_set = set(s for s in s_set_k if s in dag_dict) for s_node in s_set: sdag_dict[s_node] = {} source_dict = { i: (dag_dict[s_node][i], s_node) for i in dag_dict[s_node] } source_dict[s_node] = (1.0, s_node) source_heap = [(dag_dict[s_node][i], i) for i in dag_dict[s_node]] heap.heapify_max(source_heap) # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) i_prev = source_dict[i_node][1] # -- find MIP from source_node to i_node -- i_path = [i_node, i_prev] while i_prev != s_node: i_prev = source_dict[i_prev][1] i_path.append(i_prev) i_path.pop() i_path.reverse() sdag_dict[s_node][i_node] = (i_prob, i_path) if i_node in dag_dict: for ii_node in dag_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in sdag_dict[s_node]: ii_prob = round(i_prob * dag_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_dict: ii_prob_d = source_dict[ii_node][0] if ii_prob > ii_prob_d: source_dict[ii_node] = (ii_prob, i_node) source_heap.remove( (ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: source_dict[ii_node] = (ii_prob, i_node) heap.heappush_max(source_heap, (ii_prob, ii_node)) return sdag_dict
def generateDegreeHeap(self): degree_heap = [(-1, -1, '-1')] with open(self.data_degree_path) as f: for line in f: (i, deg) = line.split() if deg == '0': continue for k in range(self.num_product): degree_item = (int(deg), k, i) heap.heappush_max(degree_heap, degree_item) f.close() return degree_heap
def generateCelfHeap(self): # -- calculate expected profit for all combinations of nodes and products -- ### celf_item: (list) (mg, k_prod, i_node, flag) degree_dict = {} for i in self.graph_dict: deg = len(self.graph_dict[i]) if int(deg) in degree_dict: degree_dict[int(deg)].add(i) else: degree_dict[int(deg)] = {i} num_node20 = round( sum(deg * len(degree_dict[deg]) for deg in degree_dict) * 0.2, 4) degree_count_dict = { deg: round( abs( sum([len(degree_dict[d]) for d in degree_dict if d >= deg]) - num_node20), 4) for deg in degree_dict } degree_threshold20 = min(degree_count_dict, key=degree_count_dict.get) Billboard_set, Handbill_set = set(), set() for deg in degree_dict: if deg >= degree_threshold20: Billboard_set = Billboard_set.union(degree_dict[deg]) else: Handbill_set = Handbill_set.union(degree_dict[deg]) Billboard_celf_heap, Handbill_celf_heap = [], [] ss = SeedSelectionBCS(self.graph_dict, self.seed_cost_dict, self.product_list, self.product_weight_list, self.epw_flag) for k in range(self.num_product): for i in self.graph_dict: s_set = [set() for _ in range(self.num_product)] s_set[k].add(i) ep = ss.getSeedSetProfit(s_set) if ep > 0: if i in Billboard_set: celf_item = (ep, k, i, 0) heap.heappush_max(Billboard_celf_heap, celf_item) elif i in Handbill_set: ep = safe_div(ep, self.seed_cost_dict[i]) celf_item = (ep, k, i, 0) heap.heappush_max(Handbill_celf_heap, celf_item) return [Billboard_celf_heap, Handbill_celf_heap]
def generateCelfHeap(self): # -- calculate expected profit for all combinations of nodes and products -- ### celf_item: (list) (mg, k_prod, i_node, flag) celf_heap = [(0.0, -1, '-1', 0)] diffap_ss = DiffusionAccProb(self.graph_dict, self.product_list) for i in self.graph_dict: i_dict = diffap_ss.buildNodeExpectedInfDict({i}, i, 1) ei = getExpectedInf(i_dict) if ei > 0: for k in range(self.num_product): mg = round(ei * self.product_list[k][0], 4) celf_item = (mg, k, i, 0) heap.heappush_max(celf_heap, celf_item) return celf_heap
def generateDAG1(self, s_set_k): node_rank_dict = {} source_dict = {s_node: 1.0 for s_node in s_set_k} source_heap = [(1.0, s_node) for s_node in s_set_k] # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) node_rank_dict[i_node] = i_prob if i_node in self.graph_dict: for ii_node in self.graph_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in node_rank_dict: ii_prob = round( i_prob * self.graph_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_dict: ii_prob_d = source_dict[ii_node] if ii_prob > ii_prob_d: source_dict[ii_node] = ii_prob source_heap.remove((ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: source_dict[ii_node] = ii_prob heap.heappush_max(source_heap, (ii_prob, ii_node)) dag_dict = {i: {} for i in self.graph_dict} i_set = set(i for i in self.graph_dict if i in node_rank_dict) for i in i_set: j_set = set(j for j in self.graph_dict[i] if j in node_rank_dict and node_rank_dict[i] > node_rank_dict[j]) for j in j_set: dag_dict[i][j] = self.graph_dict[i][j] if not dag_dict[i]: del dag_dict[i] return dag_dict
def generateCelfHeap(self): # -- calculate expected profit for all combinations of nodes and products -- ### celf_item: (list) (mg, k_prod, i_node, flag) celf_heap = [] ss = SeedSelectionNG(self.graph_dict, self.seed_cost_dict, self.product_list, self.epw_list, True) for i in self.graph_dict: s_set = [set() for _ in range(self.num_product)] s_set[0].add(i) ep = ss.getSeedSetProfit(s_set) if ep > 0: ep = safe_div(ep, self.seed_cost_dict[i]) celf_item = (ep, 0, i, 0) heap.heappush_max(celf_heap, celf_item) return celf_heap
def generateCelfHeap(self): # -- calculate expected profit for all combinations of nodes and products -- ### celf_item: (list) (mg, k_prod, i_node, flag) celf_heap = [[] for _ in range(self.num_product)] diff_ss = Diffusion(self.graph_dict, self.product_list, self.product_weight_list) for i in self.graph_dict: s_set = [set() for _ in range(self.num_product)] s_set[0].add(i) ep = round(sum([diff_ss.getSeedSetProfit(s_set) for _ in range(self.monte)]) / self.monte, 4) if ep > 0: for k in range(self.num_product): mg = safe_div(ep * self.product_list[k][0], self.product_list[0][0]) celf_item = (mg, k, i, 0) heap.heappush_max(celf_heap[k], celf_item) return celf_heap
def generateMIA(self): mioa_dict, miia_dict = {}, {} for source_node in self.graph_dict: ### source_dict[i_node] = (prob, in-neighbor) mioa_dict[source_node] = {} source_dict = {source_node: 1.0} source_heap = [] for i in self.graph_dict[source_node]: source_dict[i] = self.graph_dict[source_node][i] heap.heappush_max(source_heap, (self.graph_dict[source_node][i], i)) # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) mioa_dict[source_node][i_node] = i_prob if i_node not in miia_dict: miia_dict[i_node] = {source_node} else: miia_dict[i_node].add(source_node) if i_node in self.graph_dict: for ii_node in self.graph_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in mioa_dict[source_node]: ii_prob = round(i_prob * self.graph_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_dict: ii_prob_d = source_dict[ii_node][0] if ii_prob > ii_prob_d: source_dict[ii_node] = ii_prob source_heap.remove((ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: source_dict[ii_node] = ii_prob heap.heappush_max(source_heap, (ii_prob, ii_node)) return mioa_dict, miia_dict
def generateExpandDegreeHeap(self): degree_dict = {} with open(self.data_degree_path) as f: for line in f: (i, deg) = line.split() degree_dict[i] = int(deg) f.close() degree_expand_heap = [(0, -1, '-1')] for i in self.graph_dict: deg = degree_dict[i] for ii in self.graph_dict[i]: deg += degree_dict[ii] for k in range(self.num_product): degree_item = (deg * self.product_weight_list[k], k, i) heap.heappush_max(degree_expand_heap, degree_item) return degree_expand_heap
def generateCelfHeap(self, mioa_dict): celf_heap = [] ss = SeedSelectionMIOA(self.graph_dict, self.seed_cost_dict, self.product_list, self.epw_list, self.dag_class, self.r_flag) for k in range(self.num_product): for i in self.graph_dict: s_set = [set() for _ in range(self.num_product)] s_set[k].add(i) dag_dict = [{} for _ in range(self.num_product)] if self.dag_class == 1: dag_dict = ss.generateDAG1(mioa_dict, s_set) elif self.dag_class == 2: dag_dict = ss.generateDAG2(mioa_dict, s_set) ep = ss.calculateExpectedProfit(dag_dict, s_set) if ep > 0: if self.r_flag: ep = safe_div(ep, self.seed_cost_dict[i]) celf_item = (ep, k, i, 0) heap.heappush_max(celf_heap, celf_item) return celf_heap
def generateMIOG(self): miog_dict = {s: [] for s in self.graph_dict} for source_node in self.graph_dict: ### source_dict[i_node] = (prob, in-neighbor) source_dict = {i: self.graph_dict[source_node][i] for i in self.graph_dict[source_node]} source_dict[source_node] = 1.0 source_heap = [(self.graph_dict[source_node][i], i, [i]) for i in self.graph_dict[source_node]] heap.heapify_max(source_heap) # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node, i_path) = heap.heappop_max(source_heap) if i_prob >= source_dict[i_node]: miog_dict[source_node].append((i_prob, i_path)) # if i_prev not in miog_dict[source_node]: # miog_dict[source_node][i_prev] = [i_node] # else: # miog_dict[source_node][i_prev].append(i_node) if i_node in self.graph_dict: for ii_node in self.graph_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- ii_prob = round(i_prob * self.graph_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: if ii_node in source_dict: if ii_prob >= source_dict[ii_node]: source_dict[ii_node] = ii_prob heap.heappush_max(source_heap, (ii_prob, ii_node, i_path + [ii_node])) else: source_dict[ii_node] = ii_prob heap.heappush_max(source_heap, (ii_prob, ii_node, i_path + [ii_node])) return miog_dict
def updatePMIIA(self, s_set, pmiia_dict): s_list = s_set.copy() s_node = '' sub_graph = copy.deepcopy(self.graph_dict) mioa_dict = {} while s_list: if len(s_list) != len(s_set): induceGraph(sub_graph, s_node) s_node = s_list.pop(0) mioa_dict[s_node] = {} source_dict = {s_node: (1.0, s_node)} source_heap = [] if s_node in sub_graph: for i in sub_graph[s_node]: source_dict[i] = (sub_graph[s_node][i], s_node) heap.heappush_max(source_heap, (sub_graph[s_node][i], i)) while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) i_prev = source_dict[i_node][1] # -- find MIP from source_node to i_node -- i_path = [i_node, i_prev] while i_prev != source_dict[i_prev][1]: i_prev = source_dict[i_prev][1] i_path.append(i_prev) i_path.reverse() mioa_dict[s_node][i_node] = (i_prob, i_path) if i_node in sub_graph: for ii_node in sub_graph[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in mioa_dict[s_node]: ii_prob = round( i_prob * sub_graph[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_dict: ii_prob_d = source_dict[ii_node][0] if ii_prob > ii_prob_d: source_dict[ii_node] = (ii_prob, i_node) source_heap.remove( (ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: source_dict[ii_node] = (ii_prob, i_node) heap.heappush_max(source_heap, (ii_prob, ii_node)) is_dict = { i_node_v: set() for s_node in mioa_dict for i_node_v in mioa_dict[s_node] } s_list = s_set.copy() s_node = s_list.pop(0) while s_list: for i_node_v in mioa_dict[s_node]: # --- if there is a seed j > i s.t. sj is in MIP_G(Si) (si, v), si will be added into IS(v) --- is_condition = { i for i in mioa_dict[s_node][i_node_v][1] if i in s_list } if is_condition: is_dict[i_node_v].add(s_node) s_node = s_list.pop(0) for i_node_v in is_dict: s_set_reduce_is_set = set(s_set).difference(is_dict[i_node_v]) for s_node in s_set_reduce_is_set: if i_node_v in mioa_dict[s_node]: if i_node_v not in pmiia_dict: pmiia_dict[i_node_v] = {} pmiia_dict[i_node_v][s_node] = mioa_dict[s_node][i_node_v] return pmiia_dict
def generateMIOA(self): ### mioa_dict[source_node][i_node]: (prob., MIP) mioa_dict = {} for source_node in self.graph_dict: ### source_dict: the node in heap which may update its activated probability -- ### source_dict[i_node] = (prob, in-neighbor) mioa_dict[source_node] = {} source_dict = { i: (self.graph_dict[source_node][i], source_node) for i in self.graph_dict[source_node] } source_dict[source_node] = (1.0, source_node) source_heap = [(self.graph_dict[source_node][i], i) for i in self.graph_dict[source_node]] heap.heapify_max(source_heap) # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) i_prev = source_dict[i_node][1] # -- find MIP from source_node to i_node -- i_path = [i_node, i_prev] while i_prev != source_node: i_prev = source_dict[i_prev][1] i_path.append(i_prev) i_path.pop() i_path.reverse() mioa_dict[source_node][i_node] = (i_prob, i_path) if i_node in self.graph_dict: for ii_node in self.graph_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in mioa_dict[source_node]: ii_prob = round( i_prob * self.graph_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_dict: ii_prob_d = source_dict[ii_node][0] if ii_prob > ii_prob_d: source_dict[ii_node] = (ii_prob, i_node) source_heap.remove( (ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: source_dict[ii_node] = (ii_prob, i_node) heap.heappush_max(source_heap, (ii_prob, ii_node)) mioa_dict = [mioa_dict] * self.num_product if self.epw_flag: # -- update node's activated probability by product weight -- mioa_dict = [{ i: { j: (round( mioa_dict[k][i][j][0] * self.product_weight_list[k]** len(mioa_dict[k][i][j][1]), 4), mioa_dict[k][i][j][1]) for j in mioa_dict[k][i] } for i in mioa_dict[k] } for k in range(self.num_product)] # -- remove influenced nodes which are over diffusion threshold -- mioa_dict = [{ i: { j: mioa_dict[k][i][j] for j in mioa_dict[k][i] if mioa_dict[k][i][j][0] >= self.prob_threshold } for i in mioa_dict[k] } for k in range(self.num_product)] # -- remove empty mioa -- mioa_dict = [{ i: mioa_dict[k][i] for i in mioa_dict[k] if mioa_dict[k][i] } for k in range(self.num_product)] return mioa_dict
def updatePMIIA(self, s_set, pmiia_dict): s_list = s_set.copy() s_node = '' sub_graph = self.graph_dict.copy() while s_list: if len(s_list) != len(s_set): induceGraph(sub_graph, s_node) s_node = s_list.pop(0) pmiia_dict[s_node] = {} mioa_dict, miia_dict = {}, {s_node: {}} source_in_dict = {s_node: (1.0, s_node)} source_in_heap = [] s_node_in_neighbor = [ i for i in sub_graph if s_node in sub_graph[i] ] for i in s_node_in_neighbor: source_in_dict[i] = (sub_graph[i][s_node], s_node) heap.heappush_max(source_in_heap, (sub_graph[i][s_node], i)) while source_in_heap: (i_prob, i_node) = heap.heappop_max(source_in_heap) i_subs = source_in_dict[i_node][1] # -- find MIP from source_node to i_node -- i_path = [i_node, i_subs] while i_subs != source_in_dict[i_subs][1]: i_subs = source_in_dict[i_subs][1] i_path.append(i_subs) if i_node not in mioa_dict: mioa_dict[i_node] = {s_node: (i_prob, i_path)} else: mioa_dict[i_node][s_node] = (i_prob, i_path) miia_dict[s_node][i_node] = (i_prob, i_path) i_node_in_neighbor = [ i for i in sub_graph if i_node in sub_graph[i] ] if i_node_in_neighbor: for ii_node in i_node_in_neighbor: # -- not yet find MIP from source_node to ii_node -- if ii_node not in mioa_dict[i_node]: ii_prob = round( i_prob * sub_graph[ii_node][i_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_in_dict: ii_prob_d = source_in_dict[ii_node][0] if ii_prob > ii_prob_d: source_in_dict[ii_node] = (ii_prob, i_node) source_in_heap.remove( (ii_prob_d, ii_node)) source_in_heap.append( (ii_prob, ii_node)) heap.heapify_max(source_in_heap) # -- if ii_node is not in heap -- else: source_in_dict[ii_node] = (ii_prob, i_node) heap.heappush_max(source_in_heap, (ii_prob, ii_node)) for i_node_v in miia_dict[s_node]: is_set = { i for i in miia_dict[s_node][i_node_v][1] if i in s_list } if not is_set: pmiia_dict[s_node][i_node_v] = miia_dict[s_node][i_node_v] del_list = [i for i in pmiia_dict if not pmiia_dict[i]] while del_list: del_node = del_list.pop() del pmiia_dict[del_node] return pmiia_dict
def generateSeedExpectedInfDictUsingDAG1(self, k_prod, s_set): node_rank_dict = {} source_dict = {s_node: 1.0 for s_node in s_set[k_prod]} source_heap = [(1.0, s_node) for s_node in s_set[k_prod]] # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) node_rank_dict[i_node] = i_prob if i_node in self.graph_dict: for ii_node in self.graph_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in node_rank_dict: ii_prob = round( i_prob * self.graph_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in source_dict: ii_prob_d = source_dict[ii_node] if ii_prob > ii_prob_d: source_dict[ii_node] = ii_prob source_heap.remove((ii_prob_d, ii_node)) source_heap.append((ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: source_dict[ii_node] = ii_prob heap.heappush_max(source_heap, (ii_prob, ii_node)) s_total_set = set(s for k in range(self.num_product) for s in s_set[k]) dag_dict = {} for i in self.graph_dict: if i in node_rank_dict: for j in self.graph_dict[i]: if j in node_rank_dict and j not in s_total_set: if node_rank_dict[i] > node_rank_dict[j]: if i not in dag_dict: dag_dict[i] = {} dag_dict[i][j] = self.graph_dict[i][j] seed_exp_inf_dict = {} for s_node in s_set[k_prod]: if s_node in dag_dict: ### source_dict[i_node] = (prob, in-neighbor) mioa_set = set() s_node_dict = {s_node: 1.0} source_heap = [] for i in dag_dict[s_node]: s_node_dict[i] = dag_dict[s_node][i] heap.heappush_max(source_heap, (dag_dict[s_node][i], i)) # -- it will not find a better path than the existing MIP -- # -- because if this path exists, it should be pop earlier from the heap. -- while source_heap: (i_prob, i_node) = heap.heappop_max(source_heap) mioa_set.add(i_node) if i_node in seed_exp_inf_dict: seed_exp_inf_dict[i_node].append(i_prob) else: seed_exp_inf_dict[i_node] = [i_prob] if i_node in dag_dict: for ii_node in dag_dict[i_node]: # -- not yet find MIP from source_node to ii_node -- if ii_node not in mioa_set: ii_prob = round( i_prob * dag_dict[i_node][ii_node], 4) if ii_prob >= self.prob_threshold: # -- if ii_node is in heap -- if ii_node in s_node_dict: ii_prob_d = s_node_dict[ii_node] if ii_prob > ii_prob_d: s_node_dict[ii_node] = ii_prob source_heap.remove( (ii_prob_d, ii_node)) source_heap.append( (ii_prob, ii_node)) heap.heapify_max(source_heap) # -- if ii_node is not in heap -- else: s_node_dict[ii_node] = ii_prob heap.heappush_max( source_heap, (ii_prob, ii_node)) return seed_exp_inf_dict