Anthropomorphic object algorithm C # Implementation of NP-hard packing

Source: Internet
Author: User

The interface is very simple. There is only one "button1" button. After you press the button, the small circle in the large circle container is automatically moved to the local minimum value. If the conditions are not met, searches for a random position for the circle with the largest potential energy or the smallest potential energy, and re-calculates and moves the circle, the idea of this algorithm comes from Huang Wenqi and Xu Ruchu's "modern computing theory guidance-Background of NP hard problem, Prospect and Solution Algorithm Research" page 62.

Using system; using system. io; using system. collections; using system. collections. generic; using system. componentmodel; using system. data; using system. drawing; using system. LINQ; using system. text; using system. windows. forms; using system. threading; // form1.cs Packing Problem namespace packingob1 {public partial class form1: FORM {// Potential Energy // double step for progressive movement; circle [] circles = new circle [10]; streamread Er sr = new streamreader ("circles1.txt"); string line; int num; string [] r_str = new string [100]; string [] co_str = new string [200]; double [] radius = new double [100]; pointf [] cordinates = new pointf [100]; Public form1 () {initializecomponent ();} void drawcircle (circle) {graphics G = graphics. fromhwnd (this. handle); G. translatetransform (this. width/2, this. height/2); G. drawellipse (New Pen (color. black), new rectanglef (float) (circle. x-circle. r), (float) (circle. y-circle. r), (float) (2 * circle. r), (float) (2 * circle. r); G. dispose ();} void readstream (streamreader SR) {line = sr. readline (); num = convert. toint32 (line); // This is a covert class line = sr. readline (); r_str = line. split (New char [] {''}); // pay attention to the use of the split for (INT I = 0; I <num; I ++) {Radius [I] = convert. todouble (r_str [I]);} line = sr. readline (); co_str = line. split (New char [] {''}); For (INT I = 0; I <num; I ++) {cordinates [I]. X = (float) convert. todouble (co_str [2 * I]); cordinates [I]. y = (float) convert. todouble (co_str [2 * I + 1]);} private void form1_load (Object sender, eventargs e) {// read data from a text file, create a circular readstream (SR); For (INT I = 0; I <num; I ++) {circles [I] = New circle (); circles [I]. R = radius [I]; circles [I]. X = cordinates [I]. x; circles [I]. y = cordinates [I]. Y ;}}/// <summary> // calculate the potential energy of the entire system, max_pe for calculating the maximum potential energy and min_pe for the minimum potential energy at the same time // </Summary> double calc_pe (circle [] circles, ref circle maxpe_circle, ref circle minpe_circle) {double Pe = 0; // the previous calculation result is cleared before calculation !!! For (INT I = 1; I <num; I ++) {circles [I]. DX = 0; circles [I]. DY = 0; circles [I]. pe = 0;} calc_dx_dy (circles); For (INT I = 1; I <num; I ++) {PE + = circles [I]. PE;} maxpe_circle = minpe_circle = circles [1]; for (INT I = 2; I <num; I ++) {maxpe_circle = maxpe_circle.pe <circles [I]. PE? Circles [I]: maxpe_circle; minpe_circle = minpe_circle.pe> circles [I]. PE? Circles [I]: minpe_circle;} return PE ;} /// <summary> /// count Dx and dy of all circles /// </Summary> void calc_dx_dy (circle [] circles) {for (INT I = 1; I <num; I ++) {movedirection (circles [I], num, circles, I );}} /// <summary> /// calculate the direction of each circle to move /// </Summary> /// <Param name = "circle"> </param> // /<Param name = "num"> </param> // <Param name = "numth"> </param> void movedirection (circle, int num, circle [] C Ircles, int numth) {for (INT I = 0; I <num; I ++) {// consider the distance from 0th circles if (I = 0) {double d0i = math. SQRT (circle. x * circle. X + circle. y * circle. y); If (d0i + circle. r> circles [I]. r) {circle. dx + = circle. x/d0i * (d0i + circle. r-circles [I]. r); circle. dy + = circle. y/d0i * (d0i + circle. r-circles [I]. r); circle. PE + = math. pow (d0i + circle. r-circles [I]. r, 2.0) ;}/// consider the distance between the container and other circles else if (n Umth! = I) {double dij = math. SQRT (math. pow (circle. x-circles [I]. x, 2.0) + math. pow (circle. y-circles [I]. y, 2.0); If (dij <circle. R + circles [I]. r) {circle. dx + = (circles [I]. x-circle. x)/dij * (circle. R + circles [I]. r-dij); circle. dy + = (circles [I]. y-circle. y)/dij * (circle. R + circles [I]. r-dij); circle. PE + = math. pow (circle. R + circles [I]. r-dij, 2.0) ;}}} private void form1_paint (Object sender, painteventargs e) {for (INT I = 0; I <num; I ++) {drawcircle (circles [I]);} /// <summary> /// click, start to move the circle /// </Summary> /// <Param name = "sender"> </param> /// <Param name = "E"> </param> private void button#click (Object sender, eventargs e) {step = 0.1; Circle oldmaxpe = circles [0]; Circle maxpe = circles [1]; Circle minpe = circles [1]; double new_pe; double old_pe = 0; int T = 0; Wh Ile (true) {If (Step> = 0.001) {new_pe = calc_pe (circles, ref maxpe, ref minpe); If (new_pe <0.0001) {return ;} else if (new_pe <old_pe) {old_pe = new_pe; For (INT I = 1; I <num; I ++) {circles [I]. x-= Step * circles [I]. DX; circles [I]. y-= Step * circles [I]. dy;} invalidate (); Update (); // thread. sleep (10);} else if (new_pe> = old_pe) {old_pe = new_pe; step = 0.8 * step; For (INT I = 0; I <Num; I ++) {circles [I]. x-= Step * circles [I]. DX; circles [I]. y-= Step * circles [I]. dy;} invalidate (); Update (); // thread. sleep (10) ;}} else {If (maxpe = oldmaxpe) {T = t + 1;} If (T <1) {// random point selection on the disc, re-place the circle with the largest potential energy. // note that both maxpe and oldmaxpe point to the object in old_circles. Random Rand = new random (); maxpe. X =-circles [0]. R + 2 * circles [0]. R * Rand. nextdouble (); maxpe. y =-circles [0]. R + 2 * circles [0]. R * Rand. nextdouble (); oldmaxpe = maxpe; step = 0.1;} else if (t = 1) {random Rand = new random (); minpe. X =-circles [0]. R + 2 * circles [0]. R * Rand. nextdouble (); minpe. y =-circles [0]. R + 2 * circles [0]. R * Rand. nextdouble (); t = 0; oldmaxpe = circles [0]; step = 0.1 ;}}}/// <summary> // a circle accepts coordinates (x, y) and radius R // </Summary> public class circle {// The coordinates of the circle public Double X; Public Double Y; // the radius of the circle public Double R; // public double DX; Public double dy; Public double PE; // <summary> // create a circle (No parameter required) /// </Summary> Public circle () {This. DX = 0; this. DY = 0; this. pe = 0 ;} /// <summary> /// create a circle // </Summary> /// <Param name = "X"> </param> /// <Param name = "Y"> </param> // <Param name = "R"> </param> Public circle (Double X, double Y, double r) {This. X = x; this. y = y; this. R = r; this. DX = 0; this. DY = 0; this. pe = 0 ;} /// <summary> /// copy and copy the circle // </Summary> /// <returns> returns the circle </returns> Public circle clone () {circle clone_circle = new circle (); clone_circle.x = This. x; clone_circle.y = This. y; clone_circle.r = This. r; clone_circle.dx = This. DX; clone_circle.dy = This. dy; clone_circle.pe = This. PE; return clone_circle ;}}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.