public static MCNodeData operator +(MCNodeData node1, MCNodeData node2) { if (node1.K == node2.K) { MCNodeData ret = new MCNodeData(node1.K); for (int i = 0; i < node1.K; i++) ret[i] = node1[i] + node2[i]; return ret; } else throw new ArgumentException("Node Data dimensions must agree"); }
public MCNodeData[] BuildNodes() { this.setScale(); this._dataID = new Dictionary<int, double[]>(); MCNodeData[] nodes = new MCNodeData[_n]; int dim = _m * this.K + ((this.EqualCardinality) ? 1 : 0); for (int i = 0; i < _n; i++) { nodes[i] = new MCNodeData(dim); double[] row = new double[_m]; for (int j = 0; j < _m; j++) { for (int sc = 0; sc < this.K; sc++) { nodes[i][j * this.K + sc] = _critFunc[j](_data[j][i], sc + 1) * _scaling[j][sc]; } row[j] = _data[j][i]; } if (this.EqualCardinality) { nodes[i][dim - 1] = double.MaxValue/2; } nodes[i].ID = MCNodeData.GetNewID(); this._dataID.Add(nodes[i].ID, row); } this.SetNodes(nodes); return nodes; }
public virtual double Partition() { //// define active set List<MCNodeData> l = this._graph.Nodes.Select(d => d.Value).ToList(); l.Sort(new MCNodeDescCostComparer()); // continue while active set as more than one node // final node is the remainder with the objective value while (l.Count > 1) { // initially take highest cost MCNodeData u = l[0]; l.RemoveAt(0); // remainder node, to replace origin/larger MCNodeData rem = new MCNodeData(); // index of wstar to track which to remove int wstarIndex = 0; // minimum net cost available // value will be set on initial iteration when // calculated from first available node i.e. second // node available in the active set double minNet = double.MaxValue; //u.NodeCost; // only consider "next node" for single criteria // this is the standard NP problem int stopCount = (l[0].K == 1) ? 1 : l.Count; bool opposite = false; // check remaining nodes for wstar // stop looking if c(w) <= c(u) - c(uwc) for (int j = 0; j < stopCount; j++) { MCNodeData w = l[j]; //if (w.NodeCost > u.NodeCost - l[wstarIndex].NodeCost || j == l.Count - 2) //{ MCNodeData uwo = u - w; MCNodeData uws = u + w; if (uwo.NodeCost <= minNet || uws.NodeCost <= minNet) { opposite = uwo.NodeCost <= uws.NodeCost; if (opposite) { rem = uwo; } else { rem = uws; } minNet = rem.NodeCost; wstarIndex = j; } } GraphNode<MCNodeData> gu = _graph.FindByID(u.ID); GraphNode<MCNodeData> gw = _graph.FindByID(l[wstarIndex].ID); //Console.WriteLine("Create arc " + gu.Value.ID + " " + gu.Value.NodeCost + " " // + (int)((opposite) ? ArcType.Opposite : ArcType.Same) + " " + gw.Value.ID + " " + gw.Value.NodeCost); _graph.AddUndirectedEdge(gu, gw, (int)((opposite) ? ArcType.Opposite : ArcType.Same)); l.RemoveAt(wstarIndex); // add nonzero cost nodes back to active set if (rem.NodeCost > 0) { int addIndex = 0; // find place to add remainder node for (int j = l.Count - 1; j >= 0; j--) { if (rem.NodeCost <= l[j].NodeCost) { addIndex = j + 1; // if index = count, then capacity auto adjusts j = -1; } } rem.ID = u.ID; l.Insert(addIndex, rem); } } if (l.Count == 1) this.Remainder = l[0]; else { this.Remainder = new MCNodeData(_graph.Nodes[0].Value.K); } return this.Remainder.NodeCost; }
public MCKK(MCNodeData[] nodes) { SetNodes(nodes); }
protected void SetNodes(MCNodeData[] nodes) { foreach (MCNodeData d in nodes) _graph.AddNode(d); initializePartitions(); }